@alchemy.run/docker 0.0.0 → 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/LICENSE +201 -0
- package/README.md +46 -4
- package/lib/Bootstrap.d.ts +7 -0
- package/lib/Bootstrap.d.ts.map +1 -0
- package/lib/Bootstrap.js +25 -0
- package/lib/Bootstrap.js.map +1 -0
- package/lib/BuildHash.d.ts +56 -0
- package/lib/BuildHash.d.ts.map +1 -0
- package/lib/BuildHash.js +172 -0
- package/lib/BuildHash.js.map +1 -0
- package/lib/Container.d.ts +450 -0
- package/lib/Container.d.ts.map +1 -0
- package/lib/Container.js +745 -0
- package/lib/Container.js.map +1 -0
- package/lib/Context.d.ts +86 -0
- package/lib/Context.d.ts.map +1 -0
- package/lib/Context.js +146 -0
- package/lib/Context.js.map +1 -0
- package/lib/Docker.d.ts +527 -0
- package/lib/Docker.d.ts.map +1 -0
- package/lib/Docker.js +437 -0
- package/lib/Docker.js.map +1 -0
- package/lib/Dockerfile.d.ts +72 -0
- package/lib/Dockerfile.d.ts.map +1 -0
- package/lib/Dockerfile.js +12 -0
- package/lib/Dockerfile.js.map +1 -0
- package/lib/HealthcheckCommand.d.ts +17 -0
- package/lib/HealthcheckCommand.d.ts.map +1 -0
- package/lib/HealthcheckCommand.js +33 -0
- package/lib/HealthcheckCommand.js.map +1 -0
- package/lib/Image.d.ts +179 -0
- package/lib/Image.d.ts.map +1 -0
- package/lib/Image.js +210 -0
- package/lib/Image.js.map +1 -0
- package/lib/ImageSource.d.ts +288 -0
- package/lib/ImageSource.d.ts.map +1 -0
- package/lib/ImageSource.js +498 -0
- package/lib/ImageSource.js.map +1 -0
- package/lib/Network.d.ts +70 -0
- package/lib/Network.d.ts.map +1 -0
- package/lib/Network.js +111 -0
- package/lib/Network.js.map +1 -0
- package/lib/Providers.d.ts +21 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +26 -0
- package/lib/Providers.js.map +1 -0
- package/lib/Registry.d.ts +47 -0
- package/lib/Registry.d.ts.map +1 -0
- package/lib/Registry.js +67 -0
- package/lib/Registry.js.map +1 -0
- package/lib/RegistryError.d.ts +21 -0
- package/lib/RegistryError.d.ts.map +1 -0
- package/lib/RegistryError.js +28 -0
- package/lib/RegistryError.js.map +1 -0
- package/lib/RemoteImage.d.ts +118 -0
- package/lib/RemoteImage.d.ts.map +1 -0
- package/lib/RemoteImage.js +164 -0
- package/lib/RemoteImage.js.map +1 -0
- package/lib/Service.d.ts +499 -0
- package/lib/Service.d.ts.map +1 -0
- package/lib/Service.js +730 -0
- package/lib/Service.js.map +1 -0
- package/lib/ServiceImage.d.ts +78 -0
- package/lib/ServiceImage.d.ts.map +1 -0
- package/lib/ServiceImage.js +162 -0
- package/lib/ServiceImage.js.map +1 -0
- package/lib/Swarm.d.ts +119 -0
- package/lib/Swarm.d.ts.map +1 -0
- package/lib/Swarm.js +148 -0
- package/lib/Swarm.js.map +1 -0
- package/lib/Volume.d.ts +94 -0
- package/lib/Volume.d.ts.map +1 -0
- package/lib/Volume.js +133 -0
- package/lib/Volume.js.map +1 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +13 -0
- package/lib/index.js.map +1 -0
- package/package.json +58 -3
- package/src/Bootstrap.ts +51 -0
- package/src/BuildHash.ts +265 -0
- package/src/Container.ts +1118 -0
- package/src/Context.ts +215 -0
- package/src/Docker.ts +1173 -0
- package/src/Dockerfile.ts +81 -0
- package/src/HealthcheckCommand.ts +35 -0
- package/src/Image.ts +322 -0
- package/src/ImageSource.ts +842 -0
- package/src/Network.ts +169 -0
- package/src/Providers.ts +46 -0
- package/src/Registry.ts +91 -0
- package/src/RegistryError.ts +48 -0
- package/src/RemoteImage.ts +255 -0
- package/src/Service.ts +1264 -0
- package/src/ServiceImage.ts +252 -0
- package/src/Swarm.ts +221 -0
- package/src/Volume.ts +193 -0
- package/src/index.ts +17 -0
package/lib/Docker.js
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
import { createPhysicalName } from "alchemy/PhysicalName";
|
|
2
|
+
import * as Config from "effect/Config";
|
|
3
|
+
import * as Context from "effect/Context";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import { Base64 } from "effect/encoding";
|
|
6
|
+
import * as FileSystem from "effect/FileSystem";
|
|
7
|
+
import { flow } from "effect/Function";
|
|
8
|
+
import * as Layer from "effect/Layer";
|
|
9
|
+
import * as Option from "effect/Option";
|
|
10
|
+
import * as Path from "effect/Path";
|
|
11
|
+
import { PlatformError, SystemError } from "effect/PlatformError";
|
|
12
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
13
|
+
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
|
|
14
|
+
import * as Redacted from "effect/Redacted";
|
|
15
|
+
import * as Result from "effect/Result";
|
|
16
|
+
import * as Schema from "effect/Schema";
|
|
17
|
+
import * as Sink from "effect/Sink";
|
|
18
|
+
import * as Stream from "effect/Stream";
|
|
19
|
+
import { classifyDockerRegistryError } from "./RegistryError.js";
|
|
20
|
+
const RegistryAuth = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => {
|
|
21
|
+
const decoded = Base64.decode(value);
|
|
22
|
+
return Result.isSuccess(decoded) && decoded.success.indexOf(58) > 0;
|
|
23
|
+
})));
|
|
24
|
+
const decodeRegistryAuthConfig = Schema.Struct({
|
|
25
|
+
auths: Schema.Record(Schema.String, Schema.Struct({ auth: RegistryAuth })).pipe(Schema.NullOr, Schema.optional),
|
|
26
|
+
}).pipe(Schema.fromJsonString, (schema) => Schema.decodeEffect(schema, { onExcessProperty: "error" }));
|
|
27
|
+
export class Docker extends Context.Service()("@alchemy/Docker") {
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extra environment for every Docker CLI invocation, layered over the
|
|
31
|
+
* process environment (per-call variables still win). Scope it with
|
|
32
|
+
* `Effect.provideService(DockerEnvironment, { BUILDX_BUILDER: "ci" })` to
|
|
33
|
+
* target a buildx builder or Docker context without mutating `process.env`.
|
|
34
|
+
* @default {}
|
|
35
|
+
*/
|
|
36
|
+
export const DockerEnvironment = Context.Reference("alchemy/Docker/DockerEnvironment", { defaultValue: () => ({}) });
|
|
37
|
+
/** The Docker CLI client, running `options.bin` (`DOCKER_BIN` overrides). */
|
|
38
|
+
export const dockerLive = (options = {}) => Layer.effect(Docker, makeDocker(options));
|
|
39
|
+
const makeDocker = (options) => Effect.gen(function* () {
|
|
40
|
+
const fs = yield* FileSystem.FileSystem;
|
|
41
|
+
const path = yield* Path.Path;
|
|
42
|
+
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
43
|
+
const bin = yield* Config.String("DOCKER_BIN").pipe(Effect.orElseSucceed(() => options.bin ?? "docker"));
|
|
44
|
+
const run = (args, env, tap = Stream.tap(Effect.logDebug)) => Effect.gen(function* () {
|
|
45
|
+
const ambient = yield* DockerEnvironment;
|
|
46
|
+
return yield* spawner.spawn(ChildProcess.make(bin, args, {
|
|
47
|
+
stdin: "ignore",
|
|
48
|
+
stdout: "pipe",
|
|
49
|
+
stderr: "pipe",
|
|
50
|
+
detached: false,
|
|
51
|
+
env: { ...ambient, ...env },
|
|
52
|
+
extendEnv: true,
|
|
53
|
+
}));
|
|
54
|
+
}).pipe(Effect.flatMap((child) => Effect.all({
|
|
55
|
+
exitCode: child.exitCode,
|
|
56
|
+
stdout: child.stdout.pipe(Stream.decodeText, tap, Stream.mkString, Effect.map((stdout) => stdout.trim())),
|
|
57
|
+
stderr: child.stderr.pipe(Stream.decodeText, tap, Stream.mkString, Effect.map((stderr) => stderr.trim())),
|
|
58
|
+
}, { concurrency: "unbounded" })), Effect.mapError((error) => systemError({
|
|
59
|
+
_tag: "Unknown",
|
|
60
|
+
args,
|
|
61
|
+
// Name the CLI: a misconfigured `bin` / DOCKER_BIN fails here.
|
|
62
|
+
description: `Failed to run \`${bin}\`; is it installed and on PATH?`,
|
|
63
|
+
cause: error.reason,
|
|
64
|
+
})), Effect.tap((result) => {
|
|
65
|
+
if (result.exitCode === 0)
|
|
66
|
+
return Effect.void;
|
|
67
|
+
const stderr = result.stderr.replace(/^Error response from daemon: /, "");
|
|
68
|
+
if (stderr.match(/not found|not known|no such/i)) {
|
|
69
|
+
return systemError({ _tag: "NotFound", args, description: stderr });
|
|
70
|
+
}
|
|
71
|
+
if (stderr.match(/already exists/i)) {
|
|
72
|
+
return systemError({ _tag: "AlreadyExists", args, description: stderr });
|
|
73
|
+
}
|
|
74
|
+
return systemError({
|
|
75
|
+
_tag: "Unknown",
|
|
76
|
+
args,
|
|
77
|
+
description: `Command exited with code ${result.exitCode}: ${failureOutput(stderr, result.stdout)}`,
|
|
78
|
+
});
|
|
79
|
+
}), Effect.scoped);
|
|
80
|
+
const runInspect = (args) => run(args).pipe(Effect.map((result) => {
|
|
81
|
+
const [item] = JSON.parse(result.stdout);
|
|
82
|
+
return item;
|
|
83
|
+
}));
|
|
84
|
+
// Merge `credentials` into the ambient auth config: the process's
|
|
85
|
+
// DOCKER_AUTH_CONFIG, overlaid by one provided through DockerEnvironment
|
|
86
|
+
// (as `run` layers DockerEnvironment over the process environment).
|
|
87
|
+
// Merging, not replacing, keeps the user's own registry logins.
|
|
88
|
+
const registryEnvironment = Effect.fn("registryEnvironment")((credentials) => Effect.gen(function* () {
|
|
89
|
+
const value = yield* Config.Redacted("DOCKER_AUTH_CONFIG").pipe(Config.withDefault(Redacted.make("{}")));
|
|
90
|
+
const base = yield* decodeRegistryAuthConfig(Redacted.value(value) || "{}");
|
|
91
|
+
const ambient = yield* DockerEnvironment;
|
|
92
|
+
const overlay = ambient.DOCKER_AUTH_CONFIG === undefined
|
|
93
|
+
? undefined
|
|
94
|
+
: yield* decodeRegistryAuthConfig(ambient.DOCKER_AUTH_CONFIG || "{}");
|
|
95
|
+
return { auths: { ...base.auths, ...overlay?.auths } };
|
|
96
|
+
}).pipe(
|
|
97
|
+
// Schema diagnostics may include credential input. Do not retain them.
|
|
98
|
+
Effect.mapError(() => systemError({
|
|
99
|
+
_tag: "InvalidData",
|
|
100
|
+
args: ["buildx", "build"],
|
|
101
|
+
description: "Invalid DOCKER_AUTH_CONFIG; expected an auths map.",
|
|
102
|
+
})), Effect.map((current) => {
|
|
103
|
+
const password = Redacted.isRedacted(credentials.password)
|
|
104
|
+
? Redacted.value(credentials.password)
|
|
105
|
+
: credentials.password;
|
|
106
|
+
const auth = Base64.encode(`${credentials.username}:${password}`);
|
|
107
|
+
// Preserve Docker's file/helper fallback, contexts, and builders.
|
|
108
|
+
return {
|
|
109
|
+
DOCKER_AUTH_CONFIG: JSON.stringify({
|
|
110
|
+
auths: { ...current.auths, [credentials.server]: { auth } },
|
|
111
|
+
}),
|
|
112
|
+
};
|
|
113
|
+
})));
|
|
114
|
+
// How a build reaches a registry. Buildx 0.26 is the first release
|
|
115
|
+
// embedding Docker CLI 28.3's DOCKER_AUTH_CONFIG credential store, so it
|
|
116
|
+
// can `buildx build --push` straight from BuildKit. Older plugins (e.g.
|
|
117
|
+
// the buildx bundled with Docker Desktop < 4.44) silently ignore the
|
|
118
|
+
// variable, so the image is instead `--load`ed into the local store and
|
|
119
|
+
// published with the isolated-config `push`. Without any buildx plugin
|
|
120
|
+
// the legacy builder always loads, so a plain `image build` suffices.
|
|
121
|
+
// Probed once per Docker service instance.
|
|
122
|
+
const publication = yield* Effect.cached(Effect.gen(function* () {
|
|
123
|
+
const version = yield* run(["buildx", "version"]).pipe(Effect.option);
|
|
124
|
+
if (Option.isNone(version))
|
|
125
|
+
return "legacy";
|
|
126
|
+
// Numeric template captures can consume version separators as decimals.
|
|
127
|
+
const match = /^github\.com\/docker\/buildx v?(\d+)\.(\d+)\.\d+(?:[-+][^\s]+)?(?:\s.*)?$/.exec(version.value.stdout);
|
|
128
|
+
if (!match)
|
|
129
|
+
return "load";
|
|
130
|
+
const major = Number(match[1]);
|
|
131
|
+
const minor = Number(match[2]);
|
|
132
|
+
return major >= 1 || minor >= 26 ? "export" : "load";
|
|
133
|
+
}));
|
|
134
|
+
const outputTap = (session) => session
|
|
135
|
+
? Stream.tapSink(Sink.make()(flow(Stream.splitLines, Stream.runForEach((line) => session.note(line, { kind: "output" })))))
|
|
136
|
+
: undefined;
|
|
137
|
+
// `podman push` prints no `digest:` line, and Podman's RepoDigests can
|
|
138
|
+
// list a source digest under the pushed name, so Podman pushes report the
|
|
139
|
+
// published digest through `--digestfile` instead. Probed once.
|
|
140
|
+
const isPodman = yield* Effect.cached(run(["--version"]).pipe(Effect.map((result) => /^podman\b/i.test(result.stdout.trim())), Effect.orElseSucceed(() => false)));
|
|
141
|
+
const push = Effect.fn(function* (ref, credentials, platform, context, session) {
|
|
142
|
+
// Write the registry credentials directly into an isolated docker config
|
|
143
|
+
// as a plaintext `auths` entry and skip `docker login` entirely.
|
|
144
|
+
//
|
|
145
|
+
// `docker login` is the wrong tool here: on macOS Docker Desktop it routes
|
|
146
|
+
// through the shared `osxkeychain`/`desktop` credential helper *regardless*
|
|
147
|
+
// of an isolated DOCKER_CONFIG, so concurrent deploys either race the system
|
|
148
|
+
// keychain (`The specified item already exists in the keychain (-25299)`) or
|
|
149
|
+
// land the credential in the helper — leaving this isolated config without
|
|
150
|
+
// an `auths` entry, so the subsequent `docker push` fails with "no basic
|
|
151
|
+
// auth credentials". Embedding the base64 `auth` inline (the same thing
|
|
152
|
+
// `docker login` would write when no credsStore is configured) makes each
|
|
153
|
+
// deploy fully self-contained: no credential helper, no keychain, no login
|
|
154
|
+
// race. Only `push` reads this config; `build`/`pull`/`tag` keep using the
|
|
155
|
+
// global docker config (buildx builders, `docker context`, etc. intact).
|
|
156
|
+
const dir = yield* fs.makeTempDirectoryScoped({ prefix: "alchemy-docker-" });
|
|
157
|
+
// The isolated DOCKER_CONFIG holds none of the CLI's contexts. Ask the CLI
|
|
158
|
+
// (same environment as the push) which context it would use, and copy just
|
|
159
|
+
// that context's metadata and TLS material in.
|
|
160
|
+
const selected = context ??
|
|
161
|
+
(yield* run(["context", "show"]).pipe(Effect.map((result) => result.stdout), Effect.orElseSucceed(() => "default")));
|
|
162
|
+
if (selected && selected !== "default") {
|
|
163
|
+
const inspected = yield* runInspect(["context", "inspect", selected]);
|
|
164
|
+
for (const [kind, source] of [
|
|
165
|
+
["meta", inspected.Storage.MetadataPath],
|
|
166
|
+
["tls", inspected.Storage.TLSPath],
|
|
167
|
+
]) {
|
|
168
|
+
if (!(yield* fs.exists(source)))
|
|
169
|
+
continue;
|
|
170
|
+
const target = path.join(dir, "contexts", kind, path.basename(source));
|
|
171
|
+
yield* fs.makeDirectory(path.dirname(target), { recursive: true });
|
|
172
|
+
yield* fs.copy(source, target);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const pushContext = selected && selected !== "default" ? selected : context;
|
|
176
|
+
const config = yield* Effect.sync(() => {
|
|
177
|
+
const password = Redacted.isRedacted(credentials.password)
|
|
178
|
+
? Redacted.value(credentials.password)
|
|
179
|
+
: credentials.password;
|
|
180
|
+
const auth = Buffer.from(`${credentials.username}:${password}`).toString("base64");
|
|
181
|
+
return JSON.stringify({ auths: { [credentials.server]: { auth } } });
|
|
182
|
+
});
|
|
183
|
+
yield* fs.writeFileString(path.join(dir, "config.json"), config);
|
|
184
|
+
const digestFile = path.join(dir, "digest");
|
|
185
|
+
const digestArgs = (yield* isPodman) ? ["--digestfile", digestFile] : [];
|
|
186
|
+
const result = platform === undefined
|
|
187
|
+
? yield* run([...formatArgs({ context: pushContext }), "push", ...digestArgs, ref], { DOCKER_CONFIG: dir }, outputTap(session))
|
|
188
|
+
: yield* run([
|
|
189
|
+
...formatArgs({ context: pushContext }),
|
|
190
|
+
"push",
|
|
191
|
+
"--platform",
|
|
192
|
+
platform,
|
|
193
|
+
...digestArgs,
|
|
194
|
+
ref,
|
|
195
|
+
], { DOCKER_CONFIG: dir }, outputTap(session)).pipe(
|
|
196
|
+
// Engines without the containerd image store reject `--platform`
|
|
197
|
+
// on push; their local tag is already narrowed to the requested
|
|
198
|
+
// platform by `pull --platform`, so a plain push is equivalent.
|
|
199
|
+
Effect.catchIf((error) => /--platform|unknown flag|containerd/i.test(String(error)), () => run([...formatArgs({ context: pushContext }), "push", ...digestArgs, ref], { DOCKER_CONFIG: dir }, outputTap(session))));
|
|
200
|
+
if (digestArgs.length === 0)
|
|
201
|
+
return result;
|
|
202
|
+
const digest = (yield* fs
|
|
203
|
+
.readFileString(digestFile)
|
|
204
|
+
.pipe(Effect.orElseSucceed(() => ""))).trim();
|
|
205
|
+
// Report it the way `docker push` does, so callers parse one format.
|
|
206
|
+
return digest ? { ...result, stdout: `${result.stdout}\ndigest: ${digest}` } : result;
|
|
207
|
+
}, Effect.scoped, Effect.mapError(classifyDockerRegistryError));
|
|
208
|
+
return Docker.of({
|
|
209
|
+
run,
|
|
210
|
+
materialize: Effect.fn((options) => Effect.forEach([...options.files, { path: "Dockerfile", content: options.dockerfile }], (file) => {
|
|
211
|
+
const fullPath = path.join(options.context, file.path);
|
|
212
|
+
return fs
|
|
213
|
+
.makeDirectory(path.dirname(fullPath), { recursive: true })
|
|
214
|
+
.pipe(Effect.andThen(typeof file.content === "string"
|
|
215
|
+
? fs.writeFileString(fullPath, file.content)
|
|
216
|
+
: fs.writeFile(fullPath, file.content)));
|
|
217
|
+
}, { concurrency: "unbounded" })),
|
|
218
|
+
container: {
|
|
219
|
+
create: ({ image, env, command, context, ...options }) =>
|
|
220
|
+
// `--env KEY` (name-only) keeps values off CLI arguments; Docker
|
|
221
|
+
// copies each value from the CLI process environment, so the
|
|
222
|
+
// normalized container env must be passed to the child process.
|
|
223
|
+
run([
|
|
224
|
+
...formatArgs({ context }),
|
|
225
|
+
"container",
|
|
226
|
+
"create",
|
|
227
|
+
...formatArgs({ ...options, env: env ? Object.keys(env) : undefined }),
|
|
228
|
+
image,
|
|
229
|
+
...(command ?? []),
|
|
230
|
+
], env),
|
|
231
|
+
inspect: (name, context) => runInspect([...formatArgs({ context }), "container", "inspect", name]),
|
|
232
|
+
remove: (name, force, context) => run([...formatArgs({ context }), "container", "rm", name, ...(force ? ["-f"] : [])]),
|
|
233
|
+
start: (name, context) => run([...formatArgs({ context }), "container", "start", name]),
|
|
234
|
+
stop: (name, context) => run([...formatArgs({ context }), "container", "stop", name]),
|
|
235
|
+
},
|
|
236
|
+
image: {
|
|
237
|
+
build: Effect.fn("Docker.image.build")(function* ({ context: buildContext, engineContext, args, credentials, secrets, ...options }, session, registry) {
|
|
238
|
+
const tap = outputTap(session);
|
|
239
|
+
const secret = buildSecrets(secrets);
|
|
240
|
+
const buildArgs = [buildContext, ...formatArgs(options), ...secret.args, ...(args ?? [])];
|
|
241
|
+
const engine = formatArgs({ context: engineContext });
|
|
242
|
+
if (registry === undefined) {
|
|
243
|
+
return yield* run([...engine, "image", "build", ...buildArgs], {
|
|
244
|
+
...(credentials ? yield* registryEnvironment(credentials) : undefined),
|
|
245
|
+
...secret.env,
|
|
246
|
+
}, tap);
|
|
247
|
+
}
|
|
248
|
+
const mode = yield* publication;
|
|
249
|
+
if (mode === "export") {
|
|
250
|
+
// Export straight from BuildKit to the registry; the image never
|
|
251
|
+
// round-trips through the local image store.
|
|
252
|
+
const env = yield* registryEnvironment(registry);
|
|
253
|
+
return yield* run([...engine, "buildx", "build", "--push", ...buildArgs], { ...env, ...secret.env }, tap).pipe(Effect.mapError(classifyDockerRegistryError));
|
|
254
|
+
}
|
|
255
|
+
// Older Buildx ignores DOCKER_AUTH_CONFIG, so a `--push` export
|
|
256
|
+
// would fail with "no basic auth credentials". Build into the local
|
|
257
|
+
// store and publish with the isolated-config `push` instead.
|
|
258
|
+
// `--load` matters for non-loading builders (docker-container):
|
|
259
|
+
// without it the result stays in the build cache and `push` sees no
|
|
260
|
+
// such tag.
|
|
261
|
+
yield* run([
|
|
262
|
+
...engine,
|
|
263
|
+
...(mode === "load" ? ["buildx", "build", "--load"] : ["image", "build"]),
|
|
264
|
+
...buildArgs,
|
|
265
|
+
], secret.env, tap);
|
|
266
|
+
const [tag, ...tags] = typeof options.tag === "string" ? [options.tag] : options.tag;
|
|
267
|
+
return yield* push(tag, registry, options.platform, engineContext, session).pipe(Effect.tap(() => Effect.forEach(tags, (tag) => push(tag, registry, options.platform, engineContext, session))));
|
|
268
|
+
}),
|
|
269
|
+
pull: (ref, platform, context, session) => run([
|
|
270
|
+
...formatArgs({ context }),
|
|
271
|
+
"image",
|
|
272
|
+
"pull",
|
|
273
|
+
ref,
|
|
274
|
+
...(platform ? ["--platform", platform] : []),
|
|
275
|
+
], undefined, outputTap(session)),
|
|
276
|
+
inspect: (ref, context) => runInspect([...formatArgs({ context }), "image", "inspect", ref]),
|
|
277
|
+
remove: (ref, force, context) => run([
|
|
278
|
+
...formatArgs({ context }),
|
|
279
|
+
"image",
|
|
280
|
+
"rm",
|
|
281
|
+
...(Array.isArray(ref) ? ref : [ref]),
|
|
282
|
+
...(force ? ["-f"] : []),
|
|
283
|
+
]),
|
|
284
|
+
tag: (source, target, context) => run([...formatArgs({ context }), "image", "tag", source, target]),
|
|
285
|
+
push,
|
|
286
|
+
},
|
|
287
|
+
volume: {
|
|
288
|
+
create: ({ context, ...options }) => run([...formatArgs({ context }), "volume", "create", ...formatArgs(options)]),
|
|
289
|
+
remove: (name, context) => run([...formatArgs({ context }), "volume", "rm", name]),
|
|
290
|
+
inspect: (name, context) => runInspect([...formatArgs({ context }), "volume", "inspect", name]),
|
|
291
|
+
},
|
|
292
|
+
context: {
|
|
293
|
+
create: ({ name, description, docker }) => run(["context", "create", name, ...formatArgs({ description, docker })]),
|
|
294
|
+
update: ({ name, description, docker }) => run(["context", "update", name, ...formatArgs({ description, docker })]),
|
|
295
|
+
inspect: (name) => runInspect(["context", "inspect", name]),
|
|
296
|
+
remove: (name, force) => run(["context", "rm", ...(force ? ["-f"] : []), name]),
|
|
297
|
+
},
|
|
298
|
+
network: {
|
|
299
|
+
create: ({ name, driver, ipv6, label, context }) => run([
|
|
300
|
+
...formatArgs({ context }),
|
|
301
|
+
"network",
|
|
302
|
+
"create",
|
|
303
|
+
name,
|
|
304
|
+
...formatArgs({ driver, ipv6, label }),
|
|
305
|
+
]),
|
|
306
|
+
connect: ({ network, container, alias, context }) => run([
|
|
307
|
+
...formatArgs({ context }),
|
|
308
|
+
"network",
|
|
309
|
+
"connect",
|
|
310
|
+
network,
|
|
311
|
+
container,
|
|
312
|
+
...(alias ? alias.flatMap((a) => ["--alias", a]) : []),
|
|
313
|
+
]),
|
|
314
|
+
disconnect: ({ network, container, context }) => run([...formatArgs({ context }), "network", "disconnect", network, container]),
|
|
315
|
+
inspect: (name, context) => runInspect([...formatArgs({ context }), "network", "inspect", name]),
|
|
316
|
+
remove: (id, context) => run([...formatArgs({ context }), "network", "rm", id]),
|
|
317
|
+
},
|
|
318
|
+
swarm: {
|
|
319
|
+
init: ({ context, ...options }) => run([...formatArgs({ context }), "swarm", "init", ...formatArgs(options)]),
|
|
320
|
+
info: (context) => run([...formatArgs({ context }), "info", "--format", "{{json .Swarm}}"]).pipe(Effect.map((result) => JSON.parse(result.stdout))),
|
|
321
|
+
leave: (force, context) => run([...formatArgs({ context }), "swarm", "leave", ...(force ? ["--force"] : [])]),
|
|
322
|
+
},
|
|
323
|
+
service: {
|
|
324
|
+
create: ({ context, image, command, args, ...options }) => run([
|
|
325
|
+
...formatArgs({ context }),
|
|
326
|
+
"service",
|
|
327
|
+
"create",
|
|
328
|
+
...formatArgs({ ...options }),
|
|
329
|
+
image,
|
|
330
|
+
...(command ?? []),
|
|
331
|
+
...(args ?? []),
|
|
332
|
+
]),
|
|
333
|
+
update: ({ context, id, ...options }) => run([
|
|
334
|
+
...formatArgs({ context }),
|
|
335
|
+
"service",
|
|
336
|
+
"update",
|
|
337
|
+
"--detach=false",
|
|
338
|
+
...formatArgs({ ...options }),
|
|
339
|
+
id,
|
|
340
|
+
]),
|
|
341
|
+
inspect: (id, context) => runInspect([...formatArgs({ context }), "service", "inspect", id]),
|
|
342
|
+
remove: (id, context) => run([...formatArgs({ context }), "service", "rm", id]),
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
/** The Docker CLI client, running `docker` (or `DOCKER_BIN`). */
|
|
347
|
+
export const DockerLive = dockerLive();
|
|
348
|
+
export const dockerContextName = (context) => {
|
|
349
|
+
const value = typeof context === "string" ? context : context?.name;
|
|
350
|
+
const normalized = value?.trim();
|
|
351
|
+
return normalized && normalized.length > 0 ? normalized : undefined;
|
|
352
|
+
};
|
|
353
|
+
/**
|
|
354
|
+
* Resolve an {@link Docker.EngineRef} to a context name. A `Docker.Swarm`
|
|
355
|
+
* reference (narrowed by its `nodeId` attribute) contributes the context the
|
|
356
|
+
* swarm was initialized on.
|
|
357
|
+
*/
|
|
358
|
+
export const dockerEngineContextName = (ref) => {
|
|
359
|
+
if (typeof ref === "object" && ref !== null && "nodeId" in ref) {
|
|
360
|
+
return dockerContextName(ref.context);
|
|
361
|
+
}
|
|
362
|
+
return dockerContextName(ref);
|
|
363
|
+
};
|
|
364
|
+
export const dockerPhysicalName = (id, props, instanceId,
|
|
365
|
+
// Swarm service names are capped at 63 characters; other Docker object
|
|
366
|
+
// names accept much longer values.
|
|
367
|
+
maxLength = 128) => props?.name
|
|
368
|
+
? Effect.succeed(props.name)
|
|
369
|
+
: createPhysicalName({ id, instanceId, maxLength, lowercase: true });
|
|
370
|
+
/**
|
|
371
|
+
* A failing `docker` command splits its diagnosis over both streams: the
|
|
372
|
+
* builder writes the step log to one and the reason it stopped to the other,
|
|
373
|
+
* and which carries which depends on the builder, the progress mode and
|
|
374
|
+
* whether the output is a terminal. A build that fails inside a `RUN` step
|
|
375
|
+
* therefore reports nothing but its exit code when only `stderr` is kept.
|
|
376
|
+
* Keep both, the reason first, so the error says why the build failed.
|
|
377
|
+
*/
|
|
378
|
+
const failureOutput = (stderr, stdout) => {
|
|
379
|
+
const output = [stderr, stdout].filter((text) => text.length > 0);
|
|
380
|
+
return output.length > 0 ? output.join("\n") : "the command wrote no output.";
|
|
381
|
+
};
|
|
382
|
+
/** Constructs a PlatformError from a command execution result. */
|
|
383
|
+
const systemError = (input) => new PlatformError(new SystemError({
|
|
384
|
+
_tag: input._tag,
|
|
385
|
+
module: "Docker",
|
|
386
|
+
method: input.args.slice(0, 2).join("."),
|
|
387
|
+
pathOrDescriptor: input.args.join(" "),
|
|
388
|
+
description: input.description,
|
|
389
|
+
cause: input.cause,
|
|
390
|
+
}));
|
|
391
|
+
/**
|
|
392
|
+
* `--secret id=<id>,env=<var>` per secret, with each value under a generated
|
|
393
|
+
* variable name: an id is the Dockerfile author's choice and may collide with
|
|
394
|
+
* the environment Docker itself reads (`PATH`, `DOCKER_HOST`).
|
|
395
|
+
*/
|
|
396
|
+
const buildSecrets = (secrets) => {
|
|
397
|
+
const args = [];
|
|
398
|
+
const env = {};
|
|
399
|
+
Object.entries(secrets ?? {}).forEach(([id, value], index) => {
|
|
400
|
+
const variable = `ALCHEMY_BUILD_SECRET_${index}`;
|
|
401
|
+
args.push("--secret", `id=${id},env=${variable}`);
|
|
402
|
+
env[variable] = Redacted.isRedacted(value) ? Redacted.value(value) : value;
|
|
403
|
+
});
|
|
404
|
+
return { args, env };
|
|
405
|
+
};
|
|
406
|
+
/** Formats a set of options into a list of command-line arguments. */
|
|
407
|
+
const formatArgs = (options) => {
|
|
408
|
+
const args = [];
|
|
409
|
+
for (const [key, value] of Object.entries(options)) {
|
|
410
|
+
// `0` is meaningful (`--replicas 0`, `--update-parallelism 0`), so only
|
|
411
|
+
// absent, `false` and empty values are omitted.
|
|
412
|
+
if (value === undefined || value === false || value === "")
|
|
413
|
+
continue;
|
|
414
|
+
const prefix = key.length > 1 ? `--${key}` : `-${key}`;
|
|
415
|
+
if (value === true) {
|
|
416
|
+
args.push(prefix);
|
|
417
|
+
}
|
|
418
|
+
else if (typeof value === "string") {
|
|
419
|
+
args.push(prefix, value);
|
|
420
|
+
}
|
|
421
|
+
else if (typeof value === "number") {
|
|
422
|
+
args.push(prefix, String(value));
|
|
423
|
+
}
|
|
424
|
+
else if (Array.isArray(value)) {
|
|
425
|
+
for (const item of value) {
|
|
426
|
+
args.push(prefix, item);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else if (value !== null && typeof value === "object") {
|
|
430
|
+
for (const [k, v] of Object.entries(value)) {
|
|
431
|
+
args.push(prefix, `${k}=${v}`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return args;
|
|
436
|
+
};
|
|
437
|
+
//# sourceMappingURL=Docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Docker.js","sourceRoot":"","sources":["../src/Docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline Dockerfile content for container platforms.
|
|
3
|
+
*
|
|
4
|
+
* Container platform props accept `dockerfile: string | { content: Input<string> }`:
|
|
5
|
+
* a plain string is always a **path** (relative to `context`); an object with a
|
|
6
|
+
* `content` key is **inline Dockerfile content**. `Dockerfile.inline` is the
|
|
7
|
+
* ergonomic way to produce the latter — a tagged template whose interpolations
|
|
8
|
+
* ride the normal {@link Output} machinery, so referencing another resource's
|
|
9
|
+
* attributes (e.g. an {@link ECR.Image}'s `imageUri`) creates a real dependency
|
|
10
|
+
* edge and re-resolves on change.
|
|
11
|
+
*
|
|
12
|
+
* The returned value is a plain JSON-serializable object (no symbols or
|
|
13
|
+
* brands) so it round-trips through persisted state unchanged; the structural
|
|
14
|
+
* `content` key is the discriminant.
|
|
15
|
+
*
|
|
16
|
+
* @example Base plus system packages, still bundling your Effect program
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import * as Dockerfile from "@alchemy.run/docker/Dockerfile";
|
|
19
|
+
*
|
|
20
|
+
* const worker = yield* AWS.ECS.Task(
|
|
21
|
+
* "Transcoder",
|
|
22
|
+
* {
|
|
23
|
+
* cluster,
|
|
24
|
+
* main: import.meta.url,
|
|
25
|
+
* dockerfile: Dockerfile.inline`
|
|
26
|
+
* FROM oven/bun:1
|
|
27
|
+
* RUN apt-get update && apt-get install -y ffmpeg
|
|
28
|
+
* `,
|
|
29
|
+
* },
|
|
30
|
+
* impl,
|
|
31
|
+
* );
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example Deriving from another resource's image (dependency edge for free)
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const base = yield* AWS.ECR.Image("MlBase", { context: "./ml-base" });
|
|
37
|
+
*
|
|
38
|
+
* const trainer = yield* AWS.ECS.Task(
|
|
39
|
+
* "Trainer",
|
|
40
|
+
* {
|
|
41
|
+
* cluster,
|
|
42
|
+
* main: import.meta.url,
|
|
43
|
+
* dockerfile: Dockerfile.inline`
|
|
44
|
+
* FROM ${base.imageUri}
|
|
45
|
+
* RUN pip install -r /opt/requirements.txt
|
|
46
|
+
* `,
|
|
47
|
+
* },
|
|
48
|
+
* impl,
|
|
49
|
+
* );
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
import type { Input } from "alchemy/Input";
|
|
53
|
+
/**
|
|
54
|
+
* Inline Dockerfile content. A plain, state-serializable object; the
|
|
55
|
+
* structural `content` key distinguishes it from a path string wherever
|
|
56
|
+
* `dockerfile` props accept `string | InlineDockerfile`.
|
|
57
|
+
*
|
|
58
|
+
* Never interpolate secrets: anything in Dockerfile content is baked into
|
|
59
|
+
* image layers. `Input<string>` excludes `Redacted` values at the type level.
|
|
60
|
+
*/
|
|
61
|
+
export interface InlineDockerfile {
|
|
62
|
+
readonly content: Input<string>;
|
|
63
|
+
}
|
|
64
|
+
/** Structural guard for {@link InlineDockerfile} vs a path string. */
|
|
65
|
+
export declare const isInlineDockerfile: (value: unknown) => value is InlineDockerfile;
|
|
66
|
+
/**
|
|
67
|
+
* Tagged template producing {@link InlineDockerfile}. Interpolations may be
|
|
68
|
+
* plain strings or `Output<string>`s (resolved at deploy time via
|
|
69
|
+
* `Output.interpolate`); with no interpolations the content is a plain string.
|
|
70
|
+
*/
|
|
71
|
+
export declare const inline: (template: TemplateStringsArray, ...args: Array<Input<string>>) => InlineDockerfile;
|
|
72
|
+
//# sourceMappingURL=Dockerfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dockerfile.d.ts","sourceRoot":"","sources":["../src/Dockerfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAG3C;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACjC;AAED,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,UAAW,OAAO,KAAG,KAAK,IAAI,gBACM,CAAC;AAEpE;;;;GAIG;AACH,eAAO,MAAM,MAAM,aACP,oBAAoB,WACrB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAC5B,gBAED,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as Output from "alchemy/Output";
|
|
2
|
+
/** Structural guard for {@link InlineDockerfile} vs a path string. */
|
|
3
|
+
export const isInlineDockerfile = (value) => typeof value === "object" && value !== null && "content" in value;
|
|
4
|
+
/**
|
|
5
|
+
* Tagged template producing {@link InlineDockerfile}. Interpolations may be
|
|
6
|
+
* plain strings or `Output<string>`s (resolved at deploy time via
|
|
7
|
+
* `Output.interpolate`); with no interpolations the content is a plain string.
|
|
8
|
+
*/
|
|
9
|
+
export const inline = (template, ...args) => ({
|
|
10
|
+
content: args.length === 0 ? template.raw.join("") : Output.interpolate(template, ...args),
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=Dockerfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dockerfile.js","sourceRoot":"","sources":["../src/Dockerfile.ts"],"names":[],"mappings":"AAoDA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAczC,sEAAsE;AACtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAc,EAA6B,EAAE,CAC9E,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,SAAS,IAAI,KAAK,CAAC;AAEpE;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,QAA8B,EAC9B,GAAG,IAA0B,EACX,EAAE,CAAC,CAAC;IACtB,OAAO,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC;CAC3F,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders a healthcheck `cmd` as the single string Docker's `--health-cmd`
|
|
3
|
+
* flag takes. The flag always runs its value through the container's shell, so
|
|
4
|
+
* the Docker API's exec form has to be flattened:
|
|
5
|
+
*
|
|
6
|
+
* - `"cmd"`: used as is.
|
|
7
|
+
* - `["CMD-SHELL", "cmd"]`: the shell command, without the marker.
|
|
8
|
+
* - `["CMD", "pg_isready", "-U", "app"]`: the arguments, each quoted so it
|
|
9
|
+
* reaches the program as one argument.
|
|
10
|
+
* - `["NONE"]`: no command (the caller disables the healthcheck).
|
|
11
|
+
* - any other array: joined with spaces and run in the shell, as before, so
|
|
12
|
+
* `["curl -f localhost || exit 1"]` keeps working.
|
|
13
|
+
*/
|
|
14
|
+
export declare const healthcheckCommand: (cmd: string[] | string) => string | undefined;
|
|
15
|
+
/** True when `cmd` is Docker's `["NONE"]` form, which disables the healthcheck. */
|
|
16
|
+
export declare const isHealthcheckDisabled: (cmd: string[] | string) => boolean;
|
|
17
|
+
//# sourceMappingURL=HealthcheckCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HealthcheckCommand.d.ts","sourceRoot":"","sources":["../src/HealthcheckCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,QAAS,MAAM,EAAE,GAAG,MAAM,KAAG,MAAM,GAAG,SAapE,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,qBAAqB,QAAS,MAAM,EAAE,GAAG,MAAM,KAAG,OACtB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders a healthcheck `cmd` as the single string Docker's `--health-cmd`
|
|
3
|
+
* flag takes. The flag always runs its value through the container's shell, so
|
|
4
|
+
* the Docker API's exec form has to be flattened:
|
|
5
|
+
*
|
|
6
|
+
* - `"cmd"`: used as is.
|
|
7
|
+
* - `["CMD-SHELL", "cmd"]`: the shell command, without the marker.
|
|
8
|
+
* - `["CMD", "pg_isready", "-U", "app"]`: the arguments, each quoted so it
|
|
9
|
+
* reaches the program as one argument.
|
|
10
|
+
* - `["NONE"]`: no command (the caller disables the healthcheck).
|
|
11
|
+
* - any other array: joined with spaces and run in the shell, as before, so
|
|
12
|
+
* `["curl -f localhost || exit 1"]` keeps working.
|
|
13
|
+
*/
|
|
14
|
+
export const healthcheckCommand = (cmd) => {
|
|
15
|
+
if (typeof cmd === "string")
|
|
16
|
+
return cmd;
|
|
17
|
+
const [head, ...rest] = cmd;
|
|
18
|
+
switch (head) {
|
|
19
|
+
case "NONE":
|
|
20
|
+
return undefined;
|
|
21
|
+
case "CMD-SHELL":
|
|
22
|
+
return rest.join(" ");
|
|
23
|
+
case "CMD":
|
|
24
|
+
return rest.map(shellQuote).join(" ");
|
|
25
|
+
default:
|
|
26
|
+
return cmd.join(" ");
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/** True when `cmd` is Docker's `["NONE"]` form, which disables the healthcheck. */
|
|
30
|
+
export const isHealthcheckDisabled = (cmd) => Array.isArray(cmd) && cmd[0] === "NONE";
|
|
31
|
+
/** Single-quotes an argument unless it is made only of shell-safe characters. */
|
|
32
|
+
const shellQuote = (arg) => /^[\w@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replaceAll("'", `'\\''`)}'`;
|
|
33
|
+
//# sourceMappingURL=HealthcheckCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HealthcheckCommand.js","sourceRoot":"","sources":["../src/HealthcheckCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAsB,EAAsB,EAAE;IAC/E,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IAC5B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,KAAK,KAAK;YACR,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC;YACE,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAEF,mFAAmF;AACnF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAsB,EAAW,EAAE,CACvE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;AAE1C,iFAAiF;AACjF,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE,CACzC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC"}
|