Skip to content

Commit

Permalink
feat: Language plugins choose the runner image (#3268)
Browse files Browse the repository at this point in the history
Language plugins can now declare the runner image to use by including a
ModuleRuntime in the Module schema.
Image names do not include the tag to use, instead FTL will use the same
tag that the rest of FTL is using.
If a language plugin does not choose a runner image, it is defaulted
to`ftl0/ftl-runner`.

---------

Co-authored-by: Alec Thomas <[email protected]>
  • Loading branch information
matt2e and alecthomas authored Nov 7, 2024
1 parent 26f349a commit ab91f25
Show file tree
Hide file tree
Showing 23 changed files with 559 additions and 465 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,18 @@ jobs:
- uses: cashapp/[email protected]
- uses: ./.github/actions/build-cache
- run: just build-docker provisioner
docker-build-runner:
name: Build Runner Docker Image
docker-build-runners:
name: Build Runner Docker Images
# if: github.event_name != 'pull_request' || github.event.action == 'enqueued' || contains( github.event.pull_request.labels.*.name, 'run-all')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cashapp/[email protected]
- uses: ./.github/actions/build-cache
- run: just build-docker runner
- name: Build Runner Docker Image
run: just build-docker runner
- name: Build JVM Docker Image
run: just build-docker runner-jvm
docker-build-box:
name: Build Box Docker Image
# if: github.event_name != 'pull_request' || github.event.action == 'enqueued' || contains( github.event.pull_request.labels.*.name, 'run-all')
Expand Down
29 changes: 25 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ on:
- "v[0-9]+.[0-9]+.[0-9]+"
name: Automatically Build Release
jobs:
build-runner:
name: Build Runner Docker Image
build-runners:
name: Build Runner Docker Images
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Init Hermit
uses: cashapp/[email protected]
- name: Build
- name: Build Runner
run: |
just build-docker runner
mkdir -p artifacts/ftl-runner
Expand All @@ -23,6 +23,17 @@ jobs:
name: docker-runner-artifact
path: artifacts/ftl-runner/ftl-runner.tar
retention-days: 1
- name: Build JVM Runner
run: |
just build-docker runner-jvm
mkdir -p artifacts/ftl-runner-jvm
docker save -o artifacts/ftl-runner-jvm/ftl-runner-jvm.tar ftl0/ftl-runner-jvm:latest
- name: Temporarily save JVM Docker image
uses: actions/upload-artifact@v4
with:
name: docker-runner-jvm-artifact
path: artifacts/ftl-runner-jvm/ftl-runner-jvm.tar
retention-days: 1
build-controller:
name: Build Controller Docker Image
runs-on: ubuntu-latest
Expand Down Expand Up @@ -86,7 +97,7 @@ jobs:
permissions:
contents: read
packages: write
needs: [build-runner, build-controller, build-provisioner, build-box]
needs: [build-runners, build-controller, build-provisioner, build-box]
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -99,6 +110,11 @@ jobs:
with:
name: docker-runner-artifact
path: artifacts/ftl-runner
- name: Retrieve JVM Runner Docker image
uses: actions/download-artifact@v4
with:
name: docker-runner-jvm-artifact
path: artifacts/ftl-runner-jvm
- name: Retrieve Controller Docker image
uses: actions/download-artifact@v4
with:
Expand All @@ -116,6 +132,8 @@ jobs:
path: artifacts/ftl-box
- name: Load Runner Docker image
run: docker load -i artifacts/ftl-runner/ftl-runner.tar
- name: Load JVM Runner Docker image
run: docker load -i artifacts/ftl-runner-jvm/ftl-runner-jvm.tar
- name: Load Controller Docker image
run: docker load -i artifacts/ftl-controller/ftl-controller.tar
- name: Load Provisioner Docker image
Expand All @@ -133,6 +151,9 @@ jobs:
docker tag ftl0/ftl-runner:latest ftl0/ftl-runner:"$GITHUB_SHA"
docker tag ftl0/ftl-runner:latest ftl0/ftl-runner:"$version"
docker push -a ftl0/ftl-runner
docker tag ftl0/ftl-runner-jvm:latest ftl0/ftl-runner-jvm:"$GITHUB_SHA"
docker tag ftl0/ftl-runner-jvm:latest ftl0/ftl-runner-jvm:"$version"
docker push -a ftl0/ftl-runner-jvm
docker tag ftl0/ftl-controller:latest ftl0/ftl-controller:"$GITHUB_SHA"
docker tag ftl0/ftl-controller:latest ftl0/ftl-controller:"$version"
docker push -a ftl0/ftl-controller
Expand Down
5 changes: 0 additions & 5 deletions Dockerfile.runner
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ RUN apt-get install -y curl git zip
COPY ./bin /src/bin
ENV PATH="/src/bin:$PATH"
ENV HERMIT_STATE_DIR=/hermit
RUN hermit install openjdk-17.0.8_7
RUN go version
RUN mvn -B --version

WORKDIR /src

Expand All @@ -32,9 +30,6 @@ RUN apt-get install -y ca-certificates

WORKDIR /root/

ENV PATH="/root/jdk/bin:$PATH"
ENV JAVA_HOME="/root/jdk"
COPY --from=builder /hermit/pkg/openjdk-17.0.8_7/ /root/jdk/
COPY --from=builder /src/build/release/ftl-runner .
COPY --from=builder /src/build/release/ftl .
RUN mkdir deployments
Expand Down
19 changes: 19 additions & 0 deletions Dockerfile.runner-jvm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM ubuntu:24.04 AS builder
RUN apt-get update
RUN apt-get install -y curl git zip

# Seed some of the most common tools - this will be cached
COPY ./bin /src/bin
ENV PATH="/src/bin:$PATH"
ENV HERMIT_STATE_DIR=/hermit
RUN hermit install openjdk-17.0.8_7
RUN mvn -B --version

# Finally create the runtime image.
FROM ftl0/ftl-runner:latest

WORKDIR /root/

ENV PATH="/root/jdk/bin:$PATH"
ENV JAVA_HOME="/root/jdk"
COPY --from=builder /hermit/pkg/openjdk-17.0.8_7/ /root/jdk/
10 changes: 6 additions & 4 deletions backend/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1585,11 +1585,13 @@ func (s *Service) watchModuleChanges(ctx context.Context, sendChange func(respon
delete(moduleByDeploymentKey, deletion.String())
} else if message, ok := notification.Message.Get(); ok {
moduleSchema := message.Schema.ToProto().(*schemapb.Module) //nolint:forcetypeassert
moduleSchema.Runtime = &schemapb.ModuleRuntime{
Language: message.Language,
CreateTime: timestamppb.New(message.CreatedAt),
MinReplicas: int32(message.MinReplicas),
if moduleSchema.Runtime == nil {
moduleSchema.Runtime = &schemapb.ModuleRuntime{
Language: message.Language,
}
}
moduleSchema.Runtime.CreateTime = timestamppb.New(message.CreatedAt)
moduleSchema.Runtime.MinReplicas = int32(message.MinReplicas)

hasher := sha.New()
data := []byte(moduleSchema.String())
Expand Down
19 changes: 18 additions & 1 deletion backend/controller/scaling/k8sscaling/deployment_provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,24 @@ func (r *DeploymentProvisioner) handleNewDeployment(ctx context.Context, dep *sc
if err != nil {
return err
}
runnerImage := strings.ReplaceAll(ourImage, "controller", "runner")

// runner images use the same tag as the controller
rawRunnerImage := optional.Ptr(dep.Runtime.Image).Default("ftl0/ftl-runner")
var runnerImage string
if len(strings.Split(rawRunnerImage, ":")) != 1 {
return fmt.Errorf("module runtime's image should not contain a tag: %s", rawRunnerImage)
}
if strings.HasPrefix(rawRunnerImage, "ftl0/") {
// Images in the ftl0 namespace should use the same tag as the controller and use the same namespace as ourImage
runnerImage = strings.ReplaceAll(ourImage, "ftl-controller", rawRunnerImage[len(`ftl0/`):])
} else {
// Images outside of the ftl0 namespace should use the same tag as the controller
ourImageComponents := strings.Split(ourImage, ":")
if len(ourImageComponents) != 2 {
return fmt.Errorf("expected <name>:<tag> for image name %q", ourImage)
}
runnerImage = rawRunnerImage + ":" + ourImageComponents[1]
}

deployment.Name = name
deployment.OwnerReferences = []v1.OwnerReference{{APIVersion: "v1", Kind: "service", Name: name, UID: service.UID}}
Expand Down
Loading

0 comments on commit ab91f25

Please sign in to comment.