Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: wire up cron again #3452

Merged
merged 1 commit into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,15 @@ jobs:
- uses: cashapp/[email protected]
- uses: ./.github/actions/build-cache
- run: just build-docker provisioner
docker-build-cron:
name: Build Cron Docker Image
# 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 cron
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')
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,25 @@ jobs:
name: docker-provisioner-artifact
path: artifacts/ftl-provisioner
retention-days: 1
build-cron:
name: Build Cron Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Init Hermit
uses: cashapp/[email protected]
- name: Build
run: |
just build-docker cron
mkdir -p artifacts/ftl-provisioner
docker save -o artifacts/ftl-cron/ftl-cron.tar ftl0/ftl-cron:latest
- name: Temporarily save Docker image
uses: actions/upload-artifact@v4
with:
name: docker-cron-artifact
path: artifacts/ftl-cron
retention-days: 1
build-box:
name: Build FTL-in-a-box Docker Image
runs-on: ubuntu-latest
Expand Down Expand Up @@ -125,6 +144,11 @@ jobs:
with:
name: docker-provisioner-artifact
path: artifacts/ftl-provisioner
- name: Retrieve Cron Docker image
uses: actions/download-artifact@v4
with:
name: docker-cron-artifact
path: artifacts/ftl-cron
- name: Retrieve FTL-in-a-box Docker image
uses: actions/download-artifact@v4
with:
Expand All @@ -138,6 +162,8 @@ jobs:
run: docker load -i artifacts/ftl-controller/ftl-controller.tar
- name: Load Provisioner Docker image
run: docker load -i artifacts/ftl-provisioner/ftl-provisioner.tar
- name: Load Cron Docker image
run: docker load -i artifacts/ftl-cron/ftl-cron.tar
- name: Load FTL-in-a-box Docker image
run: docker load -i artifacts/ftl-box/ftl-box.tar
- name: Log in to the Container registry
Expand All @@ -160,6 +186,9 @@ jobs:
docker tag ftl0/ftl-provisioner:latest ftl0/ftl-provisioner:"$GITHUB_SHA"
docker tag ftl0/ftl-provisioner:latest ftl0/ftl-provisioner:"$version"
docker push -a ftl0/ftl-provisioner
docker tag ftl0/ftl-cron:latest ftl0/ftl-cron:"$GITHUB_SHA"
docker tag ftl0/ftl-cron:latest ftl0/ftl-cron:"$version"
docker push -a ftl0/ftl-cron
docker tag ftl0/ftl-box:latest ftl0/ftl-box:"$GITHUB_SHA"
docker tag ftl0/ftl-box:latest ftl0/ftl-box:"$version"
docker push -a ftl0/ftl-box
Expand Down
44 changes: 44 additions & 0 deletions Dockerfile.cron
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
FROM ubuntu:24.04 AS builder
RUN apt-get update
RUN apt-get install -y curl git zip

# Copy Hermit bin stubs and install all packages. This is done
# separately so that Docker will cache the tools correctly.
COPY ./bin /src/bin
ENV PATH="/src/bin:$PATH"
WORKDIR /src

# Seed some of the most common tools - this will be cached
RUN go version
RUN node --version

# Download Go dependencies separately so Docker will cache them
COPY go.mod go.sum ./
RUN go mod download -x

# Download PNPM dependencies separately so Docker will cache them
COPY frontend/console/package.json ./frontend/console/
COPY frontend/vscode/package.json ./frontend/vscode/
COPY pnpm-workspace.yaml pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

# Build
COPY . /src/
RUN just errtrace
# Reset timestamps so that the build state is reset
RUN git ls-files -z | xargs -0 touch -r go.mod
RUN just build ftl-cron

# Finally create the runtime image.
FROM scratch

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

WORKDIR /plugins/

WORKDIR /service/
COPY --from=builder /src/build/release/ftl-cron .

EXPOSE 8893

