@alchemy.run/fly 2.0.0-beta.84 → 2.0.0-beta.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/App.d.ts +4 -4
- package/lib/App.d.ts.map +1 -1
- package/lib/App.js +4 -6
- package/lib/App.js.map +1 -1
- package/lib/AuthProvider.d.ts +1 -1
- package/lib/AuthProvider.d.ts.map +1 -1
- package/lib/BindService.d.ts.map +1 -1
- package/lib/BindService.js +1 -1
- package/lib/BindService.js.map +1 -1
- package/lib/Bucket.d.ts +2 -2
- package/lib/Bucket.d.ts.map +1 -1
- package/lib/Bucket.js +10 -10
- package/lib/Bucket.js.map +1 -1
- package/lib/BucketBinding.js +1 -1
- package/lib/BucketBinding.js.map +1 -1
- package/lib/Certificate.js +4 -4
- package/lib/Certificate.js.map +1 -1
- package/lib/ConnectPostgres.d.ts +1 -1
- package/lib/ConnectPostgres.d.ts.map +1 -1
- package/lib/ConnectPostgresHttp.js +1 -1
- package/lib/ConnectPostgresHttp.js.map +1 -1
- package/lib/Contributions.d.ts +1 -1
- package/lib/Credentials.d.ts +1 -1
- package/lib/Credentials.d.ts.map +1 -1
- package/lib/Credentials.js +10 -14
- package/lib/Credentials.js.map +1 -1
- package/lib/DeploymentImages.js +1 -1
- package/lib/DeploymentImages.js.map +1 -1
- package/lib/Errors.d.ts +1 -1
- package/lib/Errors.d.ts.map +1 -1
- package/lib/IpAssignment.js +4 -4
- package/lib/IpAssignment.js.map +1 -1
- package/lib/Machine.d.ts +1 -1
- package/lib/Machine.d.ts.map +1 -1
- package/lib/Machine.js +2 -2
- package/lib/Machine.js.map +1 -1
- package/lib/Postgres.d.ts +1 -1
- package/lib/Postgres.d.ts.map +1 -1
- package/lib/Postgres.js +6 -6
- package/lib/Postgres.js.map +1 -1
- package/lib/PostgresMigrations.d.ts +7 -22
- package/lib/PostgresMigrations.d.ts.map +1 -1
- package/lib/PostgresMigrations.js +37 -89
- package/lib/PostgresMigrations.js.map +1 -1
- package/lib/Providers.d.ts +1 -1
- package/lib/Providers.d.ts.map +1 -1
- package/lib/Redis.d.ts +2 -2
- package/lib/Redis.d.ts.map +1 -1
- package/lib/Redis.js +9 -6
- package/lib/Redis.js.map +1 -1
- package/lib/RedisBinding.js +1 -1
- package/lib/RedisBinding.js.map +1 -1
- package/lib/RedisHttp.d.ts +1 -1
- package/lib/RedisHttp.d.ts.map +1 -1
- package/lib/RedisHttp.js +4 -1
- package/lib/RedisHttp.js.map +1 -1
- package/lib/Secret.d.ts +1 -1
- package/lib/Secret.d.ts.map +1 -1
- package/lib/Secret.js +2 -2
- package/lib/Secret.js.map +1 -1
- package/lib/SecretKey.d.ts +1 -1
- package/lib/SecretKey.d.ts.map +1 -1
- package/lib/SecretKey.js +2 -2
- package/lib/SecretKey.js.map +1 -1
- package/lib/Service.d.ts +8 -13
- package/lib/Service.d.ts.map +1 -1
- package/lib/Service.js +51 -18
- package/lib/Service.js.map +1 -1
- package/lib/Sprite.d.ts +2 -2
- package/lib/Sprite.d.ts.map +1 -1
- package/lib/Sprite.js +7 -5
- package/lib/Sprite.js.map +1 -1
- package/lib/Volume.d.ts +2 -2
- package/lib/Volume.d.ts.map +1 -1
- package/lib/Volume.js +5 -5
- package/lib/Volume.js.map +1 -1
- package/lib/VolumeSnapshot.js +1 -1
- package/lib/VolumeSnapshot.js.map +1 -1
- package/lib/Website/AssetDeployment.d.ts.map +1 -1
- package/lib/Website/AssetDeployment.js +9 -9
- package/lib/Website/AssetDeployment.js.map +1 -1
- package/lib/Website/Astro.d.ts +8 -6
- package/lib/Website/Astro.d.ts.map +1 -1
- package/lib/Website/Astro.js +12 -13
- package/lib/Website/Astro.js.map +1 -1
- package/lib/Website/FrameworkSite.d.ts +39 -2
- package/lib/Website/FrameworkSite.d.ts.map +1 -1
- package/lib/Website/FrameworkSite.js +46 -3
- package/lib/Website/FrameworkSite.js.map +1 -1
- package/lib/Website/StaticSite.d.ts +10 -3
- package/lib/Website/StaticSite.d.ts.map +1 -1
- package/lib/Website/StaticSite.js +16 -4
- package/lib/Website/StaticSite.js.map +1 -1
- package/lib/Website/Vite.d.ts +9 -0
- package/lib/Website/Vite.d.ts.map +1 -1
- package/lib/Website/Vite.js +9 -0
- package/lib/Website/Vite.js.map +1 -1
- package/lib/WriteCertificatesHttp.js +2 -2
- package/lib/WriteCertificatesHttp.js.map +1 -1
- package/lib/bluegreen.d.ts +4 -4
- package/lib/bluegreen.d.ts.map +1 -1
- package/lib/bluegreen.js +6 -4
- package/lib/bluegreen.js.map +1 -1
- package/lib/hosted.d.ts +3 -4
- package/lib/hosted.d.ts.map +1 -1
- package/lib/hosted.js.map +1 -1
- package/lib/internal/RemoteBuilder.d.ts.map +1 -1
- package/lib/internal/RemoteBuilder.js +21 -8
- package/lib/internal/RemoteBuilder.js.map +1 -1
- package/lib/leases.d.ts +2 -2
- package/lib/replicas.d.ts +10 -10
- package/lib/replicas.d.ts.map +1 -1
- package/lib/replicas.js +7 -7
- package/lib/replicas.js.map +1 -1
- package/package.json +13 -13
- package/src/App.ts +5 -7
- package/src/BindService.ts +1 -2
- package/src/Bucket.ts +15 -13
- package/src/BucketBinding.ts +1 -1
- package/src/Certificate.ts +4 -4
- package/src/ConnectPostgres.ts +1 -1
- package/src/ConnectPostgresHttp.ts +1 -1
- package/src/Credentials.ts +9 -36
- package/src/DeploymentImages.ts +1 -1
- package/src/Errors.ts +1 -1
- package/src/IpAssignment.ts +4 -4
- package/src/Machine.ts +5 -3
- package/src/Postgres.ts +7 -7
- package/src/PostgresMigrations.ts +39 -99
- package/src/Redis.ts +11 -8
- package/src/RedisBinding.ts +1 -1
- package/src/RedisHttp.ts +4 -1
- package/src/Secret.ts +3 -3
- package/src/SecretKey.ts +3 -3
- package/src/Service.ts +53 -19
- package/src/Sprite.ts +11 -9
- package/src/Volume.ts +6 -6
- package/src/VolumeSnapshot.ts +1 -1
- package/src/Website/AssetDeployment.ts +13 -15
- package/src/Website/Astro.ts +20 -15
- package/src/Website/FrameworkSite.ts +92 -6
- package/src/Website/StaticSite.ts +27 -7
- package/src/Website/Vite.ts +9 -0
- package/src/WriteCertificatesHttp.ts +2 -2
- package/src/bluegreen.ts +7 -4
- package/src/hosted.ts +3 -4
- package/src/internal/RemoteBuilder.ts +37 -19
- package/src/replicas.ts +8 -8
|
@@ -43,7 +43,7 @@ export const certificatesWriteClient = (
|
|
|
43
43
|
return yield* authorize(
|
|
44
44
|
machines
|
|
45
45
|
.createAppAcmeCertificate({ app_name: yield* appName, hostname })
|
|
46
|
-
.pipe(Effect.catchTag("Conflict", () => Effect.
|
|
46
|
+
.pipe(Effect.catchTag("Conflict", () => Effect.undefined)),
|
|
47
47
|
);
|
|
48
48
|
}),
|
|
49
49
|
upload: Effect.fn("Fly.Certificates.upload")(function* (request) {
|
|
@@ -78,7 +78,7 @@ export const certificatesWriteClient = (
|
|
|
78
78
|
return yield* authorize(
|
|
79
79
|
machines
|
|
80
80
|
.getAppCertificate({ app_name: yield* appName, hostname })
|
|
81
|
-
.pipe(Effect.catchTag("NotFound", () => Effect.
|
|
81
|
+
.pipe(Effect.catchTag("NotFound", () => Effect.undefined)),
|
|
82
82
|
);
|
|
83
83
|
}),
|
|
84
84
|
remove: Effect.fn("Fly.Certificates.remove")(function* (hostname) {
|
package/src/bluegreen.ts
CHANGED
|
@@ -102,7 +102,7 @@ export const setRouting = (
|
|
|
102
102
|
yield* getMachineById(appName, machineId).pipe(
|
|
103
103
|
Effect.filterOrFail(
|
|
104
104
|
(machine) => machine !== undefined && machine.cordoned === cordoned,
|
|
105
|
-
() => new ReplicaNotCreated({ appName,
|
|
105
|
+
() => new ReplicaNotCreated({ appName, resourceName: machineId }),
|
|
106
106
|
),
|
|
107
107
|
Effect.retry({
|
|
108
108
|
times: 8,
|
|
@@ -293,7 +293,9 @@ export const reconcileBlueGreen = Effect.fn(function* (
|
|
|
293
293
|
reusable?.[0] ??
|
|
294
294
|
(yield* sha256Object({
|
|
295
295
|
workload,
|
|
296
|
-
predecessors: owned
|
|
296
|
+
predecessors: owned
|
|
297
|
+
.map((machine) => machine.id)
|
|
298
|
+
.sort((a, b) => ((a ?? "") < (b ?? "") ? -1 : (a ?? "") > (b ?? "") ? 1 : 0)),
|
|
297
299
|
})).slice(0, 20);
|
|
298
300
|
const desired = reusable?.[1] ?? [];
|
|
299
301
|
if (
|
|
@@ -417,7 +419,7 @@ export const reconcileBlueGreen = Effect.fn(function* (
|
|
|
417
419
|
),
|
|
418
420
|
Effect.filterOrFail(
|
|
419
421
|
(machine) => machine !== undefined,
|
|
420
|
-
() => new ReplicaNotCreated({ appName: input.appName, name }),
|
|
422
|
+
() => new ReplicaNotCreated({ appName: input.appName, resourceName: name }),
|
|
421
423
|
),
|
|
422
424
|
Effect.retry({
|
|
423
425
|
times: 8,
|
|
@@ -446,7 +448,8 @@ export const reconcileBlueGreen = Effect.fn(function* (
|
|
|
446
448
|
Effect.catchReason("HttpClientError", "TransportError", () => readback),
|
|
447
449
|
);
|
|
448
450
|
}
|
|
449
|
-
if (!current?.id)
|
|
451
|
+
if (!current?.id)
|
|
452
|
+
return yield* new ReplicaNotCreated({ appName: input.appName, resourceName: name });
|
|
450
453
|
const leased = (yield* leaseSnapshot(input.appName, [current], leases))[0];
|
|
451
454
|
if (!leased?.id)
|
|
452
455
|
return yield* ambiguous(
|
package/src/hosted.ts
CHANGED
|
@@ -70,13 +70,12 @@ export const MACHINE_PLATFORM = "linux/amd64";
|
|
|
70
70
|
export interface FlyBuildOptions extends Bundle.BundleConfig {
|
|
71
71
|
/**
|
|
72
72
|
* Native or Node-only packages to install into the Machine image with
|
|
73
|
-
* `npm install` instead of bundling them. `
|
|
74
|
-
*
|
|
75
|
-
* constructor`). Same `build.install` shape as Lambda.
|
|
73
|
+
* `npm install` instead of bundling them. Same `build.install` shape as
|
|
74
|
+
* Lambda.
|
|
76
75
|
*
|
|
77
76
|
* @example
|
|
78
77
|
* ```typescript
|
|
79
|
-
* build: { install: ["
|
|
78
|
+
* build: { install: ["sharp"] }
|
|
80
79
|
* ```
|
|
81
80
|
*/
|
|
82
81
|
readonly install?: PackageInstall;
|
|
@@ -37,7 +37,9 @@ const HEALTH_INTERVAL = Duration.seconds(5);
|
|
|
37
37
|
const MAX_PENDING_POLLS = 240;
|
|
38
38
|
/** How often, and how long, to wait for the builder's push to reach `registry.fly.io`. */
|
|
39
39
|
const UPSTREAM_POLL = Duration.seconds(2);
|
|
40
|
-
const MAX_UPSTREAM_POLLS =
|
|
40
|
+
const MAX_UPSTREAM_POLLS = 30;
|
|
41
|
+
/** Pushes of one image before giving up on it reaching the registry. */
|
|
42
|
+
const MAX_PUSHES = 3;
|
|
41
43
|
|
|
42
44
|
export class RemoteBuilderError extends Data.TaggedError("Fly.RemoteBuilderError")<{
|
|
43
45
|
operation: string;
|
|
@@ -170,7 +172,13 @@ export const buildOnRemoteBuilder = Effect.fn(function* (input: {
|
|
|
170
172
|
() => input.docker.run(["buildx", "rm", builder]).pipe(Effect.ignore),
|
|
171
173
|
);
|
|
172
174
|
|
|
173
|
-
|
|
175
|
+
// The builder pushes through its host's registry mirror, which forwards
|
|
176
|
+
// to registry.fly.io. Machines pull from there, so confirm the tag landed
|
|
177
|
+
// (usually within seconds) while the builder is still held. The mirror
|
|
178
|
+
// occasionally drops a push without an error, so a tag that hasn't
|
|
179
|
+
// landed is pushed again: the builder has every layer cached, so a
|
|
180
|
+
// repeat build only re-sends the image.
|
|
181
|
+
const build = input.docker.image
|
|
174
182
|
.build(
|
|
175
183
|
{
|
|
176
184
|
context: input.contextDir,
|
|
@@ -193,25 +201,35 @@ export const buildOnRemoteBuilder = Effect.fn(function* (input: {
|
|
|
193
201
|
}),
|
|
194
202
|
}),
|
|
195
203
|
);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
Effect.provideService(DockerEnvironment, {
|
|
203
|
-
DOCKER_AUTH_CONFIG: JSON.stringify({
|
|
204
|
-
auths: { [input.registry.server]: { auth: basicAuth(input.registry) } },
|
|
205
|
-
}),
|
|
206
|
-
}),
|
|
207
|
-
Effect.retry({ schedule: Schedule.spaced(UPSTREAM_POLL), times: MAX_UPSTREAM_POLLS }),
|
|
208
|
-
Effect.mapError(
|
|
209
|
-
() =>
|
|
210
|
-
new RemoteBuilderError({
|
|
211
|
-
operation: "upload",
|
|
212
|
-
message: `${input.imageRef} did not reach ${input.registry.server}`,
|
|
204
|
+
const landed = input.docker
|
|
205
|
+
.run(["buildx", "imagetools", "inspect", "--raw", input.imageRef])
|
|
206
|
+
.pipe(
|
|
207
|
+
Effect.provideService(DockerEnvironment, {
|
|
208
|
+
DOCKER_AUTH_CONFIG: JSON.stringify({
|
|
209
|
+
auths: { [input.registry.server]: { auth: basicAuth(input.registry) } },
|
|
213
210
|
}),
|
|
211
|
+
}),
|
|
212
|
+
Effect.retry({ schedule: Schedule.spaced(UPSTREAM_POLL), times: MAX_UPSTREAM_POLLS }),
|
|
213
|
+
Effect.mapError(
|
|
214
|
+
() =>
|
|
215
|
+
new RemoteBuilderError({
|
|
216
|
+
operation: "upload",
|
|
217
|
+
message: `${input.imageRef} did not reach ${input.registry.server} after ${MAX_PUSHES} pushes`,
|
|
218
|
+
}),
|
|
219
|
+
),
|
|
220
|
+
);
|
|
221
|
+
const started = yield* Clock.currentTimeMillis;
|
|
222
|
+
yield* build.pipe(
|
|
223
|
+
Effect.andThen(landed),
|
|
224
|
+
Effect.tapError((error) =>
|
|
225
|
+
error._tag === "Fly.RemoteBuilderError" && error.operation === "upload"
|
|
226
|
+
? note(`${input.imageRef} hasn't reached ${input.registry.server} yet`)
|
|
227
|
+
: Effect.void,
|
|
214
228
|
),
|
|
229
|
+
Effect.retry({
|
|
230
|
+
while: (error) => error._tag === "Fly.RemoteBuilderError" && error.operation === "upload",
|
|
231
|
+
times: MAX_PUSHES - 1,
|
|
232
|
+
}),
|
|
215
233
|
);
|
|
216
234
|
const waited = (yield* Clock.currentTimeMillis) - started;
|
|
217
235
|
yield* note(`${input.imageRef} available on ${input.registry.server} after ${waited}ms`);
|
package/src/replicas.ts
CHANGED
|
@@ -42,7 +42,7 @@ const waitBackoff = Schedule.exponential("500 millis");
|
|
|
42
42
|
const SERVICE_CHECK_NAME_PREFIX = "servicecheck-";
|
|
43
43
|
|
|
44
44
|
export class ReplicaNotCreated extends Data.TaggedError("Fly.ReplicaNotCreated")<{
|
|
45
|
-
|
|
45
|
+
resourceName: string;
|
|
46
46
|
appName: string;
|
|
47
47
|
}> {}
|
|
48
48
|
|
|
@@ -115,7 +115,7 @@ export const gone = (machine: FlyMachine | undefined) =>
|
|
|
115
115
|
export const getMachineById = (appName: string, machineId: string) =>
|
|
116
116
|
machines.getMachine({ app_name: appName, machine_id: machineId }).pipe(
|
|
117
117
|
Effect.map((machine) => (gone(machine) ? undefined : machine)),
|
|
118
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
118
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
119
119
|
);
|
|
120
120
|
|
|
121
121
|
/**
|
|
@@ -137,7 +137,7 @@ const getLeasedMachine = (appName: string, machineId: string) =>
|
|
|
137
137
|
const getLeasedMachineById = (appName: string, machineId: string) =>
|
|
138
138
|
getLeasedMachine(appName, machineId).pipe(
|
|
139
139
|
Effect.map((machine) => (gone(machine) ? undefined : machine)),
|
|
140
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
140
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
141
141
|
);
|
|
142
142
|
|
|
143
143
|
export const listMachinesByApp = (appName: string) =>
|
|
@@ -1163,7 +1163,7 @@ const reconcileLeasedReplicas = Effect.fn(function* (
|
|
|
1163
1163
|
);
|
|
1164
1164
|
const volumeId = volume?.id;
|
|
1165
1165
|
if (volumeId === undefined) {
|
|
1166
|
-
return yield* new ReplicaNotCreated({ name, appName: input.appName });
|
|
1166
|
+
return yield* new ReplicaNotCreated({ resourceName: name, appName: input.appName });
|
|
1167
1167
|
}
|
|
1168
1168
|
usedVolumeIds.add(volumeId);
|
|
1169
1169
|
mounts.push({ volume: volumeId, path: group.disk.path });
|
|
@@ -1187,7 +1187,7 @@ const reconcileLeasedReplicas = Effect.fn(function* (
|
|
|
1187
1187
|
skip_launch: input.skipLaunch === true ? true : undefined,
|
|
1188
1188
|
min_secrets_version: input.minSecretsVersion,
|
|
1189
1189
|
})
|
|
1190
|
-
.pipe(Effect.catchTag("Conflict", () => Effect.
|
|
1190
|
+
.pipe(Effect.catchTag("Conflict", () => Effect.undefined));
|
|
1191
1191
|
current =
|
|
1192
1192
|
created ??
|
|
1193
1193
|
(yield* listMachinesByApp(input.appName).pipe(
|
|
@@ -1200,11 +1200,11 @@ const reconcileLeasedReplicas = Effect.fn(function* (
|
|
|
1200
1200
|
),
|
|
1201
1201
|
));
|
|
1202
1202
|
if (current === undefined || current.id === undefined) {
|
|
1203
|
-
return yield* new ReplicaNotCreated({ name, appName: input.appName });
|
|
1203
|
+
return yield* new ReplicaNotCreated({ resourceName: name, appName: input.appName });
|
|
1204
1204
|
}
|
|
1205
1205
|
const observed = (yield* leaseSnapshot(input.appName, [current], leases))[0];
|
|
1206
1206
|
if (!observed || input.configDrifted(observed, { mounts, metadata })) {
|
|
1207
|
-
return yield* new ReplicaNotCreated({ name, appName: input.appName });
|
|
1207
|
+
return yield* new ReplicaNotCreated({ resourceName: name, appName: input.appName });
|
|
1208
1208
|
}
|
|
1209
1209
|
current = observed;
|
|
1210
1210
|
} else if (
|
|
@@ -1243,7 +1243,7 @@ const reconcileLeasedReplicas = Effect.fn(function* (
|
|
|
1243
1243
|
!sameChecks(observed.config?.checks, config.checks) ||
|
|
1244
1244
|
!sameStopConfig(observed.config?.stop_config, config.stop_config)
|
|
1245
1245
|
)
|
|
1246
|
-
return yield* new ReplicaNotCreated({ appName: input.appName, name });
|
|
1246
|
+
return yield* new ReplicaNotCreated({ appName: input.appName, resourceName: name });
|
|
1247
1247
|
return observed;
|
|
1248
1248
|
}).pipe(
|
|
1249
1249
|
Effect.retry({
|