# openswarm-runner: one ephemeral Firecracker machine per workflow run. Boots the # backend headless, runs the workflow, reports, exits. Nothing here is long-lived. # # THIS APP MUST NOT SHARE THE TRUSTED 6PN MESH with openswarm-cloud / openswarm-edge. # The agent inside has Bash and executes user prose, so from in here # `curl http://openswarm-cloud.internal:8080` must resolve to nothing. Fly decides an # app's private network AT CREATE TIME and fly.toml cannot express it, so the app is # created once, by hand, onto its own isolated network: # # fly apps create openswarm-runner --org openswarm --network openswarm-runner-isolated # fly deploy . --config openswarm-runner/fly.toml --dockerfile openswarm-runner/Dockerfile # # (deploy runs from the REPO ROOT: the image needs backend/ in its build context.) # Verify the isolation after the first deploy, do not assume it: # fly ssh console -a openswarm-runner -C "getent hosts openswarm-cloud.internal" # must fail # # There is deliberately no [http_service] and no [[services]]: the runner takes no # inbound traffic and gets no public IP. It reaches the control plane outbound over # the public internet with the callback token in the run spec, which is why the two # do not need a shared private network in the first place. # # Machines are created per run by the control plane (Machines API, auto_destroy=true, # run spec passed as OPENSWARM_RUN_SPEC). This file is the app-level shape they inherit. app = 'openswarm-runner' primary_region = 'iad' kill_signal = 'SIGTERM' kill_timeout = '30s' [build] dockerfile = 'Dockerfile' # No [env] block on purpose. Per-run machines are created through the Machines API, # which does not read this file, so anything set here would apply to the deploy's # template machine and to nothing that actually runs a workflow. Every runtime value, # including the RUNNER_MAX_RUN_SECONDS wall-clock cap, is baked into the image instead. # The template machine this deploy creates has no run spec, so it exits 2 immediately. # Without this it would crash-loop on Fly's default on-failure policy and bill forever. [[restart]] policy = 'never' # No [[mounts]]: a run's state is garbage the moment it ends, and an ephemeral rootfs # means one run cannot leave a credential lying around for the next tenant to find. [[vm]] cpu_kind = 'shared' cpus = 2 memory_mb = 4096