CMD ["/service/ftl-cron"]
5 changes: 5 additions & 0 deletions backend/cron/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cron
import (
"context"
"fmt"
"net/url"
"sort"
"time"

Expand Down Expand Up @@ -37,6 +38,10 @@ type cronJob struct {
next time.Time
}

type Config struct {
ControllerEndpoint *url.URL `name:"ftl-endpoint" help:"Controller endpoint." env:"FTL_ENDPOINT" default:"http://127.0.0.1:8892"`
}

func (c cronJob) String() string {
desc := fmt.Sprintf("%s.%s (%s)", c.module, c.verb.Name, c.pattern)
var next string
Expand Down
5 changes: 5 additions & 0 deletions charts/ftl/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,9 @@ app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/name: {{ include "ftl.fullname" . }}
app.kubernetes.io/component: provisioner
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{- define "ftl-cron.selectorLabels" -}}
app.kubernetes.io/name: {{ include "ftl.fullname" . }}
app.kubernetes.io/component: cron
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
9 changes: 9 additions & 0 deletions charts/ftl/templates/cron-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.cron.serviceAccountName }}
namespace: {{ .Release.Namespace }}
{{- if .Values.cron.cronsRoleArn }}
annotations:
eks.amazonaws.com/role-arn: {{ .Values.cron.cronsRoleArn }}
{{- end }}
53 changes: 53 additions & 0 deletions charts/ftl/templates/cron.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{{ $version := printf "v%s" .Chart.Version -}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "ftl.fullname" . }}-cron
labels:
{{- include "ftl.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.cron.replicas }}
revisionHistoryLimit: {{ .Values.cron.revisionHistoryLimit }}
selector:
matchLabels:
{{- include "ftl-cron.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "ftl-cron.selectorLabels" . | nindent 8 }}
{{- if .Values.cron.podAnnotations }}
annotations:
{{- toYaml .Values.cron.podAnnotations | nindent 8 }}
{{- end }}
spec:
serviceAccountName: {{ .Values.cron.serviceAccountName }}
containers:
- name: app
image: "{{ .Values.cron.image.repository }}:{{ .Values.cron.image.tag | default $version }}"
imagePullPolicy: {{ .Values.cron.image.pullPolicy }}
{{- if .Values.cron.envFrom }}
envFrom:
{{- if .Values.cron.envFrom }}
{{- toYaml .Values.cron.envFrom | nindent 12 }}
{{- end }}
{{- end }}
env:
{{- if .Values.cron.env }}
{{- toYaml .Values.cron.env | nindent 12 }}
{{- end }}
{{- if .Values.cron.nodeSelector }}
nodeSelector:
{{- toYaml .Values.cron.nodeSelector | nindent 8 }}
{{- end }}
{{- if .Values.cron.affinity }}
affinity:
{{- toYaml .Values.cron.affinity | nindent 8 }}
{{- end }}
{{- if .Values.cron.topologySpreadConstraints }}
topologySpreadConstraints:
{{- toYaml .Values.cron.topologySpreadConstraints | nindent 8 }}
{{- end }}
{{- if .Values.cron.tolerations }}
tolerations:
{{- toYaml .Values.cron.tolerations | nindent 8 }}
{{- end }}
2 changes: 0 additions & 2 deletions charts/ftl/templates/ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ spec:
name: ftl-controller-ingress
port:
number: 8891
{{- if .Values.provisioner.enabled }}
- path: /xyz.block.ftl.v1beta1.provisioner.ProvisionerService/
pathType: Prefix
backend:
service:
name: ftl-provisioner
port:
number: 8893
{{- end }}
{{- range $host := .Values.ingress.hosts }}
- host: "{{ $host.host }}"
http:
Expand Down
2 changes: 0 additions & 2 deletions charts/ftl/templates/provisioner-config-map.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{{- if .Values.provisioner.enabled }}
{{- if eq .Values.provisioner.configMap "ftl-provisioner-default-config" }}
apiVersion: v1
kind: ConfigMap
Expand All @@ -12,5 +11,4 @@ data:
{ id = "cloudformation", resources = ["postgres"] },
{ id = "controller", resources = ["module"] },
]
{{- end}}
{{- end}}
4 changes: 1 addition & 3 deletions charts/ftl/templates/provisioner-services.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{{- if .Values.provisioner.enabled }}
apiVersion: v1
kind: Service
metadata:
Expand All @@ -22,5 +21,4 @@ spec:
{{- end }}
selector:
{{- include "ftl-provisioner.selectorLabels" . | nindent 4 }}
type: {{ .Values.provisioner.service.type | default "ClusterIP" }}
{{- end }}
type: {{ .Values.provisioner.service.type | default "ClusterIP" }}
4 changes: 1 addition & 3 deletions charts/ftl/templates/provisioner.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{{- if .Values.provisioner.enabled }}
{{ $version := printf "v%s" .Chart.Version -}}
apiVersion: apps/v1
kind: Deployment
Expand Down Expand Up @@ -81,5 +80,4 @@ spec:
{{- if .Values.provisioner.tolerations }}
tolerations:
{{- toYaml .Values.provisioner.tolerations | nindent 8 }}
{{- end }}
{{- end }}
{{- end }}
21 changes: 19 additions & 2 deletions charts/ftl/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ controller:

provisioner:
provisionersRoleArn: arn:aws:iam::ftl-provisioners-irsa-role
enabled: false
replicas: 1
revisionHistoryLimit: 0
configMap: "ftl-provisioner-default-config"
Expand Down Expand Up @@ -131,7 +130,6 @@ provisioner:
valueFrom:
fieldRef:
fieldPath: status.hostIP

ports:
- name: http
containerPort: 8893
Expand Down Expand Up @@ -211,6 +209,25 @@ runner:
topologySpreadConstraints: null
tolerations: null


cron:
replicas: 1
revisionHistoryLimit: 0
image:
repository: "ftl0/ftl-cron"
pullPolicy: IfNotPresent

envFrom: null
serviceAccountName: ftl-cron

env:
- name: FTL_ENDPOINT
value: "http://ftl-controller:8892"
- name: LOG_LEVEL
value: "debug"
- name: LOG_JSON
value: "true"

postgresql:
enabled: true
architecture: standalone
Expand Down
49 changes: 49 additions & 0 deletions cmd/ftl-cron/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package main

import (
"context"
"fmt"
"os"
"strconv"
"time"

"github.com/alecthomas/kong"

"github.com/TBD54566975/ftl"
"github.com/TBD54566975/ftl/backend/cron"
"github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect"
_ "github.com/TBD54566975/ftl/internal/automaxprocs" // Set GOMAXPROCS to match Linux container CPU quota.
"github.com/TBD54566975/ftl/internal/log"
"github.com/TBD54566975/ftl/internal/observability"
"github.com/TBD54566975/ftl/internal/rpc"
)

var cli struct {
Version kong.VersionFlag `help:"Show version."`
ObservabilityConfig observability.Config `embed:"" prefix:"o11y-"`
LogConfig log.Config `embed:"" prefix:"log-"`
CronConfig cron.Config `embed:""`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general we should prefix all embedded configs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not the pattern we have been using for the 'main' config though. Cron, Runner, Provisioner, Controller etc all have one 'main' config that is not prefixed.

ConfigFlag string `name:"config" short:"C" help:"Path to FTL project cf file." env:"FTL_CONFIG" placeholder:"FILE"`
}

func main() {
t, err := strconv.ParseInt(ftl.Timestamp, 10, 64)
if err != nil {
panic(fmt.Sprintf("invalid timestamp %q: %s", ftl.Timestamp, err))
}
kctx := kong.Parse(&cli,
kong.Description(`FTL - Cron`),
kong.UsageOnError(),
kong.Vars{"version": ftl.Version, "timestamp": time.Unix(t, 0).Format(time.RFC3339)},
)

ctx := log.ContextWithLogger(context.Background(), log.Configure(os.Stderr, cli.LogConfig))
err = observability.Init(ctx, false, "", "ftl-cron", ftl.Version, cli.ObservabilityConfig)
kctx.FatalIfErrorf(err, "failed to initialize observability")

verbClient := rpc.Dial(ftlv1connect.NewVerbServiceClient, cli.CronConfig.ControllerEndpoint.String(), log.Error)
schemaClient := rpc.Dial(ftlv1connect.NewSchemaServiceClient, cli.CronConfig.ControllerEndpoint.String(), log.Error)

err = cron.Start(ctx, schemaClient, verbClient)
kctx.FatalIfErrorf(err, "failed to start provisioner")
}
8 changes: 8 additions & 0 deletions deployment/Dockerfile.cron.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM ubuntu:24.04

WORKDIR /root/

COPY docker-build/ftl-cron .
EXPOSE 8893

CMD ["/root/ftl-cron"]
Loading
Loading