| 1 | import * as machines from "@distilled.cloud/fly-io/machines"; |
| 2 | import * as Effect from "effect/Effect"; |
| 3 | import * as Schedule from "effect/Schedule"; |
| 4 | |
| 5 | export const nginx = { |
| 6 | region: "iad", |
| 7 | image: "nginx:alpine", |
| 8 | guest: { cpus: 1, memoryMb: 256 }, |
| 9 | }; |
| 10 | |
| 11 | /** Plain HTTP on port 80: Fly issues no TLS certificate for `.flycast`. */ |
| 12 | export const httpService = { |
| 13 | protocol: "tcp", |
| 14 | internalPort: 80, |
| 15 | ports: [{ port: 80, handlers: ["http"] }], |
| 16 | autostart: true, |
| 17 | autostop: "off" as const, |
| 18 | }; |
| 19 | |
| 20 | /** Fetch `url` from inside a Machine until the body contains `expected`. */ |
| 21 | export const fetchFrom = ( |
| 22 | caller: { appName: string; machineId: string }, |
| 23 | url: string, |
| 24 | expected = "Welcome to nginx", |
| 25 | ) => |
| 26 | machines |
| 27 | .execMachine({ |
| 28 | app_name: caller.appName, |
| 29 | machine_id: caller.machineId, |
| 30 | command: ["sh", "-c", `wget -qO- -T 5 ${url} || true`], |
| 31 | timeout: 15, |
| 32 | }) |
| 33 | .pipe( |
| 34 | Effect.repeat({ |
| 35 | schedule: Schedule.spaced("3 seconds"), |
| 36 | times: 20, |
| 37 | until: (result) => result.stdout?.includes(expected) === true, |
| 38 | }), |
| 39 | Effect.map((result) => result.stdout ?? ""), |
| 40 | ); |
| 41 | |
| 42 | /** Fetch `url` once from inside a Machine; returns the body or wget's error. */ |
| 43 | export const fetchOnce = ( |
| 44 | caller: { appName: string; machineId: string }, |
| 45 | url: string, |
| 46 | ) => |
| 47 | machines |
| 48 | .execMachine({ |
| 49 | app_name: caller.appName, |
| 50 | machine_id: caller.machineId, |
| 51 | command: ["sh", "-c", `wget -qO- -T 5 ${url} 2>&1 || true`], |
| 52 | timeout: 15, |
| 53 | }) |
| 54 | .pipe(Effect.map((result) => result.stdout ?? "")); |