@mysten-incubation/devstack 0.0.0
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 +189 -0
- package/README.md +94 -0
- package/dist/_virtual/_rolldown/runtime.mjs +13 -0
- package/dist/api/define-capabilities.d.mts +25 -0
- package/dist/api/define-capabilities.mjs +19 -0
- package/dist/api/define-capabilities.mjs.map +1 -0
- package/dist/api/define-devstack-with.d.mts +41 -0
- package/dist/api/define-devstack-with.mjs +24 -0
- package/dist/api/define-devstack-with.mjs.map +1 -0
- package/dist/api/define-devstack.d.mts +62 -0
- package/dist/api/define-devstack.mjs +108 -0
- package/dist/api/define-devstack.mjs.map +1 -0
- package/dist/api/define-plugin.d.mts +1 -0
- package/dist/api/inference-network.mjs +122 -0
- package/dist/api/inference-network.mjs.map +1 -0
- package/dist/api/mode-narrowed-factory.d.mts +26 -0
- package/dist/api/mode-narrowed-factory.mjs +8 -0
- package/dist/api/mode-narrowed-factory.mjs.map +1 -0
- package/dist/api/plugin-errors.mjs +10 -0
- package/dist/api/plugin-errors.mjs.map +1 -0
- package/dist/api/run-stack.d.mts +82 -0
- package/dist/api/run-stack.mjs +127 -0
- package/dist/api/run-stack.mjs.map +1 -0
- package/dist/build-integrations/playwright/config.d.mts +92 -0
- package/dist/build-integrations/playwright/config.mjs +71 -0
- package/dist/build-integrations/playwright/config.mjs.map +1 -0
- package/dist/build-integrations/playwright/errors.d.mts +82 -0
- package/dist/build-integrations/playwright/errors.mjs +43 -0
- package/dist/build-integrations/playwright/errors.mjs.map +1 -0
- package/dist/build-integrations/playwright/global-setup.d.mts +64 -0
- package/dist/build-integrations/playwright/global-setup.mjs +44 -0
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -0
- package/dist/build-integrations/playwright/index.d.mts +6 -0
- package/dist/build-integrations/playwright/index.mjs +6 -0
- package/dist/build-integrations/playwright/stack-context.d.mts +95 -0
- package/dist/build-integrations/playwright/stack-context.mjs +277 -0
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -0
- package/dist/build-integrations/playwright/wallet-context.d.mts +87 -0
- package/dist/build-integrations/playwright/wallet-context.mjs +148 -0
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -0
- package/dist/build-integrations/runtime/cold-start-url.d.mts +67 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs +56 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -0
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs +10 -0
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -0
- package/dist/build-integrations/runtime/discover.d.mts +78 -0
- package/dist/build-integrations/runtime/discover.mjs +124 -0
- package/dist/build-integrations/runtime/discover.mjs.map +1 -0
- package/dist/build-integrations/runtime/endpoint-registry.d.mts +26 -0
- package/dist/build-integrations/runtime/endpoint-registry.mjs +41 -0
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -0
- package/dist/build-integrations/runtime/errors.d.mts +64 -0
- package/dist/build-integrations/runtime/errors.mjs +51 -0
- package/dist/build-integrations/runtime/errors.mjs.map +1 -0
- package/dist/build-integrations/runtime/index.d.mts +7 -0
- package/dist/build-integrations/runtime/index.mjs +6 -0
- package/dist/build-integrations/runtime/read-stack-context.d.mts +38 -0
- package/dist/build-integrations/runtime/read-stack-context.mjs +130 -0
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -0
- package/dist/build-integrations/runtime/stack-context.d.mts +53 -0
- package/dist/build-integrations/vitest/config.d.mts +62 -0
- package/dist/build-integrations/vitest/config.mjs +80 -0
- package/dist/build-integrations/vitest/config.mjs.map +1 -0
- package/dist/build-integrations/vitest/env.d.mts +48 -0
- package/dist/build-integrations/vitest/env.mjs +50 -0
- package/dist/build-integrations/vitest/env.mjs.map +1 -0
- package/dist/build-integrations/vitest/errors.d.mts +44 -0
- package/dist/build-integrations/vitest/errors.mjs +18 -0
- package/dist/build-integrations/vitest/errors.mjs.map +1 -0
- package/dist/build-integrations/vitest/index.d.mts +6 -0
- package/dist/build-integrations/vitest/index.mjs +6 -0
- package/dist/build-integrations/vitest/setup.d.mts +53 -0
- package/dist/build-integrations/vitest/setup.mjs +56 -0
- package/dist/build-integrations/vitest/setup.mjs.map +1 -0
- package/dist/build-integrations/vitest/stack-context.d.mts +58 -0
- package/dist/build-integrations/vitest/stack-context.mjs +67 -0
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -0
- package/dist/cli/main.d.mts +5 -0
- package/dist/cli/main.mjs +586 -0
- package/dist/cli/main.mjs.map +1 -0
- package/dist/cli/prune-direct.mjs +216 -0
- package/dist/cli/prune-direct.mjs.map +1 -0
- package/dist/cli/snapshot-reader.mjs +73 -0
- package/dist/cli/snapshot-reader.mjs.map +1 -0
- package/dist/cli/up-lifecycle.mjs +28 -0
- package/dist/cli/up-lifecycle.mjs.map +1 -0
- package/dist/contracts/capability-decl.d.mts +42 -0
- package/dist/contracts/chain-probe.d.mts +26 -0
- package/dist/contracts/chain-probe.mjs +8 -0
- package/dist/contracts/chain-probe.mjs.map +1 -0
- package/dist/contracts/codegenable.d.mts +43 -0
- package/dist/contracts/container-runtime.d.mts +245 -0
- package/dist/contracts/liveness-classifier.d.mts +19 -0
- package/dist/contracts/network-resolver.d.mts +15 -0
- package/dist/contracts/network-resolver.mjs +7 -0
- package/dist/contracts/network-resolver.mjs.map +1 -0
- package/dist/contracts/projection.d.mts +15 -0
- package/dist/contracts/routable.d.mts +53 -0
- package/dist/contracts/snapshotable.d.mts +39 -0
- package/dist/contracts/strategy-contributor.d.mts +26 -0
- package/dist/index.d.mts +89 -0
- package/dist/index.mjs +37 -0
- package/dist/orchestrators/codegen/bindings.d.mts +2 -0
- package/dist/orchestrators/codegen/bindings.mjs +340 -0
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -0
- package/dist/orchestrators/codegen/emit.mjs +56 -0
- package/dist/orchestrators/codegen/emit.mjs.map +1 -0
- package/dist/orchestrators/codegen/errors.d.mts +1 -0
- package/dist/orchestrators/codegen/errors.mjs +66 -0
- package/dist/orchestrators/codegen/errors.mjs.map +1 -0
- package/dist/orchestrators/codegen/extras.mjs +16 -0
- package/dist/orchestrators/codegen/extras.mjs.map +1 -0
- package/dist/orchestrators/codegen/format.mjs +109 -0
- package/dist/orchestrators/codegen/format.mjs.map +1 -0
- package/dist/orchestrators/codegen/gitignore.mjs +67 -0
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -0
- package/dist/orchestrators/codegen/paths.d.mts +1 -0
- package/dist/orchestrators/codegen/paths.mjs +33 -0
- package/dist/orchestrators/codegen/paths.mjs.map +1 -0
- package/dist/orchestrators/codegen/permissions.mjs +6 -0
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -0
- package/dist/orchestrators/codegen/service.d.mts +1 -0
- package/dist/orchestrators/codegen/service.mjs +276 -0
- package/dist/orchestrators/codegen/service.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs +58 -0
- package/dist/orchestrators/router/cleanup.mjs.map +1 -0
- package/dist/orchestrators/router/cors.mjs +31 -0
- package/dist/orchestrators/router/cors.mjs.map +1 -0
- package/dist/orchestrators/router/entrypoints.d.mts +1 -0
- package/dist/orchestrators/router/entrypoints.mjs +80 -0
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -0
- package/dist/orchestrators/router/errors.d.mts +1 -0
- package/dist/orchestrators/router/errors.mjs +103 -0
- package/dist/orchestrators/router/errors.mjs.map +1 -0
- package/dist/orchestrators/router/file-provider.d.mts +1 -0
- package/dist/orchestrators/router/file-provider.mjs +320 -0
- package/dist/orchestrators/router/file-provider.mjs.map +1 -0
- package/dist/orchestrators/router/hostname.d.mts +1 -0
- package/dist/orchestrators/router/hostname.mjs +107 -0
- package/dist/orchestrators/router/hostname.mjs.map +1 -0
- package/dist/orchestrators/router/index.d.mts +1 -0
- package/dist/orchestrators/router/profile.d.mts +1 -0
- package/dist/orchestrators/router/profile.mjs +109 -0
- package/dist/orchestrators/router/profile.mjs.map +1 -0
- package/dist/orchestrators/router/service.d.mts +3 -0
- package/dist/orchestrators/router/service.mjs +421 -0
- package/dist/orchestrators/router/service.mjs.map +1 -0
- package/dist/orchestrators/router/traefik-container.d.mts +1 -0
- package/dist/orchestrators/router/traefik-container.mjs +229 -0
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -0
- package/dist/orchestrators/runtime-composition.d.mts +10 -0
- package/dist/orchestrators/runtime-composition.mjs +168 -0
- package/dist/orchestrators/runtime-composition.mjs.map +1 -0
- package/dist/orchestrators/snapshot/capture.d.mts +1 -0
- package/dist/orchestrators/snapshot/capture.mjs +350 -0
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -0
- package/dist/orchestrators/snapshot/descriptor.d.mts +1 -0
- package/dist/orchestrators/snapshot/descriptor.mjs +109 -0
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -0
- package/dist/orchestrators/snapshot/identity-guard.d.mts +1 -0
- package/dist/orchestrators/snapshot/identity-guard.mjs +132 -0
- package/dist/orchestrators/snapshot/identity-guard.mjs.map +1 -0
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs +207 -0
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs.map +1 -0
- package/dist/orchestrators/snapshot/index.d.mts +1 -0
- package/dist/orchestrators/snapshot/integrity.d.mts +1 -0
- package/dist/orchestrators/snapshot/integrity.mjs +74 -0
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -0
- package/dist/orchestrators/snapshot/prune.d.mts +1 -0
- package/dist/orchestrators/snapshot/prune.mjs +110 -0
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -0
- package/dist/orchestrators/snapshot/restore.d.mts +1 -0
- package/dist/orchestrators/snapshot/restore.mjs +404 -0
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -0
- package/dist/orchestrators/snapshot/service.d.mts +1 -0
- package/dist/orchestrators/snapshot/service.mjs +296 -0
- package/dist/orchestrators/snapshot/service.mjs.map +1 -0
- package/dist/orchestrators/snapshot/state-document.mjs +18 -0
- package/dist/orchestrators/snapshot/state-document.mjs.map +1 -0
- package/dist/orchestrators/snapshot/wipe.d.mts +1 -0
- package/dist/orchestrators/snapshot/wipe.mjs +59 -0
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -0
- package/dist/plugins/account/codegen.d.mts +12 -0
- package/dist/plugins/account/codegen.mjs +22 -0
- package/dist/plugins/account/codegen.mjs.map +1 -0
- package/dist/plugins/account/errors.d.mts +44 -0
- package/dist/plugins/account/errors.mjs +16 -0
- package/dist/plugins/account/errors.mjs.map +1 -0
- package/dist/plugins/account/funding.d.mts +94 -0
- package/dist/plugins/account/funding.mjs +199 -0
- package/dist/plugins/account/funding.mjs.map +1 -0
- package/dist/plugins/account/index.d.mts +54 -0
- package/dist/plugins/account/index.mjs +151 -0
- package/dist/plugins/account/index.mjs.map +1 -0
- package/dist/plugins/account/keypair.d.mts +32 -0
- package/dist/plugins/account/keypair.mjs +99 -0
- package/dist/plugins/account/keypair.mjs.map +1 -0
- package/dist/plugins/account/lease.mjs +21 -0
- package/dist/plugins/account/lease.mjs.map +1 -0
- package/dist/plugins/account/registry.d.mts +33 -0
- package/dist/plugins/account/registry.mjs +36 -0
- package/dist/plugins/account/registry.mjs.map +1 -0
- package/dist/plugins/account/service.d.mts +104 -0
- package/dist/plugins/account/service.mjs +405 -0
- package/dist/plugins/account/service.mjs.map +1 -0
- package/dist/plugins/account/snapshot.mjs +33 -0
- package/dist/plugins/account/snapshot.mjs.map +1 -0
- package/dist/plugins/account/variants/env.mjs +24 -0
- package/dist/plugins/account/variants/env.mjs.map +1 -0
- package/dist/plugins/account/variants/ephemeral.mjs +72 -0
- package/dist/plugins/account/variants/ephemeral.mjs.map +1 -0
- package/dist/plugins/account/variants/impersonate.d.mts +16 -0
- package/dist/plugins/account/variants/impersonate.mjs +48 -0
- package/dist/plugins/account/variants/impersonate.mjs.map +1 -0
- package/dist/plugins/account/variants/inline.mjs +13 -0
- package/dist/plugins/account/variants/inline.mjs.map +1 -0
- package/dist/plugins/account/variants/keystore.mjs +93 -0
- package/dist/plugins/account/variants/keystore.mjs.map +1 -0
- package/dist/plugins/account/variants/signer.mjs +31 -0
- package/dist/plugins/account/variants/signer.mjs.map +1 -0
- package/dist/plugins/action/build-context.d.mts +41 -0
- package/dist/plugins/action/discriminator.d.mts +20 -0
- package/dist/plugins/action/discriminator.mjs +13 -0
- package/dist/plugins/action/discriminator.mjs.map +1 -0
- package/dist/plugins/action/errors.d.mts +31 -0
- package/dist/plugins/action/errors.mjs +13 -0
- package/dist/plugins/action/errors.mjs.map +1 -0
- package/dist/plugins/action/execute.d.mts +2 -0
- package/dist/plugins/action/execute.mjs +145 -0
- package/dist/plugins/action/execute.mjs.map +1 -0
- package/dist/plugins/action/index.d.mts +56 -0
- package/dist/plugins/action/index.mjs +82 -0
- package/dist/plugins/action/index.mjs.map +1 -0
- package/dist/plugins/action/service.d.mts +26 -0
- package/dist/plugins/action/service.mjs +84 -0
- package/dist/plugins/action/service.mjs.map +1 -0
- package/dist/plugins/coin/address-resolution.d.mts +34 -0
- package/dist/plugins/coin/address-resolution.mjs +80 -0
- package/dist/plugins/coin/address-resolution.mjs.map +1 -0
- package/dist/plugins/coin/codegen.d.mts +16 -0
- package/dist/plugins/coin/codegen.mjs +21 -0
- package/dist/plugins/coin/codegen.mjs.map +1 -0
- package/dist/plugins/coin/discovery.d.mts +26 -0
- package/dist/plugins/coin/discovery.mjs +112 -0
- package/dist/plugins/coin/discovery.mjs.map +1 -0
- package/dist/plugins/coin/errors.d.mts +48 -0
- package/dist/plugins/coin/errors.mjs +13 -0
- package/dist/plugins/coin/errors.mjs.map +1 -0
- package/dist/plugins/coin/index.d.mts +95 -0
- package/dist/plugins/coin/index.mjs +172 -0
- package/dist/plugins/coin/index.mjs.map +1 -0
- package/dist/plugins/coin/metadata.d.mts +15 -0
- package/dist/plugins/coin/metadata.mjs +99 -0
- package/dist/plugins/coin/metadata.mjs.map +1 -0
- package/dist/plugins/coin/mint.d.mts +34 -0
- package/dist/plugins/coin/mint.mjs +164 -0
- package/dist/plugins/coin/mint.mjs.map +1 -0
- package/dist/plugins/coin/registry.d.mts +1 -0
- package/dist/plugins/coin/registry.mjs +37 -0
- package/dist/plugins/coin/registry.mjs.map +1 -0
- package/dist/plugins/coin/service.d.mts +47 -0
- package/dist/plugins/coin/service.mjs +51 -0
- package/dist/plugins/coin/service.mjs.map +1 -0
- package/dist/plugins/coin/snapshot.mjs +19 -0
- package/dist/plugins/coin/snapshot.mjs.map +1 -0
- package/dist/plugins/coin/type-strings.mjs +49 -0
- package/dist/plugins/coin/type-strings.mjs.map +1 -0
- package/dist/plugins/deepbook/codegen.d.mts +39 -0
- package/dist/plugins/deepbook/codegen.mjs +15 -0
- package/dist/plugins/deepbook/codegen.mjs.map +1 -0
- package/dist/plugins/deepbook/deploy.mjs +437 -0
- package/dist/plugins/deepbook/deploy.mjs.map +1 -0
- package/dist/plugins/deepbook/errors.d.mts +29 -0
- package/dist/plugins/deepbook/errors.mjs +26 -0
- package/dist/plugins/deepbook/errors.mjs.map +1 -0
- package/dist/plugins/deepbook/faucet-strategy.d.mts +8 -0
- package/dist/plugins/deepbook/faucet-strategy.mjs +81 -0
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -0
- package/dist/plugins/deepbook/index.d.mts +171 -0
- package/dist/plugins/deepbook/index.mjs +359 -0
- package/dist/plugins/deepbook/index.mjs.map +1 -0
- package/dist/plugins/deepbook/plugin-key.mjs +7 -0
- package/dist/plugins/deepbook/plugin-key.mjs.map +1 -0
- package/dist/plugins/deepbook/pyth/index.mjs +226 -0
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -0
- package/dist/plugins/deepbook/routable.mjs +21 -0
- package/dist/plugins/deepbook/routable.mjs.map +1 -0
- package/dist/plugins/deepbook/snapshot.mjs +49 -0
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -0
- package/dist/plugins/deepbook/types.d.mts +125 -0
- package/dist/plugins/deepbook/types.mjs +12 -0
- package/dist/plugins/deepbook/types.mjs.map +1 -0
- package/dist/plugins/faucet/dispatcher.d.mts +9 -0
- package/dist/plugins/faucet/dispatcher.mjs +13 -0
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -0
- package/dist/plugins/faucet/errors.d.mts +86 -0
- package/dist/plugins/faucet/errors.mjs +19 -0
- package/dist/plugins/faucet/errors.mjs.map +1 -0
- package/dist/plugins/faucet/http.mjs +127 -0
- package/dist/plugins/faucet/http.mjs.map +1 -0
- package/dist/plugins/faucet/index.d.mts +43 -0
- package/dist/plugins/faucet/index.mjs +42 -0
- package/dist/plugins/faucet/index.mjs.map +1 -0
- package/dist/plugins/faucet/service.d.mts +20 -0
- package/dist/plugins/faucet/strategies/sui-local.d.mts +23 -0
- package/dist/plugins/faucet/strategies/sui-local.mjs +29 -0
- package/dist/plugins/faucet/strategies/sui-local.mjs.map +1 -0
- package/dist/plugins/host-service/errors.d.mts +27 -0
- package/dist/plugins/host-service/errors.mjs +14 -0
- package/dist/plugins/host-service/errors.mjs.map +1 -0
- package/dist/plugins/host-service/index.d.mts +10 -0
- package/dist/plugins/host-service/index.mjs +48 -0
- package/dist/plugins/host-service/index.mjs.map +1 -0
- package/dist/plugins/host-service/routable.mjs +24 -0
- package/dist/plugins/host-service/routable.mjs.map +1 -0
- package/dist/plugins/host-service/service.d.mts +49 -0
- package/dist/plugins/host-service/service.mjs +375 -0
- package/dist/plugins/host-service/service.mjs.map +1 -0
- package/dist/plugins/package/build.d.mts +1 -0
- package/dist/plugins/package/build.mjs +24 -0
- package/dist/plugins/package/build.mjs.map +1 -0
- package/dist/plugins/package/codegen.d.mts +19 -0
- package/dist/plugins/package/codegen.mjs +41 -0
- package/dist/plugins/package/codegen.mjs.map +1 -0
- package/dist/plugins/package/dep-resolution.mjs +10 -0
- package/dist/plugins/package/dep-resolution.mjs.map +1 -0
- package/dist/plugins/package/errors.d.mts +34 -0
- package/dist/plugins/package/errors.mjs +13 -0
- package/dist/plugins/package/errors.mjs.map +1 -0
- package/dist/plugins/package/index.d.mts +109 -0
- package/dist/plugins/package/index.mjs +207 -0
- package/dist/plugins/package/index.mjs.map +1 -0
- package/dist/plugins/package/mode-known.mjs +41 -0
- package/dist/plugins/package/mode-known.mjs.map +1 -0
- package/dist/plugins/package/mode-local.d.mts +1 -0
- package/dist/plugins/package/mode-local.mjs +183 -0
- package/dist/plugins/package/mode-local.mjs.map +1 -0
- package/dist/plugins/package/publish-executor.mjs +202 -0
- package/dist/plugins/package/publish-executor.mjs.map +1 -0
- package/dist/plugins/package/publish-output.d.mts +28 -0
- package/dist/plugins/package/publish-output.mjs +45 -0
- package/dist/plugins/package/publish-output.mjs.map +1 -0
- package/dist/plugins/package/registry.d.mts +25 -0
- package/dist/plugins/package/registry.mjs +30 -0
- package/dist/plugins/package/registry.mjs.map +1 -0
- package/dist/plugins/package/service.mjs +20 -0
- package/dist/plugins/package/service.mjs.map +1 -0
- package/dist/plugins/package/snapshot.mjs +25 -0
- package/dist/plugins/package/snapshot.mjs.map +1 -0
- package/dist/plugins/postgres/codegen.mjs +42 -0
- package/dist/plugins/postgres/codegen.mjs.map +1 -0
- package/dist/plugins/postgres/connection.d.mts +33 -0
- package/dist/plugins/postgres/connection.mjs +19 -0
- package/dist/plugins/postgres/connection.mjs.map +1 -0
- package/dist/plugins/postgres/db-ensure.mjs +100 -0
- package/dist/plugins/postgres/db-ensure.mjs.map +1 -0
- package/dist/plugins/postgres/errors.d.mts +55 -0
- package/dist/plugins/postgres/errors.mjs +29 -0
- package/dist/plugins/postgres/errors.mjs.map +1 -0
- package/dist/plugins/postgres/index.d.mts +37 -0
- package/dist/plugins/postgres/index.mjs +75 -0
- package/dist/plugins/postgres/index.mjs.map +1 -0
- package/dist/plugins/postgres/routable.mjs +33 -0
- package/dist/plugins/postgres/routable.mjs.map +1 -0
- package/dist/plugins/postgres/service.d.mts +50 -0
- package/dist/plugins/postgres/service.mjs +145 -0
- package/dist/plugins/postgres/service.mjs.map +1 -0
- package/dist/plugins/postgres/snapshot.d.mts +1 -0
- package/dist/plugins/postgres/snapshot.mjs +32 -0
- package/dist/plugins/postgres/snapshot.mjs.map +1 -0
- package/dist/plugins/router-entrypoints.mjs +21 -0
- package/dist/plugins/router-entrypoints.mjs.map +1 -0
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +59 -0
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -0
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +132 -0
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -0
- package/dist/plugins/seal/codegen.d.mts +19 -0
- package/dist/plugins/seal/codegen.mjs +16 -0
- package/dist/plugins/seal/codegen.mjs.map +1 -0
- package/dist/plugins/seal/config-render.mjs +82 -0
- package/dist/plugins/seal/config-render.mjs.map +1 -0
- package/dist/plugins/seal/deploy.mjs +198 -0
- package/dist/plugins/seal/deploy.mjs.map +1 -0
- package/dist/plugins/seal/errors.d.mts +52 -0
- package/dist/plugins/seal/errors.mjs +19 -0
- package/dist/plugins/seal/errors.mjs.map +1 -0
- package/dist/plugins/seal/index.d.mts +161 -0
- package/dist/plugins/seal/index.mjs +235 -0
- package/dist/plugins/seal/index.mjs.map +1 -0
- package/dist/plugins/seal/key-manager.d.mts +22 -0
- package/dist/plugins/seal/key-manager.mjs +22 -0
- package/dist/plugins/seal/key-manager.mjs.map +1 -0
- package/dist/plugins/seal/key-server.mjs +175 -0
- package/dist/plugins/seal/key-server.mjs.map +1 -0
- package/dist/plugins/seal/keygen.mjs +96 -0
- package/dist/plugins/seal/keygen.mjs.map +1 -0
- package/dist/plugins/seal/mode/fork-known.d.mts +8 -0
- package/dist/plugins/seal/mode/fork-known.mjs +23 -0
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -0
- package/dist/plugins/seal/mode/live.d.mts +18 -0
- package/dist/plugins/seal/mode/live.mjs +64 -0
- package/dist/plugins/seal/mode/live.mjs.map +1 -0
- package/dist/plugins/seal/mode/local-keygen.mjs +180 -0
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -0
- package/dist/plugins/seal/plugin-key.mjs +7 -0
- package/dist/plugins/seal/plugin-key.mjs.map +1 -0
- package/dist/plugins/seal/registry-publish.d.mts +43 -0
- package/dist/plugins/seal/registry-publish.mjs +9 -0
- package/dist/plugins/seal/registry-publish.mjs.map +1 -0
- package/dist/plugins/seal/routable.mjs +57 -0
- package/dist/plugins/seal/routable.mjs.map +1 -0
- package/dist/plugins/seal/service.mjs +17 -0
- package/dist/plugins/seal/service.mjs.map +1 -0
- package/dist/plugins/seal/snapshot.mjs +51 -0
- package/dist/plugins/seal/snapshot.mjs.map +1 -0
- package/dist/plugins/sui/auto-tick.mjs +45 -0
- package/dist/plugins/sui/auto-tick.mjs.map +1 -0
- package/dist/plugins/sui/chain-build-container.d.mts +1 -0
- package/dist/plugins/sui/chain-probe.d.mts +85 -0
- package/dist/plugins/sui/chain-probe.mjs +104 -0
- package/dist/plugins/sui/chain-probe.mjs.map +1 -0
- package/dist/plugins/sui/codegen.d.mts +14 -0
- package/dist/plugins/sui/codegen.mjs +26 -0
- package/dist/plugins/sui/codegen.mjs.map +1 -0
- package/dist/plugins/sui/errors.d.mts +74 -0
- package/dist/plugins/sui/errors.mjs +28 -0
- package/dist/plugins/sui/errors.mjs.map +1 -0
- package/dist/plugins/sui/fork-orchestration.mjs +24 -0
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -0
- package/dist/plugins/sui/fork-transaction.mjs +96 -0
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -0
- package/dist/plugins/sui/index.d.mts +318 -0
- package/dist/plugins/sui/index.mjs +182 -0
- package/dist/plugins/sui/index.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +60 -0
- package/dist/plugins/sui/mode/external.mjs.map +1 -0
- package/dist/plugins/sui/mode/fork.mjs +283 -0
- package/dist/plugins/sui/mode/fork.mjs.map +1 -0
- package/dist/plugins/sui/mode/live.mjs +103 -0
- package/dist/plugins/sui/mode/live.mjs.map +1 -0
- package/dist/plugins/sui/mode/local.mjs +293 -0
- package/dist/plugins/sui/mode/local.mjs.map +1 -0
- package/dist/plugins/sui/mode/shared-boot.mjs +254 -0
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -0
- package/dist/plugins/sui/mode/shared.d.mts +103 -0
- package/dist/plugins/sui/mode/shared.mjs +12 -0
- package/dist/plugins/sui/mode/shared.mjs.map +1 -0
- package/dist/plugins/sui/mode/spec.d.mts +94 -0
- package/dist/plugins/sui/network-resolver.d.mts +23 -0
- package/dist/plugins/sui/routable.mjs +88 -0
- package/dist/plugins/sui/routable.mjs.map +1 -0
- package/dist/plugins/sui/seed-objects.d.mts +18 -0
- package/dist/plugins/sui/seed-objects.mjs +25 -0
- package/dist/plugins/sui/seed-objects.mjs.map +1 -0
- package/dist/plugins/sui/service.mjs +38 -0
- package/dist/plugins/sui/service.mjs.map +1 -0
- package/dist/plugins/sui/snapshot.mjs +53 -0
- package/dist/plugins/sui/snapshot.mjs.map +1 -0
- package/dist/plugins/wallet/codegen.d.mts +33 -0
- package/dist/plugins/wallet/codegen.mjs +34 -0
- package/dist/plugins/wallet/codegen.mjs.map +1 -0
- package/dist/plugins/wallet/errors.d.mts +66 -0
- package/dist/plugins/wallet/errors.mjs +16 -0
- package/dist/plugins/wallet/errors.mjs.map +1 -0
- package/dist/plugins/wallet/index.d.mts +63 -0
- package/dist/plugins/wallet/index.mjs +126 -0
- package/dist/plugins/wallet/index.mjs.map +1 -0
- package/dist/plugins/wallet/origin-policy.d.mts +1 -0
- package/dist/plugins/wallet/origin-policy.mjs +65 -0
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -0
- package/dist/plugins/wallet/pairing.d.mts +11 -0
- package/dist/plugins/wallet/pairing.mjs +125 -0
- package/dist/plugins/wallet/pairing.mjs.map +1 -0
- package/dist/plugins/wallet/protocol.d.mts +1 -0
- package/dist/plugins/wallet/protocol.mjs +96 -0
- package/dist/plugins/wallet/protocol.mjs.map +1 -0
- package/dist/plugins/wallet/routable.mjs +32 -0
- package/dist/plugins/wallet/routable.mjs.map +1 -0
- package/dist/plugins/wallet/server.d.mts +12 -0
- package/dist/plugins/wallet/server.mjs +317 -0
- package/dist/plugins/wallet/server.mjs.map +1 -0
- package/dist/plugins/wallet/service.d.mts +68 -0
- package/dist/plugins/wallet/service.mjs +97 -0
- package/dist/plugins/wallet/service.mjs.map +1 -0
- package/dist/plugins/wallet/snapshot.d.mts +1 -0
- package/dist/plugins/wallet/snapshot.mjs +14 -0
- package/dist/plugins/wallet/snapshot.mjs.map +1 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +42 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -0
- package/dist/plugins/walrus/codegen.d.mts +38 -0
- package/dist/plugins/walrus/codegen.mjs +34 -0
- package/dist/plugins/walrus/codegen.mjs.map +1 -0
- package/dist/plugins/walrus/deploy-paths.mjs +14 -0
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -0
- package/dist/plugins/walrus/deploy.d.mts +1 -0
- package/dist/plugins/walrus/deploy.mjs +224 -0
- package/dist/plugins/walrus/deploy.mjs.map +1 -0
- package/dist/plugins/walrus/errors.d.mts +38 -0
- package/dist/plugins/walrus/errors.mjs +26 -0
- package/dist/plugins/walrus/errors.mjs.map +1 -0
- package/dist/plugins/walrus/faucet-strategy.d.mts +12 -0
- package/dist/plugins/walrus/faucet-strategy.mjs +62 -0
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -0
- package/dist/plugins/walrus/index.d.mts +177 -0
- package/dist/plugins/walrus/index.mjs +284 -0
- package/dist/plugins/walrus/index.mjs.map +1 -0
- package/dist/plugins/walrus/mode/known-deploy.d.mts +25 -0
- package/dist/plugins/walrus/mode/known-deploy.mjs +71 -0
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -0
- package/dist/plugins/walrus/mode/local-cluster.d.mts +34 -0
- package/dist/plugins/walrus/mode/local-cluster.mjs +153 -0
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -0
- package/dist/plugins/walrus/plugin-key.mjs +7 -0
- package/dist/plugins/walrus/plugin-key.mjs.map +1 -0
- package/dist/plugins/walrus/registry-publish.d.mts +24 -0
- package/dist/plugins/walrus/registry-publish.mjs +7 -0
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -0
- package/dist/plugins/walrus/routable.mjs +99 -0
- package/dist/plugins/walrus/routable.mjs.map +1 -0
- package/dist/plugins/walrus/service.mjs +20 -0
- package/dist/plugins/walrus/service.mjs.map +1 -0
- package/dist/plugins/walrus/snapshot.mjs +53 -0
- package/dist/plugins/walrus/snapshot.mjs.map +1 -0
- package/dist/plugins/walrus/storage-nodes.d.mts +15 -0
- package/dist/plugins/walrus/storage-nodes.mjs +154 -0
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -0
- package/dist/plugins/walrus/wal-swap.d.mts +2 -0
- package/dist/plugins/walrus/wal-swap.mjs +58 -0
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -0
- package/dist/primitives/artifact-publisher.d.mts +12 -0
- package/dist/primitives/cache.d.mts +1 -0
- package/dist/runtime/built-in-plugin-layers.mjs +49 -0
- package/dist/runtime/built-in-plugin-layers.mjs.map +1 -0
- package/dist/runtime/docker/client.d.mts +2 -0
- package/dist/runtime/docker/client.mjs +54 -0
- package/dist/runtime/docker/client.mjs.map +1 -0
- package/dist/runtime/docker/container.d.mts +1 -0
- package/dist/runtime/docker/container.mjs +562 -0
- package/dist/runtime/docker/container.mjs.map +1 -0
- package/dist/runtime/docker/errors.d.mts +1 -0
- package/dist/runtime/docker/errors.mjs +187 -0
- package/dist/runtime/docker/errors.mjs.map +1 -0
- package/dist/runtime/docker/exec.d.mts +1 -0
- package/dist/runtime/docker/exec.mjs +63 -0
- package/dist/runtime/docker/exec.mjs.map +1 -0
- package/dist/runtime/docker/image.d.mts +1 -0
- package/dist/runtime/docker/image.mjs +278 -0
- package/dist/runtime/docker/image.mjs.map +1 -0
- package/dist/runtime/docker/index.d.mts +1 -0
- package/dist/runtime/docker/inventory.d.mts +1 -0
- package/dist/runtime/docker/inventory.mjs +167 -0
- package/dist/runtime/docker/inventory.mjs.map +1 -0
- package/dist/runtime/docker/labels.d.mts +1 -0
- package/dist/runtime/docker/labels.mjs +97 -0
- package/dist/runtime/docker/labels.mjs.map +1 -0
- package/dist/runtime/docker/logs.d.mts +1 -0
- package/dist/runtime/docker/logs.mjs +34 -0
- package/dist/runtime/docker/logs.mjs.map +1 -0
- package/dist/runtime/docker/network.d.mts +1 -0
- package/dist/runtime/docker/network.mjs +168 -0
- package/dist/runtime/docker/network.mjs.map +1 -0
- package/dist/runtime/docker/service.d.mts +9 -0
- package/dist/runtime/docker/service.mjs +266 -0
- package/dist/runtime/docker/service.mjs.map +1 -0
- package/dist/runtime/docker/sweep.d.mts +1 -0
- package/dist/runtime/docker/sweep.mjs +220 -0
- package/dist/runtime/docker/sweep.mjs.map +1 -0
- package/dist/runtime/docker/volume.d.mts +1 -0
- package/dist/runtime/docker/volume.mjs +24 -0
- package/dist/runtime/docker/volume.mjs.map +1 -0
- package/dist/runtime/docker/wrap.d.mts +1 -0
- package/dist/runtime/docker/wrap.mjs +131 -0
- package/dist/runtime/docker/wrap.mjs.map +1 -0
- package/dist/substrate/brand.d.mts +24 -0
- package/dist/substrate/brand.mjs +14 -0
- package/dist/substrate/brand.mjs.map +1 -0
- package/dist/substrate/cross-process.d.mts +1 -0
- package/dist/substrate/cross-process.mjs +28 -0
- package/dist/substrate/cross-process.mjs.map +1 -0
- package/dist/substrate/events.d.mts +117 -0
- package/dist/substrate/identity.d.mts +13 -0
- package/dist/substrate/lifecycle.d.mts +12 -0
- package/dist/substrate/manifest.d.mts +39 -0
- package/dist/substrate/manifest.mjs +33 -0
- package/dist/substrate/manifest.mjs.map +1 -0
- package/dist/substrate/network.d.mts +34 -0
- package/dist/substrate/options.d.mts +23 -0
- package/dist/substrate/plugin.d.mts +101 -0
- package/dist/substrate/plugin.mjs +61 -0
- package/dist/substrate/plugin.mjs.map +1 -0
- package/dist/substrate/projection.d.mts +100 -0
- package/dist/substrate/runtime/artifact-publisher/index.mjs +76 -0
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -0
- package/dist/substrate/runtime/atomic-write.mjs +106 -0
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -0
- package/dist/substrate/runtime/cache/index.d.mts +1 -0
- package/dist/substrate/runtime/cache/schema.d.mts +1 -0
- package/dist/substrate/runtime/cache/schema.mjs +22 -0
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -0
- package/dist/substrate/runtime/cache/service.d.mts +1 -0
- package/dist/substrate/runtime/cache/service.mjs +89 -0
- package/dist/substrate/runtime/cache/service.mjs.map +1 -0
- package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -0
- package/dist/substrate/runtime/capability-sinks/layer.d.mts +1 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs +31 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs.map +1 -0
- package/dist/substrate/runtime/capability-sinks/service.d.mts +36 -0
- package/dist/substrate/runtime/capability-sinks/service.mjs +74 -0
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -0
- package/dist/substrate/runtime/config-validation.d.mts +38 -0
- package/dist/substrate/runtime/config-validation.mjs +137 -0
- package/dist/substrate/runtime/config-validation.mjs.map +1 -0
- package/dist/substrate/runtime/context-helpers.mjs +32 -0
- package/dist/substrate/runtime/context-helpers.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +128 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +136 -0
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +49 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +9 -0
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs +119 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/roster.mjs +275 -0
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +117 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/stack-lock.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +142 -0
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -0
- package/dist/substrate/runtime/current-plugin.mjs +15 -0
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -0
- package/dist/substrate/runtime/errors.d.mts +1 -0
- package/dist/substrate/runtime/errors.mjs +76 -0
- package/dist/substrate/runtime/errors.mjs.map +1 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs +364 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -0
- package/dist/substrate/runtime/http-probe.d.mts +35 -0
- package/dist/substrate/runtime/http-probe.mjs +65 -0
- package/dist/substrate/runtime/http-probe.mjs.map +1 -0
- package/dist/substrate/runtime/lease-broker/index.d.mts +1 -0
- package/dist/substrate/runtime/lease-broker/service.d.mts +64 -0
- package/dist/substrate/runtime/lease-broker/service.mjs +155 -0
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +138 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/index.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs +31 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +133 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs +34 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +43 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/signals.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/signals.mjs +64 -0
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/state-machine.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/state-machine.mjs +38 -0
- package/dist/substrate/runtime/lifecycle/state-machine.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +27 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -0
- package/dist/substrate/runtime/managed-container.d.mts +30 -0
- package/dist/substrate/runtime/managed-container.mjs +32 -0
- package/dist/substrate/runtime/managed-container.mjs.map +1 -0
- package/dist/substrate/runtime/manifest/manifest.mjs +73 -0
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -0
- package/dist/substrate/runtime/mode-errors.d.mts +36 -0
- package/dist/substrate/runtime/observability/cascade-formatter.d.mts +1 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +135 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -0
- package/dist/substrate/runtime/observability/formatter-registry.d.mts +1 -0
- package/dist/substrate/runtime/observability/formatter-registry.mjs +65 -0
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -0
- package/dist/substrate/runtime/observability/index.d.mts +3 -0
- package/dist/substrate/runtime/observability/logger.d.mts +58 -0
- package/dist/substrate/runtime/observability/logger.mjs +89 -0
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -0
- package/dist/substrate/runtime/observability/pretty-error.d.mts +1 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs +119 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -0
- package/dist/substrate/runtime/observability/process-lines.d.mts +31 -0
- package/dist/substrate/runtime/observability/process-lines.mjs +40 -0
- package/dist/substrate/runtime/observability/process-lines.mjs.map +1 -0
- package/dist/substrate/runtime/observability/redaction.d.mts +28 -0
- package/dist/substrate/runtime/observability/redaction.mjs +45 -0
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -0
- package/dist/substrate/runtime/observability/spans.d.mts +1 -0
- package/dist/substrate/runtime/observability/spans.mjs +87 -0
- package/dist/substrate/runtime/observability/spans.mjs.map +1 -0
- package/dist/substrate/runtime/observability/subprocess-capture.d.mts +2 -0
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +82 -0
- package/dist/substrate/runtime/observability/subprocess-capture.mjs.map +1 -0
- package/dist/substrate/runtime/paths.d.mts +17 -0
- package/dist/substrate/runtime/paths.mjs +61 -0
- package/dist/substrate/runtime/paths.mjs.map +1 -0
- package/dist/substrate/runtime/port-broker/index.d.mts +1 -0
- package/dist/substrate/runtime/port-broker/service.d.mts +1 -0
- package/dist/substrate/runtime/port-broker/service.mjs +319 -0
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -0
- package/dist/substrate/runtime/post-acquire-tasks.d.mts +1 -0
- package/dist/substrate/runtime/post-acquire-tasks.mjs +34 -0
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -0
- package/dist/substrate/runtime/probes.d.mts +51 -0
- package/dist/substrate/runtime/probes.mjs +84 -0
- package/dist/substrate/runtime/probes.mjs.map +1 -0
- package/dist/substrate/runtime/process-supervisor.d.mts +57 -0
- package/dist/substrate/runtime/process-supervisor.mjs +73 -0
- package/dist/substrate/runtime/process-supervisor.mjs.map +1 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs +44 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -0
- package/dist/substrate/runtime/projection/persisted.mjs +195 -0
- package/dist/substrate/runtime/projection/persisted.mjs.map +1 -0
- package/dist/substrate/runtime/projection/state-ref.mjs +48 -0
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -0
- package/dist/substrate/runtime/projection/update.mjs +200 -0
- package/dist/substrate/runtime/projection/update.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +18 -0
- package/dist/substrate/runtime/retry-policy.mjs +16 -0
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -0
- package/dist/substrate/runtime/run.mjs +86 -0
- package/dist/substrate/runtime/run.mjs.map +1 -0
- package/dist/substrate/runtime/runtime-decode.d.mts +32 -0
- package/dist/substrate/runtime/runtime-decode.mjs +53 -0
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-http-server.mjs +36 -0
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +83 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -0
- package/dist/substrate/runtime/stage-and-swap/index.d.mts +1 -0
- package/dist/substrate/runtime/stage-and-swap/index.mjs +131 -0
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -0
- package/dist/substrate/runtime/state-store/schema.mjs +36 -0
- package/dist/substrate/runtime/state-store/schema.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +22 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +30 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/index.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/service.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs +67 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -0
- package/dist/substrate/runtime/sui-execute/index.d.mts +11 -0
- package/dist/substrate/runtime/sui-execute/index.mjs +144 -0
- package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -0
- package/dist/substrate/runtime/sui-move-build/index.d.mts +1 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs +283 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor.d.mts +1 -0
- package/dist/substrate/runtime/supervisor.mjs +831 -0
- package/dist/substrate/runtime/supervisor.mjs.map +1 -0
- package/dist/surfaces/cli/command-tree.mjs +276 -0
- package/dist/surfaces/cli/command-tree.mjs.map +1 -0
- package/dist/surfaces/cli/commands/config.mjs +31 -0
- package/dist/surfaces/cli/commands/config.mjs.map +1 -0
- package/dist/surfaces/cli/commands/confirm-node.mjs +26 -0
- package/dist/surfaces/cli/commands/confirm-node.mjs.map +1 -0
- package/dist/surfaces/cli/commands/confirm.mjs +26 -0
- package/dist/surfaces/cli/commands/confirm.mjs.map +1 -0
- package/dist/surfaces/cli/commands/doctor-probes.mjs +452 -0
- package/dist/surfaces/cli/commands/doctor-probes.mjs.map +1 -0
- package/dist/surfaces/cli/commands/doctor.mjs +38 -0
- package/dist/surfaces/cli/commands/doctor.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs +347 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune.mjs +178 -0
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -0
- package/dist/surfaces/cli/commands/snapshot.mjs +141 -0
- package/dist/surfaces/cli/commands/snapshot.mjs.map +1 -0
- package/dist/surfaces/cli/commands/status.mjs +95 -0
- package/dist/surfaces/cli/commands/status.mjs.map +1 -0
- package/dist/surfaces/cli/commands/supervisor-presence.mjs +33 -0
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -0
- package/dist/surfaces/cli/commands/wipe.mjs +28 -0
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -0
- package/dist/surfaces/cli/envelope.mjs +43 -0
- package/dist/surfaces/cli/envelope.mjs.map +1 -0
- package/dist/surfaces/cli/errors.mjs +110 -0
- package/dist/surfaces/cli/errors.mjs.map +1 -0
- package/dist/surfaces/cli/flags.mjs +56 -0
- package/dist/surfaces/cli/flags.mjs.map +1 -0
- package/dist/surfaces/cli/index.mjs +418 -0
- package/dist/surfaces/cli/index.mjs.map +1 -0
- package/dist/surfaces/cli/output.mjs +115 -0
- package/dist/surfaces/cli/output.mjs.map +1 -0
- package/dist/surfaces/cli/sysexits.mjs +139 -0
- package/dist/surfaces/cli/sysexits.mjs.map +1 -0
- package/dist/surfaces/tui/app.mjs +104 -0
- package/dist/surfaces/tui/app.mjs.map +1 -0
- package/dist/surfaces/tui/dashboard.mjs +261 -0
- package/dist/surfaces/tui/dashboard.mjs.map +1 -0
- package/dist/surfaces/tui/display-derivation.mjs +395 -0
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -0
- package/dist/surfaces/tui/errors.mjs +11 -0
- package/dist/surfaces/tui/errors.mjs.map +1 -0
- package/dist/surfaces/tui/event-log.mjs +155 -0
- package/dist/surfaces/tui/event-log.mjs.map +1 -0
- package/dist/surfaces/tui/heartbeat.mjs +33 -0
- package/dist/surfaces/tui/heartbeat.mjs.map +1 -0
- package/dist/surfaces/tui/index.mjs +50 -0
- package/dist/surfaces/tui/index.mjs.map +1 -0
- package/dist/surfaces/tui/input.mjs +104 -0
- package/dist/surfaces/tui/input.mjs.map +1 -0
- package/dist/surfaces/tui/mode-detect.mjs +32 -0
- package/dist/surfaces/tui/mode-detect.mjs.map +1 -0
- package/dist/surfaces/tui/mount-ink.mjs +31 -0
- package/dist/surfaces/tui/mount-ink.mjs.map +1 -0
- package/dist/surfaces/tui/plain-renderer.mjs +170 -0
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -0
- package/dist/surfaces/tui/resource-table.mjs +507 -0
- package/dist/surfaces/tui/resource-table.mjs.map +1 -0
- package/images/_shared/signal-forward.sh +77 -0
- package/images/postgres/Dockerfile +32 -0
- package/images/seal/Dockerfile +68 -0
- package/images/seal/entrypoint.sh +65 -0
- package/images/sui/Dockerfile +73 -0
- package/images/sui/entrypoint.sh +244 -0
- package/images/sui-fork/Dockerfile +53 -0
- package/images/sui-fork/entrypoint.sh +51 -0
- package/images/walrus/Dockerfile +122 -0
- package/images/walrus/deploy-walrus.sh +305 -0
- package/images/walrus/run-walrus.sh +53 -0
- package/package.json +94 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"labels.mjs","names":[],"sources":["../../../src/runtime/docker/labels.ts"],"sourcesContent":["// Docker label contract.\n//\n// Architecture § Container runtime § Label-driven inventory:\n// Containers, images, networks, and volumes are enumerated by the\n// four canonical engine-level dimensions and a small set of\n// well-known role labels. Inventory NEVER greps stdout for names.\n//\n// The four canonical engine dimensions (no service names anywhere):\n//\n// - `devstack.app` — the app/project this resource belongs to\n// - `devstack.stack` — the stack name within that app\n// - `devstack.plugin` — the plugin key (opaque to the runtime)\n// - `devstack.role` — the resource's role within the plugin (also opaque)\n//\n// Plus two protocol-level labels for the lifecycle machinery:\n//\n// - `devstack.cycle` — the engine cycle id that last touched it\n// (sweep filters by this to find orphans)\n// - `devstack.managed` — set to `'true'` on every resource we own;\n// a coarse \"is this ours at all?\" filter\n//\n// Network / image / volume specializations carry only the canonical\n// engine dimensions plus a kind-specific marker.\n\nimport type { ContainerLabelTuple } from '../../contracts/snapshotable.ts';\n\n/** Canonical label keys. Single source of truth. */\nexport const LabelKey = {\n\tapp: 'devstack.app',\n\tstack: 'devstack.stack',\n\tplugin: 'devstack.plugin',\n\trole: 'devstack.role',\n\tcycle: 'devstack.cycle',\n\tconfigHash: 'devstack.config-hash',\n\tmanaged: 'devstack.managed',\n\t// Resource-kind markers — coarse \"what is this?\" classification\n\t// for inventory walks.\n\tnetworkMarker: 'devstack.network',\n\tvolumeMarker: 'devstack.volume',\n\t// Reverse-proxy / routable. Router itself is built outside this\n\t// package, but if it stamps a label, this is the key it uses.\n\trouterMarker: 'devstack.router',\n\trouterProfile: 'devstack.router.profile',\n\trouterSpecVersion: 'devstack.router.spec-version',\n} as const;\n\nexport type LabelKey = (typeof LabelKey)[keyof typeof LabelKey];\n\n/** Docker Compose-compatible labels used only for Docker Desktop grouping.\n * Cleanup and inventory remain keyed by `LabelKey` above. */\nexport const ComposeLabelKey = {\n\tproject: 'com.docker.compose.project',\n\tservice: 'com.docker.compose.service',\n\tcontainerNumber: 'com.docker.compose.container-number',\n\tversion: 'com.docker.compose.version',\n\toneoff: 'com.docker.compose.oneoff',\n\tnetwork: 'com.docker.compose.network',\n\tvolume: 'com.docker.compose.volume',\n} as const;\n\nexport type ComposeLabelKey = (typeof ComposeLabelKey)[keyof typeof ComposeLabelKey];\n\nexport const COMPOSE_UI_VERSION = '2.0.0';\n\nexport type ExpectedOwnershipLabels = Readonly<Record<string, string>>;\n\nconst normalizeComposeSegment = (value: string): string => {\n\tconst normalized = value\n\t\t.trim()\n\t\t.replace(/[^a-zA-Z0-9_-]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '');\n\treturn normalized.length > 0 ? normalized : 'unnamed';\n};\n\nexport const composeProjectId = (app: string, stack: string): string =>\n\t`${normalizeComposeSegment(app)}-${normalizeComposeSegment(stack)}`;\n\nexport const composeServiceId = (tuple: ContainerLabelTuple): string =>\n\t`${normalizeComposeSegment(tuple.plugin)}.${normalizeComposeSegment(tuple.role)}`;\n\nexport const renderComposeContainerLabels = (tuple: ContainerLabelTuple): ReadonlyArray<string> => [\n\t`${ComposeLabelKey.project}=${composeProjectId(tuple.app, tuple.stack)}`,\n\t`${ComposeLabelKey.service}=${composeServiceId(tuple)}`,\n\t`${ComposeLabelKey.containerNumber}=1`,\n\t`${ComposeLabelKey.version}=${COMPOSE_UI_VERSION}`,\n\t`${ComposeLabelKey.oneoff}=False`,\n];\n\nexport const renderComposeNetworkLabels = (\n\tname: string,\n\tapp: string,\n\tstack: string,\n): ReadonlyArray<string> => [\n\t`${ComposeLabelKey.project}=${composeProjectId(app, stack)}`,\n\t`${ComposeLabelKey.network}=${name}`,\n\t`${ComposeLabelKey.version}=${COMPOSE_UI_VERSION}`,\n];\n\nexport const renderComposeVolumeLabels = (\n\tname: string,\n\ttuple: ContainerLabelTuple,\n): ReadonlyArray<string> => [\n\t`${ComposeLabelKey.project}=${composeProjectId(tuple.app, tuple.stack)}`,\n\t`${ComposeLabelKey.volume}=${name}`,\n\t`${ComposeLabelKey.version}=${COMPOSE_UI_VERSION}`,\n];\n\nexport const expectedContainerOwnershipLabels = (\n\ttuple: ContainerLabelTuple,\n): ExpectedOwnershipLabels => ({\n\t[LabelKey.managed]: 'true',\n\t[LabelKey.app]: tuple.app,\n\t[LabelKey.stack]: tuple.stack,\n\t[LabelKey.plugin]: tuple.plugin,\n\t[LabelKey.role]: tuple.role,\n});\n\nexport const expectedNetworkOwnershipLabels = (\n\tapp: string,\n\tstack: string,\n): ExpectedOwnershipLabels => ({\n\t[LabelKey.managed]: 'true',\n\t[LabelKey.networkMarker]: 'true',\n\t[LabelKey.app]: app,\n\t[LabelKey.stack]: stack,\n});\n\nexport const expectedVolumeOwnershipLabels = (\n\ttuple: ContainerLabelTuple,\n): ExpectedOwnershipLabels => ({\n\t[LabelKey.managed]: 'true',\n\t[LabelKey.volumeMarker]: 'true',\n\t[LabelKey.app]: tuple.app,\n\t[LabelKey.stack]: tuple.stack,\n\t[LabelKey.plugin]: tuple.plugin,\n\t[LabelKey.role]: tuple.role,\n});\n\nexport const ownershipMismatchDetail = (\n\texpected: ExpectedOwnershipLabels,\n\tactual: Readonly<Record<string, string>>,\n): string | null => {\n\tconst mismatches: Array<string> = [];\n\tfor (const [key, expectedValue] of Object.entries(expected)) {\n\t\tconst actualValue = actual[key];\n\t\tif (actualValue !== expectedValue) {\n\t\t\tmismatches.push(`${key}: expected ${expectedValue}, found ${actualValue ?? '<missing>'}`);\n\t\t}\n\t}\n\treturn mismatches.length === 0 ? null : mismatches.join('; ');\n};\n\n/** Render a `ContainerLabelTuple` to docker `--label key=value` pairs.\n * The cycle/managed labels are stamped at create time by `container.ts`. */\nexport const renderContainerLabels = (\n\ttuple: ContainerLabelTuple,\n\tcycle: number,\n\textra: Readonly<Record<string, string>> = {},\n): ReadonlyArray<string> => {\n\tconst ownership = [\n\t\t...Object.entries(expectedContainerOwnershipLabels(tuple)).map(\n\t\t\t([key, value]) => `${key}=${value}`,\n\t\t),\n\t\t`${LabelKey.cycle}=${cycle}`,\n\t\t...Object.entries(extra).map(([key, value]) => `${key}=${value}`),\n\t];\n\treturn [...ownership, ...renderComposeContainerLabels(tuple)];\n};\n\n/** Render a label-tuple as `--filter label=key=value` args for `docker ps`,\n * `docker volume ls`, etc. Partial tuples allowed (sweep / inventory). */\nexport const renderFilterArgs = (\n\tmatch: Partial<ContainerLabelTuple>,\n\textra: Readonly<Record<string, string>> = {},\n): ReadonlyArray<string> => {\n\tconst filters: Array<string> = [`label=${LabelKey.managed}=true`];\n\tif (match.app !== undefined) filters.push(`label=${LabelKey.app}=${match.app}`);\n\tif (match.stack !== undefined) filters.push(`label=${LabelKey.stack}=${match.stack}`);\n\tif (match.plugin !== undefined) filters.push(`label=${LabelKey.plugin}=${match.plugin}`);\n\tif (match.role !== undefined) filters.push(`label=${LabelKey.role}=${match.role}`);\n\tfor (const [k, v] of Object.entries(extra)) filters.push(`label=${k}=${v}`);\n\treturn filters.flatMap((f) => ['--filter', f]);\n};\n\n/** Network-specific labels (shared `devstack` network is cross-stack;\n * per-stack networks would stamp the full tuple). */\nexport const renderNetworkLabels = (\n\tname: string,\n\tapp: string,\n\tstack: string,\n\topts: { readonly composeUi?: boolean } = {},\n): ReadonlyArray<string> => {\n\tconst ownership = Object.entries(expectedNetworkOwnershipLabels(app, stack)).map(\n\t\t([key, value]) => `${key}=${value}`,\n\t);\n\treturn opts.composeUi === false\n\t\t? ownership\n\t\t: [...ownership, ...renderComposeNetworkLabels(name, app, stack)];\n};\n\n/** Volume labels — pre-create with these before any `run -v` argv to\n * avoid docker's lazy unlabelled-create. */\nexport const renderVolumeLabels = (\n\tname: string,\n\ttuple: ContainerLabelTuple,\n): ReadonlyArray<string> => {\n\tconst ownership = Object.entries(expectedVolumeOwnershipLabels(tuple)).map(\n\t\t([key, value]) => `${key}=${value}`,\n\t);\n\treturn [...ownership, ...renderComposeVolumeLabels(name, tuple)];\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { Effect, Stream } from "effect";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { splitUtf8Lines } from "../../substrate/runtime/observability/process-lines.mjs";
|
|
2
|
+
import { DockerHost, DockerSpawner, dockerCommand } from "./client.mjs";
|
|
3
|
+
import { DaemonUnreachable } from "./errors.mjs";
|
|
4
|
+
import { Effect, Stream } from "effect";
|
|
5
|
+
//#region src/runtime/docker/logs.ts
|
|
6
|
+
/** `docker logs --follow --timestamps <id>` projected to a per-line
|
|
7
|
+
* Stream. Combined stdout+stderr (docker writes both to the same
|
|
8
|
+
* follow stream).
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT: the stream completes when the container exits (docker
|
|
11
|
+
* closes the pipe). Consumers that want to re-follow after a restart
|
|
12
|
+
* must re-call this. */
|
|
13
|
+
const followLogs = (containerNameOrId, opts = {}) => {
|
|
14
|
+
const args = ["--follow", "--timestamps"];
|
|
15
|
+
if (opts.since !== void 0) args.push("--since", opts.since);
|
|
16
|
+
if (opts.tail !== void 0) args.push("--tail", String(opts.tail));
|
|
17
|
+
args.push(containerNameOrId);
|
|
18
|
+
const mapSpawnError = (cause) => new DaemonUnreachable({
|
|
19
|
+
op: "docker.logs",
|
|
20
|
+
detail: "logs follow stream failed",
|
|
21
|
+
cause
|
|
22
|
+
});
|
|
23
|
+
return Stream.unwrap(Effect.gen(function* () {
|
|
24
|
+
const host = yield* DockerHost;
|
|
25
|
+
const spawner = yield* DockerSpawner;
|
|
26
|
+
const cmd = dockerCommand(host, "logs", args);
|
|
27
|
+
const handle = yield* spawner.spawn(cmd).pipe(Effect.mapError(mapSpawnError));
|
|
28
|
+
return splitUtf8Lines(Stream.merge(handle.stdout, handle.stderr)).pipe(Stream.mapError(mapSpawnError));
|
|
29
|
+
}));
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { followLogs };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=logs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.mjs","names":[],"sources":["../../../src/runtime/docker/logs.ts"],"sourcesContent":["// `docker logs --follow` as an Effect Stream.\n//\n// Architecture invariant: per-line `Stream<string, …>` so consumers\n// can filter / promote levels / dedupe followers across hot-restart\n// cycles via the L1 per-line sink.\n//\n// We DON'T solve the process-global follower-dedupe problem here; the\n// supervisor's per-container-key registry is where dedupe lives.\n// This stream is the raw substrate.\n\nimport { Effect, Stream } from 'effect';\n\nimport { splitUtf8Lines } from '../../substrate/runtime/observability/process-lines.ts';\nimport { DockerHost, DockerSpawner } from './client.ts';\nimport { DaemonUnreachable, type DockerRuntimeError } from './errors.ts';\nimport { dockerCommand } from './client.ts';\n\nexport interface FollowLogsOptions {\n\treadonly since?: string;\n\treadonly tail?: number;\n}\n\n/** `docker logs --follow --timestamps <id>` projected to a per-line\n * Stream. Combined stdout+stderr (docker writes both to the same\n * follow stream).\n *\n * IMPORTANT: the stream completes when the container exits (docker\n * closes the pipe). Consumers that want to re-follow after a restart\n * must re-call this. */\nexport const followLogs = (\n\tcontainerNameOrId: string,\n\topts: FollowLogsOptions = {},\n): Stream.Stream<string, DockerRuntimeError, DockerHost | DockerSpawner> => {\n\tconst args: Array<string> = ['--follow', '--timestamps'];\n\tif (opts.since !== undefined) args.push('--since', opts.since);\n\tif (opts.tail !== undefined) args.push('--tail', String(opts.tail));\n\targs.push(containerNameOrId);\n\tconst mapSpawnError = (cause: unknown): DockerRuntimeError =>\n\t\tnew DaemonUnreachable({ op: 'docker.logs', detail: 'logs follow stream failed', cause });\n\treturn Stream.unwrap(\n\t\tEffect.gen(function* () {\n\t\t\tconst host = yield* DockerHost;\n\t\t\tconst spawner = yield* DockerSpawner;\n\t\t\tconst cmd = dockerCommand(host, 'logs', args);\n\t\t\tconst handle = yield* spawner.spawn(cmd).pipe(Effect.mapError(mapSpawnError));\n\t\t\t// Merge stdout + stderr so caller sees the unified follow stream;\n\t\t\t// docker prefixes each line with its source via --timestamps.\n\t\t\tconst lineStream = splitUtf8Lines(Stream.merge(handle.stdout, handle.stderr)).pipe(\n\t\t\t\tStream.mapError(mapSpawnError),\n\t\t\t);\n\t\t\treturn lineStream;\n\t\t}),\n\t);\n};\n\n/** Best-effort log tail for error enrichment. Returns the last\n * `tail` lines as a single string; on any failure returns empty. */\nexport const logTail = (\n\tcontainerNameOrId: string,\n\ttail: number = 50,\n): Effect.Effect<string, never, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst host = yield* DockerHost;\n\t\tconst spawner = yield* DockerSpawner;\n\t\tconst cmd = dockerCommand(host, 'logs', ['--tail', String(tail), containerNameOrId]);\n\t\tconst res = yield* Effect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst handle = yield* spawner.spawn(cmd);\n\t\t\t\tconst [out, err] = yield* Effect.all(\n\t\t\t\t\t[\n\t\t\t\t\t\tStream.mkString(Stream.decodeText(handle.stdout)),\n\t\t\t\t\t\tStream.mkString(Stream.decodeText(handle.stderr)),\n\t\t\t\t\t],\n\t\t\t\t\t{ concurrency: 'unbounded' },\n\t\t\t\t);\n\t\t\t\treturn `${out}\\n${err}`.trim();\n\t\t\t}),\n\t\t).pipe(Effect.catch(() => Effect.succeed('')));\n\t\treturn res;\n\t}).pipe(Effect.withSpan('runtime.docker.logs.tail'));\n"],"mappings":";;;;;;;;;;;;AA6BA,MAAa,cACZ,mBACA,OAA0B,EAAE,KAC+C;CAC3E,MAAM,OAAsB,CAAC,YAAY,eAAe;AACxD,KAAI,KAAK,UAAU,KAAA,EAAW,MAAK,KAAK,WAAW,KAAK,MAAM;AAC9D,KAAI,KAAK,SAAS,KAAA,EAAW,MAAK,KAAK,UAAU,OAAO,KAAK,KAAK,CAAC;AACnE,MAAK,KAAK,kBAAkB;CAC5B,MAAM,iBAAiB,UACtB,IAAI,kBAAkB;EAAE,IAAI;EAAe,QAAQ;EAA6B;EAAO,CAAC;AACzF,QAAO,OAAO,OACb,OAAO,IAAI,aAAa;EACvB,MAAM,OAAO,OAAO;EACpB,MAAM,UAAU,OAAO;EACvB,MAAM,MAAM,cAAc,MAAM,QAAQ,KAAK;EAC7C,MAAM,SAAS,OAAO,QAAQ,MAAM,IAAI,CAAC,KAAK,OAAO,SAAS,cAAc,CAAC;AAM7E,SAHmB,eAAe,OAAO,MAAM,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC,KAC7E,OAAO,SAAS,cAAc,CAEd;GAChB,CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { decodeJsonArrayElementSync } from "../../substrate/runtime/runtime-decode.mjs";
|
|
2
|
+
import { dockerRun, dockerRunOk } from "./client.mjs";
|
|
3
|
+
import { DaemonUnreachable, DockerInspectDecodeFailed, DockerInspectFailed, ForeignDockerResource, NetworkIpReadbackTimeout, NetworkOperationFailed } from "./errors.mjs";
|
|
4
|
+
import { expectedNetworkOwnershipLabels, ownershipMismatchDetail, renderNetworkLabels } from "./labels.mjs";
|
|
5
|
+
import { ProbeTimeoutError, waitForProbe } from "../../substrate/runtime/probes.mjs";
|
|
6
|
+
import { isAlreadyInNetworkStderr, isDaemonUnreachableStderr, wrapNetworkError } from "./wrap.mjs";
|
|
7
|
+
import { Effect, Schema } from "effect";
|
|
8
|
+
//#region src/runtime/docker/network.ts
|
|
9
|
+
const readLabels = (raw) => {
|
|
10
|
+
if (raw === null || typeof raw !== "object") return {};
|
|
11
|
+
const out = {};
|
|
12
|
+
for (const [key, value] of Object.entries(raw)) if (typeof value === "string") out[key] = value;
|
|
13
|
+
return out;
|
|
14
|
+
};
|
|
15
|
+
const NetworkInspectSchema = Schema.Struct({
|
|
16
|
+
Id: Schema.String,
|
|
17
|
+
Labels: Schema.optional(Schema.Unknown)
|
|
18
|
+
});
|
|
19
|
+
const isNoSuchNetworkStderr = (stderr) => /no such network|network .* not found|not found/i.test(stderr);
|
|
20
|
+
const inspectNetwork = (name) => Effect.gen(function* () {
|
|
21
|
+
const res = yield* dockerRunOk("network", ["inspect", name]).pipe(Effect.mapError(wrapNetworkError("inspect", name)));
|
|
22
|
+
if (res.exitCode !== 0) {
|
|
23
|
+
if (isNoSuchNetworkStderr(res.stderr)) return null;
|
|
24
|
+
if (isDaemonUnreachableStderr(res.stderr)) return yield* Effect.fail(new DaemonUnreachable({
|
|
25
|
+
op: "docker.network.inspect",
|
|
26
|
+
detail: "docker daemon unreachable"
|
|
27
|
+
}));
|
|
28
|
+
return yield* Effect.fail(new DockerInspectFailed({
|
|
29
|
+
resource: "network",
|
|
30
|
+
name,
|
|
31
|
+
stderr: res.stderr,
|
|
32
|
+
exitCode: res.exitCode
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const decoded = decodeJsonArrayElementSync(NetworkInspectSchema, res.stdout, {
|
|
37
|
+
source: `docker network inspect ${name}`,
|
|
38
|
+
missingMessage: "inspect returned an empty result",
|
|
39
|
+
mkError: (issue) => new DockerInspectDecodeFailed({
|
|
40
|
+
resource: "network",
|
|
41
|
+
name,
|
|
42
|
+
detail: issue.message === "inspect returned an empty result" ? issue.message : "inspect returned malformed network JSON",
|
|
43
|
+
cause: issue.cause
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
id: decoded.Id,
|
|
48
|
+
labels: readLabels(decoded.Labels)
|
|
49
|
+
};
|
|
50
|
+
} catch (cause) {
|
|
51
|
+
return yield* Effect.fail(cause);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
const assertNetworkOwned = (name, facts, opts) => Effect.gen(function* () {
|
|
55
|
+
const expected = expectedNetworkOwnershipLabels(opts.app, opts.stack);
|
|
56
|
+
const mismatch = ownershipMismatchDetail(expected, facts.labels);
|
|
57
|
+
if (mismatch !== null) return yield* Effect.fail(new ForeignDockerResource({
|
|
58
|
+
resource: "network",
|
|
59
|
+
name,
|
|
60
|
+
expected,
|
|
61
|
+
actual: facts.labels,
|
|
62
|
+
detail: mismatch
|
|
63
|
+
}));
|
|
64
|
+
});
|
|
65
|
+
/** Idempotent `docker network create`. Returns the network's id (or
|
|
66
|
+
* the pre-existing id). Architecture: NO scope finalizer — networks
|
|
67
|
+
* outlive the supervisor. */
|
|
68
|
+
const ensureNetwork = (name, opts) => Effect.gen(function* () {
|
|
69
|
+
const probe = yield* inspectNetwork(name);
|
|
70
|
+
if (probe !== null) {
|
|
71
|
+
yield* assertNetworkOwned(name, probe, opts);
|
|
72
|
+
return probe.id;
|
|
73
|
+
}
|
|
74
|
+
const labelArgs = renderNetworkLabels(name, opts.app, opts.stack, { composeUi: opts.composeUi }).flatMap((l) => ["--label", l]);
|
|
75
|
+
const driverArgs = opts.driver ? ["--driver", opts.driver] : [];
|
|
76
|
+
const subnetArgs = opts.subnet ? ["--subnet", opts.subnet] : [];
|
|
77
|
+
const gatewayArgs = opts.gateway ? ["--gateway", opts.gateway] : [];
|
|
78
|
+
return (yield* dockerRun("network", [
|
|
79
|
+
"create",
|
|
80
|
+
...driverArgs,
|
|
81
|
+
...subnetArgs,
|
|
82
|
+
...gatewayArgs,
|
|
83
|
+
...labelArgs,
|
|
84
|
+
name
|
|
85
|
+
]).pipe(Effect.mapError(wrapNetworkError("create", name)))).stdout.trim();
|
|
86
|
+
}).pipe(Effect.withSpan("runtime.docker.network.ensure"));
|
|
87
|
+
/** Idempotent `docker network connect`. Treats "already exists in
|
|
88
|
+
* network" stderr as success — architecture mandates idempotency on
|
|
89
|
+
* this verb. */
|
|
90
|
+
const connect = (containerNameOrId, network, alias) => Effect.gen(function* () {
|
|
91
|
+
const res = yield* dockerRunOk("network", [
|
|
92
|
+
"connect",
|
|
93
|
+
...alias ? ["--alias", alias] : [],
|
|
94
|
+
network,
|
|
95
|
+
containerNameOrId
|
|
96
|
+
]).pipe(Effect.mapError(wrapNetworkError("connect", network)));
|
|
97
|
+
if (res.exitCode === 0) return;
|
|
98
|
+
if (isAlreadyInNetworkStderr(res.stderr)) return;
|
|
99
|
+
return yield* Effect.fail(new NetworkOperationFailed({
|
|
100
|
+
op: "connect",
|
|
101
|
+
network,
|
|
102
|
+
stderr: res.stderr
|
|
103
|
+
}));
|
|
104
|
+
}).pipe(Effect.withSpan("runtime.docker.network.connect"));
|
|
105
|
+
/** Schema of the small JSON slice of `docker inspect` we read for the
|
|
106
|
+
* network-membership / IP shape. */
|
|
107
|
+
const InspectNetworkSettings = Schema.Struct({ NetworkSettings: Schema.Struct({ Networks: Schema.Record(Schema.String, Schema.Struct({
|
|
108
|
+
IPAddress: Schema.optional(Schema.String),
|
|
109
|
+
NetworkID: Schema.optional(Schema.String)
|
|
110
|
+
})) }) });
|
|
111
|
+
const DEFAULT_IP_POLL_BUDGET_MILLIS = 3e3;
|
|
112
|
+
const DEFAULT_IP_POLL_INTERVAL_MILLIS = 100;
|
|
113
|
+
/** Poll `docker inspect` until the container has a non-empty IP on
|
|
114
|
+
* `network`. Architecture §5 — async network-connect settle. */
|
|
115
|
+
const waitForIp = (containerNameOrId, network, opts = {}) => {
|
|
116
|
+
const budget = opts.budgetMillis ?? DEFAULT_IP_POLL_BUDGET_MILLIS;
|
|
117
|
+
const interval = opts.intervalMillis ?? DEFAULT_IP_POLL_INTERVAL_MILLIS;
|
|
118
|
+
const start = Date.now();
|
|
119
|
+
let foundIp;
|
|
120
|
+
return waitForProbe({
|
|
121
|
+
label: `docker.network.ip:${containerNameOrId}:${network}`,
|
|
122
|
+
timeoutMs: budget,
|
|
123
|
+
intervalMs: interval,
|
|
124
|
+
isRetryableError: () => false,
|
|
125
|
+
probe: () => Effect.gen(function* () {
|
|
126
|
+
const res = yield* dockerRunOk("inspect", [containerNameOrId]).pipe(Effect.mapError(wrapNetworkError("inspect", network)));
|
|
127
|
+
if (res.exitCode === 0) try {
|
|
128
|
+
const ip = decodeJsonArrayElementSync(InspectNetworkSettings, res.stdout, {
|
|
129
|
+
source: `docker inspect ${containerNameOrId}`,
|
|
130
|
+
mkError: (issue) => issue
|
|
131
|
+
}).NetworkSettings.Networks[network]?.IPAddress;
|
|
132
|
+
if (ip && ip.length > 0) {
|
|
133
|
+
foundIp = ip;
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
} catch {}
|
|
137
|
+
return false;
|
|
138
|
+
})
|
|
139
|
+
}).pipe(Effect.map(() => foundIp ?? ""), Effect.mapError((cause) => {
|
|
140
|
+
if (cause instanceof ProbeTimeoutError) return new NetworkIpReadbackTimeout({
|
|
141
|
+
container: containerNameOrId,
|
|
142
|
+
network,
|
|
143
|
+
waitedMillis: Date.now() - start
|
|
144
|
+
});
|
|
145
|
+
return cause;
|
|
146
|
+
}), Effect.withSpan("runtime.docker.network.waitForIp"));
|
|
147
|
+
};
|
|
148
|
+
/** Read out ALL networks + IPs for a container. Used by the contract's
|
|
149
|
+
* `ContainerHandle.ips`. */
|
|
150
|
+
const readIps = (containerNameOrId) => Effect.gen(function* () {
|
|
151
|
+
const res = yield* dockerRunOk("inspect", [containerNameOrId]).pipe(Effect.mapError(wrapNetworkError("inspect", containerNameOrId)));
|
|
152
|
+
if (res.exitCode !== 0) return [];
|
|
153
|
+
try {
|
|
154
|
+
const decoded = decodeJsonArrayElementSync(InspectNetworkSettings, res.stdout, {
|
|
155
|
+
source: `docker inspect ${containerNameOrId}`,
|
|
156
|
+
mkError: (issue) => issue
|
|
157
|
+
});
|
|
158
|
+
const ips = [];
|
|
159
|
+
for (const slot of Object.values(decoded.NetworkSettings.Networks)) if (slot.IPAddress && slot.IPAddress.length > 0) ips.push(slot.IPAddress);
|
|
160
|
+
return ips;
|
|
161
|
+
} catch {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
}).pipe(Effect.withSpan("runtime.docker.network.readIps"));
|
|
165
|
+
//#endregion
|
|
166
|
+
export { connect, ensureNetwork, readIps, waitForIp };
|
|
167
|
+
|
|
168
|
+
//# sourceMappingURL=network.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.mjs","names":[],"sources":["../../../src/runtime/docker/network.ts"],"sourcesContent":["// Docker network lifecycle.\n//\n// Architecture § Docker backend § Networking:\n// - ONE shared `devstack` network per host (cross-stack). Other\n// per-stack secondary networks are allowed by callers, but the\n// default surface assumes the shared bridge.\n// - `network connect` is idempotent — \"already exists in network\"\n// stderr is success (see `wrap.ts` classifier).\n// - `network connect` settle is ASYNCHRONOUS in docker — the\n// endpoint is registered before the IP is allocated. Callers must\n// wait for IP readback (see §5 and `waitForIp`).\n// - `network create` registers NO finalizer; the network outlives\n// individual stacks so resume into a stopped container reattaches\n// to the same bridge id. Cleanup is via `wipe` / `prune`.\n//\n// Surface:\n// - `ensureNetwork(name, opts)` — idempotent create\n// - `connect(container, network, alias?)` — idempotent attach\n// - `disconnect(container, network)` — idempotent detach\n// - `waitForIp(container, network, opts)` — bounded poll for IP\n\nimport { Effect, Schema } from 'effect';\n\nimport { DockerHost, DockerSpawner, dockerRun, dockerRunOk } from './client.ts';\nimport { ProbeTimeoutError, waitForProbe } from '../../substrate/runtime/probes.ts';\nimport { decodeJsonArrayElementSync } from '../../substrate/runtime/runtime-decode.ts';\nimport {\n\tDockerInspectDecodeFailed,\n\tDockerInspectFailed,\n\tDaemonUnreachable,\n\ttype DockerRuntimeError,\n\tForeignDockerResource,\n\tNetworkIpReadbackTimeout,\n\tNetworkOperationFailed,\n} from './errors.ts';\nimport {\n\texpectedNetworkOwnershipLabels,\n\townershipMismatchDetail,\n\trenderNetworkLabels,\n} from './labels.ts';\nimport { isAlreadyInNetworkStderr, isDaemonUnreachableStderr, wrapNetworkError } from './wrap.ts';\n\n/** The cross-host shared network name. Architecture-mandated single\n * bridge per host. Callers can target other networks (per-stack) but\n * this is the constant for the shared one. */\nexport const SHARED_NETWORK_NAME = 'devstack';\n\nexport interface EnsureNetworkOptions {\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly subnet?: string;\n\treadonly gateway?: string;\n\treadonly driver?: 'bridge' | 'host' | 'overlay';\n\treadonly composeUi?: boolean;\n}\n\ninterface NetworkInspectFacts {\n\treadonly id: string;\n\treadonly labels: Readonly<Record<string, string>>;\n}\n\nconst readLabels = (raw: unknown): Readonly<Record<string, string>> => {\n\tif (raw === null || typeof raw !== 'object') return {};\n\tconst out: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(raw)) {\n\t\tif (typeof value === 'string') out[key] = value;\n\t}\n\treturn out;\n};\n\nconst NetworkInspectSchema = Schema.Struct({\n\tId: Schema.String,\n\tLabels: Schema.optional(Schema.Unknown),\n});\n\nconst isNoSuchNetworkStderr = (stderr: string): boolean =>\n\t/no such network|network .* not found|not found/i.test(stderr);\n\nconst inspectNetwork = (\n\tname: string,\n): Effect.Effect<NetworkInspectFacts | null, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('network', ['inspect', name]).pipe(\n\t\t\tEffect.mapError(wrapNetworkError('inspect', name)),\n\t\t);\n\t\tif (res.exitCode !== 0) {\n\t\t\tif (isNoSuchNetworkStderr(res.stderr)) return null;\n\t\t\tif (isDaemonUnreachableStderr(res.stderr)) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\tnew DaemonUnreachable({\n\t\t\t\t\t\top: 'docker.network.inspect',\n\t\t\t\t\t\tdetail: 'docker daemon unreachable',\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew DockerInspectFailed({\n\t\t\t\t\tresource: 'network',\n\t\t\t\t\tname,\n\t\t\t\t\tstderr: res.stderr,\n\t\t\t\t\texitCode: res.exitCode,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tconst decoded = decodeJsonArrayElementSync(NetworkInspectSchema, res.stdout, {\n\t\t\t\tsource: `docker network inspect ${name}`,\n\t\t\t\tmissingMessage: 'inspect returned an empty result',\n\t\t\t\tmkError: (issue) =>\n\t\t\t\t\tnew DockerInspectDecodeFailed({\n\t\t\t\t\t\tresource: 'network',\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tdetail:\n\t\t\t\t\t\t\tissue.message === 'inspect returned an empty result'\n\t\t\t\t\t\t\t\t? issue.message\n\t\t\t\t\t\t\t\t: 'inspect returned malformed network JSON',\n\t\t\t\t\t\tcause: issue.cause,\n\t\t\t\t\t}),\n\t\t\t});\n\t\t\treturn { id: decoded.Id, labels: readLabels(decoded.Labels) };\n\t\t} catch (cause) {\n\t\t\treturn yield* Effect.fail(cause as DockerRuntimeError);\n\t\t}\n\t});\n\nconst assertNetworkOwned = (\n\tname: string,\n\tfacts: NetworkInspectFacts,\n\topts: EnsureNetworkOptions,\n): Effect.Effect<void, DockerRuntimeError> =>\n\tEffect.gen(function* () {\n\t\tconst expected = expectedNetworkOwnershipLabels(opts.app, opts.stack);\n\t\tconst mismatch = ownershipMismatchDetail(expected, facts.labels);\n\t\tif (mismatch !== null) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew ForeignDockerResource({\n\t\t\t\t\tresource: 'network',\n\t\t\t\t\tname,\n\t\t\t\t\texpected,\n\t\t\t\t\tactual: facts.labels,\n\t\t\t\t\tdetail: mismatch,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t});\n\n// -----------------------------------------------------------------------------\n// Create / inspect\n// -----------------------------------------------------------------------------\n\n/** Idempotent `docker network create`. Returns the network's id (or\n * the pre-existing id). Architecture: NO scope finalizer — networks\n * outlive the supervisor. */\nexport const ensureNetwork = (\n\tname: string,\n\topts: EnsureNetworkOptions,\n): Effect.Effect<string, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst probe = yield* inspectNetwork(name);\n\t\tif (probe !== null) {\n\t\t\tyield* assertNetworkOwned(name, probe, opts);\n\t\t\treturn probe.id;\n\t\t}\n\t\t// Create with full label stamp.\n\t\tconst labelArgs = renderNetworkLabels(name, opts.app, opts.stack, {\n\t\t\tcomposeUi: opts.composeUi,\n\t\t}).flatMap((l) => ['--label', l]);\n\t\tconst driverArgs = opts.driver ? ['--driver', opts.driver] : [];\n\t\tconst subnetArgs = opts.subnet ? ['--subnet', opts.subnet] : [];\n\t\tconst gatewayArgs = opts.gateway ? ['--gateway', opts.gateway] : [];\n\t\tconst created = yield* dockerRun('network', [\n\t\t\t'create',\n\t\t\t...driverArgs,\n\t\t\t...subnetArgs,\n\t\t\t...gatewayArgs,\n\t\t\t...labelArgs,\n\t\t\tname,\n\t\t]).pipe(Effect.mapError(wrapNetworkError('create', name)));\n\t\treturn created.stdout.trim();\n\t}).pipe(Effect.withSpan('runtime.docker.network.ensure'));\n\n// -----------------------------------------------------------------------------\n// Connect / disconnect\n// -----------------------------------------------------------------------------\n\n/** Idempotent `docker network connect`. Treats \"already exists in\n * network\" stderr as success — architecture mandates idempotency on\n * this verb. */\nexport const connect = (\n\tcontainerNameOrId: string,\n\tnetwork: string,\n\talias?: string,\n): Effect.Effect<void, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst aliasArgs = alias ? ['--alias', alias] : [];\n\t\tconst res = yield* dockerRunOk('network', [\n\t\t\t'connect',\n\t\t\t...aliasArgs,\n\t\t\tnetwork,\n\t\t\tcontainerNameOrId,\n\t\t]).pipe(Effect.mapError(wrapNetworkError('connect', network)));\n\t\tif (res.exitCode === 0) return;\n\t\tif (isAlreadyInNetworkStderr(res.stderr)) return;\n\t\t// Non-idempotent failure path.\n\t\treturn yield* Effect.fail(\n\t\t\tnew NetworkOperationFailed({ op: 'connect', network, stderr: res.stderr }),\n\t\t);\n\t}).pipe(Effect.withSpan('runtime.docker.network.connect'));\n\nexport const disconnect = (\n\tcontainerNameOrId: string,\n\tnetwork: string,\n): Effect.Effect<void, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('network', ['disconnect', network, containerNameOrId]).pipe(\n\t\t\tEffect.mapError(wrapNetworkError('disconnect', network)),\n\t\t);\n\t\t// \"is not connected\" is also idempotent success on the\n\t\t// disconnect side; we treat any non-fatal stderr as success here\n\t\t// since the postcondition (not connected) holds.\n\t\tif (res.exitCode !== 0 && !/is not connected/i.test(res.stderr)) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew NetworkOperationFailed({ op: 'disconnect', network, stderr: res.stderr }),\n\t\t\t);\n\t\t}\n\t}).pipe(Effect.withSpan('runtime.docker.network.disconnect'));\n\n// -----------------------------------------------------------------------------\n// IP readback\n// -----------------------------------------------------------------------------\n\n/** Schema of the small JSON slice of `docker inspect` we read for the\n * network-membership / IP shape. */\nconst InspectNetworkSettings = Schema.Struct({\n\tNetworkSettings: Schema.Struct({\n\t\tNetworks: Schema.Record(\n\t\t\tSchema.String,\n\t\t\tSchema.Struct({\n\t\t\t\tIPAddress: Schema.optional(Schema.String),\n\t\t\t\tNetworkID: Schema.optional(Schema.String),\n\t\t\t}),\n\t\t),\n\t}),\n});\n\nconst DEFAULT_IP_POLL_BUDGET_MILLIS = 3_000;\nconst DEFAULT_IP_POLL_INTERVAL_MILLIS = 100;\n\nexport interface WaitForIpOptions {\n\treadonly budgetMillis?: number;\n\treadonly intervalMillis?: number;\n}\n\n/** Poll `docker inspect` until the container has a non-empty IP on\n * `network`. Architecture §5 — async network-connect settle. */\nexport const waitForIp = (\n\tcontainerNameOrId: string,\n\tnetwork: string,\n\topts: WaitForIpOptions = {},\n): Effect.Effect<string, DockerRuntimeError, DockerHost | DockerSpawner> => {\n\tconst budget = opts.budgetMillis ?? DEFAULT_IP_POLL_BUDGET_MILLIS;\n\tconst interval = opts.intervalMillis ?? DEFAULT_IP_POLL_INTERVAL_MILLIS;\n\tconst start = Date.now();\n\tlet foundIp: string | undefined;\n\treturn waitForProbe({\n\t\tlabel: `docker.network.ip:${containerNameOrId}:${network}`,\n\t\ttimeoutMs: budget,\n\t\tintervalMs: interval,\n\t\tisRetryableError: () => false,\n\t\tprobe: () =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst res = yield* dockerRunOk('inspect', [containerNameOrId]).pipe(\n\t\t\t\t\tEffect.mapError(wrapNetworkError('inspect', network)),\n\t\t\t\t);\n\t\t\t\tif (res.exitCode === 0) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst decoded = decodeJsonArrayElementSync(InspectNetworkSettings, res.stdout, {\n\t\t\t\t\t\t\tsource: `docker inspect ${containerNameOrId}`,\n\t\t\t\t\t\t\tmkError: (issue) => issue,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst slot = decoded.NetworkSettings.Networks[network];\n\t\t\t\t\t\tconst ip = slot?.IPAddress;\n\t\t\t\t\t\tif (ip && ip.length > 0) {\n\t\t\t\t\t\t\tfoundIp = ip;\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Malformed — fall through to retry.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}),\n\t}).pipe(\n\t\tEffect.map(() => foundIp ?? ''),\n\t\tEffect.mapError((cause) => {\n\t\t\tif (cause instanceof ProbeTimeoutError) {\n\t\t\t\treturn new NetworkIpReadbackTimeout({\n\t\t\t\t\tcontainer: containerNameOrId,\n\t\t\t\t\tnetwork,\n\t\t\t\t\twaitedMillis: Date.now() - start,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn cause;\n\t\t}),\n\t\tEffect.withSpan('runtime.docker.network.waitForIp'),\n\t);\n};\n\n/** Read out ALL networks + IPs for a container. Used by the contract's\n * `ContainerHandle.ips`. */\nexport const readIps = (\n\tcontainerNameOrId: string,\n): Effect.Effect<ReadonlyArray<string>, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('inspect', [containerNameOrId]).pipe(\n\t\t\tEffect.mapError(wrapNetworkError('inspect', containerNameOrId)),\n\t\t);\n\t\tif (res.exitCode !== 0) return [];\n\t\ttry {\n\t\t\tconst decoded = decodeJsonArrayElementSync(InspectNetworkSettings, res.stdout, {\n\t\t\t\tsource: `docker inspect ${containerNameOrId}`,\n\t\t\t\tmkError: (issue) => issue,\n\t\t\t});\n\t\t\tconst ips: Array<string> = [];\n\t\t\tfor (const slot of Object.values(decoded.NetworkSettings.Networks)) {\n\t\t\t\tif (slot.IPAddress && slot.IPAddress.length > 0) ips.push(slot.IPAddress);\n\t\t\t}\n\t\t\treturn ips;\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}).pipe(Effect.withSpan('runtime.docker.network.readIps'));\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ContainerRuntime } from "../../contracts/container-runtime.mjs";
|
|
2
|
+
import { Context, Layer, Ref } from "effect";
|
|
3
|
+
|
|
4
|
+
//#region src/runtime/docker/service.d.ts
|
|
5
|
+
declare const ContainerRuntimeService_base: Context.ServiceClass<ContainerRuntimeService, "@devstack-rewrite/runtime-docker/ContainerRuntime", ContainerRuntime>;
|
|
6
|
+
declare class ContainerRuntimeService extends ContainerRuntimeService_base {}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { ContainerRuntimeService };
|
|
9
|
+
//# sourceMappingURL=service.d.mts.map
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { StackPathsService } from "../../substrate/runtime/paths.mjs";
|
|
2
|
+
import { chainId, contentHash } from "../../substrate/brand.mjs";
|
|
3
|
+
import { CacheService } from "../../substrate/runtime/cache/service.mjs";
|
|
4
|
+
import { DockerHost, DockerSpawner, dockerRunOk } from "./client.mjs";
|
|
5
|
+
import { toContractError } from "./errors.mjs";
|
|
6
|
+
import { ensureNetwork } from "./network.mjs";
|
|
7
|
+
import { assertContainerHandleOwned, commit, ensureContainer, inspectContainer, pause, stop, unpause } from "./container.mjs";
|
|
8
|
+
import { dockerExec, dockerRunOneShot } from "./exec.mjs";
|
|
9
|
+
import { ensureImageCached, loadImage, pull, refOf, removeImage, saveImage, saveImages, tagImage } from "./image.mjs";
|
|
10
|
+
import { listContainers } from "./inventory.mjs";
|
|
11
|
+
import { followLogs } from "./logs.mjs";
|
|
12
|
+
import { removeManagedContainers, removeManagedImages, removeManagedNetworks, removeManagedVolumes, sweepOrphans } from "./sweep.mjs";
|
|
13
|
+
import { Context, Duration, Effect, Layer, Ref, Stream } from "effect";
|
|
14
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
15
|
+
import { lstatSync, readFileSync, readdirSync, readlinkSync } from "node:fs";
|
|
16
|
+
import { join, relative, sep } from "node:path";
|
|
17
|
+
//#region src/runtime/docker/service.ts
|
|
18
|
+
var ContainerRuntimeService = class extends Context.Service()("@devstack-rewrite/runtime-docker/ContainerRuntime") {};
|
|
19
|
+
var DockerCycle = class extends Context.Service()("@devstack-rewrite/runtime-docker/Cycle") {};
|
|
20
|
+
const layerDockerCycleInitial = Layer.effect(DockerCycle, Effect.gen(function* () {
|
|
21
|
+
return yield* Ref.make(0);
|
|
22
|
+
}));
|
|
23
|
+
const mapToContractError = (eff) => eff.pipe(Effect.mapError(toContractError));
|
|
24
|
+
const snapshotTempTag = (containerName) => {
|
|
25
|
+
return `devstack-snapshot:${containerName.replace(/[^A-Za-z0-9_.-]/g, "-")}-${randomUUID().replace(/-/g, "").slice(0, 12)}`;
|
|
26
|
+
};
|
|
27
|
+
const stableRelativePath = (root, path) => {
|
|
28
|
+
const rel = relative(root, path);
|
|
29
|
+
return rel.length === 0 ? "." : rel.split(sep).join("/");
|
|
30
|
+
};
|
|
31
|
+
const updateContextEntryHash = (hash, root, path) => {
|
|
32
|
+
const stat = lstatSync(path);
|
|
33
|
+
const rel = stableRelativePath(root, path);
|
|
34
|
+
if (stat.isDirectory()) {
|
|
35
|
+
hash.update("dir\0");
|
|
36
|
+
hash.update(rel);
|
|
37
|
+
hash.update("\0");
|
|
38
|
+
for (const child of readdirSync(path).sort((a, b) => a.localeCompare(b))) updateContextEntryHash(hash, root, join(path, child));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (stat.isFile()) {
|
|
42
|
+
hash.update("file\0");
|
|
43
|
+
hash.update(rel);
|
|
44
|
+
hash.update("\0");
|
|
45
|
+
hash.update(String(stat.mode));
|
|
46
|
+
hash.update("\0");
|
|
47
|
+
hash.update(readFileSync(path));
|
|
48
|
+
hash.update("\0");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (stat.isSymbolicLink()) {
|
|
52
|
+
hash.update("symlink\0");
|
|
53
|
+
hash.update(rel);
|
|
54
|
+
hash.update("\0");
|
|
55
|
+
hash.update(readlinkSync(path));
|
|
56
|
+
hash.update("\0");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
hash.update("other\0");
|
|
60
|
+
hash.update(rel);
|
|
61
|
+
hash.update("\0");
|
|
62
|
+
hash.update(String(stat.mode));
|
|
63
|
+
hash.update("\0");
|
|
64
|
+
};
|
|
65
|
+
const normalizeFingerprintPath = (path) => path.split(/[\\/]+/g).filter((part) => part.length > 0).join("/");
|
|
66
|
+
const normalizeFingerprintPaths = (paths) => [...new Set((paths ?? []).map(normalizeFingerprintPath).filter((path) => path.length > 0))].sort((a, b) => a.localeCompare(b));
|
|
67
|
+
const buildContextFingerprint = (contextPath, fingerprintPaths) => {
|
|
68
|
+
const hash = createHash("sha256");
|
|
69
|
+
const requestedPaths = normalizeFingerprintPaths(fingerprintPaths);
|
|
70
|
+
const paths = requestedPaths.length === 0 ? null : requestedPaths;
|
|
71
|
+
try {
|
|
72
|
+
if (paths === null) updateContextEntryHash(hash, contextPath, contextPath);
|
|
73
|
+
else for (const relPath of paths) {
|
|
74
|
+
hash.update("fingerprint-path\0");
|
|
75
|
+
hash.update(relPath);
|
|
76
|
+
hash.update("\0");
|
|
77
|
+
updateContextEntryHash(hash, contextPath, join(contextPath, relPath));
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
hash.update("unreadable\0");
|
|
81
|
+
hash.update(String(err));
|
|
82
|
+
hash.update("\0");
|
|
83
|
+
}
|
|
84
|
+
return hash.digest("hex");
|
|
85
|
+
};
|
|
86
|
+
/** Stable content hash for the build context. Sorts build args so two
|
|
87
|
+
* equivalent specs whose key insertion order differs produce the same
|
|
88
|
+
* hash. The Docker build context's files are part of the key: changing
|
|
89
|
+
* a vendored entrypoint script must force a new managed image tag. */
|
|
90
|
+
const buildContentHash = (ctx) => {
|
|
91
|
+
const dockerfile = ctx.dockerfile ?? "Dockerfile";
|
|
92
|
+
const argsKey = Object.entries(ctx.buildArgs ?? {}).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}=${v}`).join("\0");
|
|
93
|
+
const platform = ctx.platform ?? "";
|
|
94
|
+
const fingerprintPathsKey = normalizeFingerprintPaths(ctx.fingerprintPaths).join("\0");
|
|
95
|
+
return createHash("sha256").update(ctx.contextPath).update("\0").update(dockerfile).update("\0").update(platform).update("\0").update(argsKey).update("\0").update(fingerprintPathsKey).update("\0").update(buildContextFingerprint(ctx.contextPath, ctx.fingerprintPaths)).digest("hex");
|
|
96
|
+
};
|
|
97
|
+
const DOCKER_ARCH_ALIASES = {
|
|
98
|
+
aarch64: "arm64",
|
|
99
|
+
arm64: "arm64",
|
|
100
|
+
x86_64: "amd64",
|
|
101
|
+
amd64: "amd64"
|
|
102
|
+
};
|
|
103
|
+
const normalizeDockerInfoPlatform = (raw) => {
|
|
104
|
+
const trimmed = raw.trim();
|
|
105
|
+
const slash = trimmed.indexOf("/");
|
|
106
|
+
if (slash <= 0 || slash === trimmed.length - 1) return null;
|
|
107
|
+
const os = trimmed.slice(0, slash);
|
|
108
|
+
const arch = trimmed.slice(slash + 1);
|
|
109
|
+
return `${os}/${DOCKER_ARCH_ALIASES[arch] ?? arch}`;
|
|
110
|
+
};
|
|
111
|
+
const inferDockerBuildPlatform = () => dockerRunOk("info", ["--format", "{{.OSType}}/{{.Architecture}}"]).pipe(Effect.map((result) => result.exitCode === 0 ? normalizeDockerInfoPlatform(result.stdout) : null), Effect.catch(() => Effect.succeed(null)));
|
|
112
|
+
const layerContainerRuntimeDocker = Layer.effect(ContainerRuntimeService, Effect.gen(function* () {
|
|
113
|
+
const cycleRef = yield* DockerCycle;
|
|
114
|
+
const dockerHost = yield* DockerHost;
|
|
115
|
+
const dockerSpawner = yield* DockerSpawner;
|
|
116
|
+
const stackPaths = yield* StackPathsService;
|
|
117
|
+
const cache = yield* CacheService;
|
|
118
|
+
const baseCtx = Context.empty().pipe(Context.add(DockerHost, dockerHost), Context.add(DockerSpawner, dockerSpawner), Context.add(StackPathsService, stackPaths), Context.add(CacheService, cache));
|
|
119
|
+
const perNameLock = yield* Ref.make(/* @__PURE__ */ new Map());
|
|
120
|
+
const ensureImage = (ctx, expected) => Effect.gen(function* () {
|
|
121
|
+
const inferredPlatform = ctx.platform === void 0 ? yield* inferDockerBuildPlatform().pipe(Effect.provide(baseCtx)) : null;
|
|
122
|
+
const effectiveCtx = ctx.platform === void 0 && inferredPlatform !== null ? {
|
|
123
|
+
...ctx,
|
|
124
|
+
platform: inferredPlatform
|
|
125
|
+
} : ctx;
|
|
126
|
+
const hash = buildContentHash(effectiveCtx);
|
|
127
|
+
const tag = expected?.tag ?? `devstack-build:${hash.slice(0, 16)}`;
|
|
128
|
+
return yield* ensureImageCached({
|
|
129
|
+
contextPath: effectiveCtx.contextPath,
|
|
130
|
+
dockerfile: effectiveCtx.dockerfile,
|
|
131
|
+
platform: effectiveCtx.platform,
|
|
132
|
+
buildArgs: effectiveCtx.buildArgs,
|
|
133
|
+
tag
|
|
134
|
+
}, {
|
|
135
|
+
namespace: "runtime-docker-build",
|
|
136
|
+
chain: chainId("n/a"),
|
|
137
|
+
contentHash: contentHash(hash)
|
|
138
|
+
}).pipe(Effect.map((digest) => refOf(digest, tag)), mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.ensureImage"));
|
|
139
|
+
});
|
|
140
|
+
const ensureNetworkContractImpl = (spec) => ensureNetwork(spec.name, {
|
|
141
|
+
app: spec.app,
|
|
142
|
+
stack: spec.stack,
|
|
143
|
+
...spec.subnet === void 0 ? {} : { subnet: spec.subnet },
|
|
144
|
+
...spec.gateway === void 0 ? {} : { gateway: spec.gateway }
|
|
145
|
+
}).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.ensureNetwork"));
|
|
146
|
+
const pullImageContractImpl = (ref) => pull(ref).pipe(Effect.map((digest) => refOf(digest, ref)), mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.pullImage"));
|
|
147
|
+
const ensureContainerImpl = (spec) => Effect.gen(function* () {
|
|
148
|
+
return yield* ensureContainer(spec, {
|
|
149
|
+
cycle: yield* Ref.get(cycleRef),
|
|
150
|
+
perNameLock
|
|
151
|
+
});
|
|
152
|
+
}).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.ensureContainer"));
|
|
153
|
+
const inspectByLabels = (labels) => Effect.gen(function* () {
|
|
154
|
+
const summaries = yield* listContainers(labels);
|
|
155
|
+
return yield* Effect.forEach(summaries, (s) => inspectContainer(s.name).pipe(Effect.map((facts) => ({
|
|
156
|
+
id: facts?.id ?? s.id,
|
|
157
|
+
name: s.name,
|
|
158
|
+
labels,
|
|
159
|
+
imageName: facts?.image ?? s.image,
|
|
160
|
+
status: facts?.paused ? "paused" : facts?.running ?? s.state === "running" ? "running" : s.state === "paused" ? "paused" : s.state === "created" ? "created" : "exited",
|
|
161
|
+
ips: [],
|
|
162
|
+
...facts?.ports !== void 0 ? { ports: facts.ports } : {}
|
|
163
|
+
}))), { concurrency: "unbounded" });
|
|
164
|
+
}).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.inspectByLabels"));
|
|
165
|
+
const followLogsImpl = (handle) => followLogs(handle.name).pipe(Stream.mapError(toContractError), Stream.provideContext(baseCtx));
|
|
166
|
+
const pauseAndCommitImpl = (handle) => Effect.gen(function* () {
|
|
167
|
+
yield* assertContainerHandleOwned(handle);
|
|
168
|
+
if (handle.status === "running") {
|
|
169
|
+
yield* pause(handle.name);
|
|
170
|
+
yield* assertContainerHandleOwned(handle);
|
|
171
|
+
}
|
|
172
|
+
const tag = snapshotTempTag(handle.name);
|
|
173
|
+
return {
|
|
174
|
+
digest: yield* commit(handle.name, tag),
|
|
175
|
+
tag
|
|
176
|
+
};
|
|
177
|
+
}).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.pauseAndCommit"));
|
|
178
|
+
const pauseImpl = (handle) => Effect.gen(function* () {
|
|
179
|
+
yield* assertContainerHandleOwned(handle);
|
|
180
|
+
yield* pause(handle.name);
|
|
181
|
+
}).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.pause"));
|
|
182
|
+
const unpauseImpl = (handle) => Effect.gen(function* () {
|
|
183
|
+
yield* assertContainerHandleOwned(handle);
|
|
184
|
+
yield* unpause(handle.name);
|
|
185
|
+
}).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.unpause"));
|
|
186
|
+
const stopImpl = (handle, grace) => {
|
|
187
|
+
const seconds = Math.max(0, Math.ceil(Duration.toMillis(grace) / 1e3));
|
|
188
|
+
return Effect.gen(function* () {
|
|
189
|
+
yield* assertContainerHandleOwned(handle);
|
|
190
|
+
yield* stop(handle.name, seconds);
|
|
191
|
+
}).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.stop"));
|
|
192
|
+
};
|
|
193
|
+
const sweepOrphansImpl = (labelMatch) => sweepOrphans(labelMatch).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.sweepOrphans"));
|
|
194
|
+
const removeManagedContainersImpl = (labelMatch) => removeManagedContainers(labelMatch).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.removeManagedContainers"));
|
|
195
|
+
const removeManagedImagesImpl = (labelMatch) => removeManagedImages(labelMatch).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.removeManagedImages"));
|
|
196
|
+
const removeManagedNetworksImpl = (labelMatch) => removeManagedNetworks(labelMatch).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.removeManagedNetworks"));
|
|
197
|
+
const removeManagedVolumesImpl = (labelMatch) => removeManagedVolumes(labelMatch).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.removeManagedVolumes"));
|
|
198
|
+
const execImpl = (handle, argv, opts) => Effect.gen(function* () {
|
|
199
|
+
yield* assertContainerHandleOwned(handle);
|
|
200
|
+
return yield* dockerExec(handle.name, argv, {
|
|
201
|
+
user: opts?.user,
|
|
202
|
+
env: opts?.env,
|
|
203
|
+
workdir: opts?.workdir
|
|
204
|
+
});
|
|
205
|
+
}).pipe(Effect.map((r) => ({
|
|
206
|
+
exitCode: r.exitCode,
|
|
207
|
+
stdout: r.stdout,
|
|
208
|
+
stderr: r.stderr
|
|
209
|
+
})), mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.exec"));
|
|
210
|
+
const saveImageImpl = (ref, opts) => {
|
|
211
|
+
return saveImage(ref.tag ?? ref.digest, opts).pipe(Stream.mapError(toContractError), Stream.provideContext(baseCtx));
|
|
212
|
+
};
|
|
213
|
+
const saveImagesImpl = (refs, opts) => {
|
|
214
|
+
return saveImages(refs.map((ref) => ref.tag ?? ref.digest), opts).pipe(Stream.mapError(toContractError), Stream.provideContext(baseCtx));
|
|
215
|
+
};
|
|
216
|
+
const loadImageContractImpl = (tar) => loadImage(tar).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.loadImage"));
|
|
217
|
+
const tagImageContractImpl = (src, newTag, opts) => {
|
|
218
|
+
return tagImage(src.tag ?? src.digest, newTag, opts).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.tagImage"));
|
|
219
|
+
};
|
|
220
|
+
const removeImageContractImpl = (ref) => {
|
|
221
|
+
return removeImage(ref.tag ?? ref.digest).pipe(mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.removeImage"));
|
|
222
|
+
};
|
|
223
|
+
const runOneShotImpl = (spec) => dockerRunOneShot({
|
|
224
|
+
image: spec.image.tag ?? spec.image.digest,
|
|
225
|
+
argv: spec.argv,
|
|
226
|
+
env: spec.env,
|
|
227
|
+
mounts: spec.mounts,
|
|
228
|
+
network: spec.network,
|
|
229
|
+
entrypoint: spec.entrypoint,
|
|
230
|
+
user: spec.user,
|
|
231
|
+
timeoutMillis: spec.timeoutMillis,
|
|
232
|
+
extraHosts: spec.extraHosts
|
|
233
|
+
}).pipe(Effect.map((r) => ({
|
|
234
|
+
exitCode: r.exitCode,
|
|
235
|
+
stdout: r.stdout,
|
|
236
|
+
stderr: r.stderr
|
|
237
|
+
})), mapToContractError, Effect.provide(baseCtx), Effect.withSpan("runtime.docker.contract.runOneShot"));
|
|
238
|
+
return ContainerRuntimeService.of({
|
|
239
|
+
ensureImage,
|
|
240
|
+
pullImage: pullImageContractImpl,
|
|
241
|
+
ensureNetwork: ensureNetworkContractImpl,
|
|
242
|
+
ensureContainer: ensureContainerImpl,
|
|
243
|
+
exec: execImpl,
|
|
244
|
+
runOneShot: runOneShotImpl,
|
|
245
|
+
inspectByLabels,
|
|
246
|
+
followLogs: followLogsImpl,
|
|
247
|
+
pause: pauseImpl,
|
|
248
|
+
pauseAndCommit: pauseAndCommitImpl,
|
|
249
|
+
saveImage: saveImageImpl,
|
|
250
|
+
saveImages: saveImagesImpl,
|
|
251
|
+
loadImage: loadImageContractImpl,
|
|
252
|
+
tagImage: tagImageContractImpl,
|
|
253
|
+
removeImage: removeImageContractImpl,
|
|
254
|
+
unpause: unpauseImpl,
|
|
255
|
+
stop: stopImpl,
|
|
256
|
+
sweepOrphans: sweepOrphansImpl,
|
|
257
|
+
removeManagedContainers: removeManagedContainersImpl,
|
|
258
|
+
removeManagedImages: removeManagedImagesImpl,
|
|
259
|
+
removeManagedNetworks: removeManagedNetworksImpl,
|
|
260
|
+
removeManagedVolumes: removeManagedVolumesImpl
|
|
261
|
+
});
|
|
262
|
+
}));
|
|
263
|
+
//#endregion
|
|
264
|
+
export { ContainerRuntimeService, layerContainerRuntimeDocker, layerDockerCycleInitial };
|
|
265
|
+
|
|
266
|
+
//# sourceMappingURL=service.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["ensureNetworkImpl","pullImageImpl","followLogsStream","stopContainer","saveImageStream","saveImagesStream","loadImageImpl","tagImageImpl","removeImageImpl"],"sources":["../../../src/runtime/docker/service.ts"],"sourcesContent":["// `ContainerRuntime` capability — Docker reference implementation.\n//\n// Composes the subsystems in this directory into the contract surface\n// declared in `contracts/container-runtime.ts`. Plugins consume the\n// `ContainerRuntime` interface through this service; the typed\n// docker-specific error variants are accessible to advanced consumers\n// via the underlying subsystems but the public surface projects to\n// the contract's narrow `ContainerRuntimeError`.\n\nimport { createHash, randomUUID } from 'node:crypto';\nimport { lstatSync, readdirSync, readFileSync, readlinkSync } from 'node:fs';\nimport { join, relative, sep } from 'node:path';\n\nimport { Context, Duration, Effect, Layer, Ref, Stream } from 'effect';\n\nimport type {\n\tContainerBuildContext,\n\tContainerHandle,\n\tContainerRuntime,\n\tContainerRuntimeError,\n\tEnsureContainerSpec,\n\tEnsureNetworkSpec,\n\tExecOptions,\n\tExecResult,\n\tImageRef,\n\tLoadedImageBundle,\n\tOneShotSpec,\n\tSaveImageOptions,\n\tTagImageOptions,\n\tTaggedImageRef,\n} from '../../contracts/container-runtime.ts';\nimport type { ContainerLabelTuple } from '../../contracts/snapshotable.ts';\nimport { chainId, contentHash } from '../../substrate/brand.ts';\nimport { CacheService } from '../../substrate/runtime/cache/index.ts';\nimport { StackPathsService } from '../../substrate/runtime/paths.ts';\nimport { DockerHost, DockerSpawner, dockerRunOk } from './client.ts';\nimport {\n\tassertContainerHandleOwned,\n\tcommit,\n\tensureContainer,\n\tinspectContainer,\n\tpause,\n\ttype PerNameLockState,\n\tstop as stopContainer,\n\tunpause,\n} from './container.ts';\nimport { toContractError } from './errors.ts';\nimport { dockerExec, dockerRunOneShot } from './exec.ts';\nimport {\n\tensureImageCached,\n\tloadImage as loadImageImpl,\n\tpull as pullImageImpl,\n\trefOf,\n\tremoveImage as removeImageImpl,\n\tsaveImage as saveImageStream,\n\tsaveImages as saveImagesStream,\n\ttagImage as tagImageImpl,\n} from './image.ts';\nimport { listContainers } from './inventory.ts';\nimport { followLogs as followLogsStream } from './logs.ts';\nimport { ensureNetwork as ensureNetworkImpl } from './network.ts';\nimport {\n\tremoveManagedContainers,\n\tremoveManagedImages,\n\tremoveManagedNetworks,\n\tremoveManagedVolumes,\n\tsweepOrphans,\n} from './sweep.ts';\n\n// -----------------------------------------------------------------------------\n// Service tag — `Context.Service` per Effect-v4 idioms\n// -----------------------------------------------------------------------------\n\nexport class ContainerRuntimeService extends Context.Service<\n\tContainerRuntimeService,\n\tContainerRuntime\n>()('@devstack-rewrite/runtime-docker/ContainerRuntime') {}\n\n// -----------------------------------------------------------------------------\n// Cycle counter — stamped on container labels at create time\n// -----------------------------------------------------------------------------\n\nexport class DockerCycle extends Context.Service<DockerCycle, Ref.Ref<number>>()(\n\t'@devstack-rewrite/runtime-docker/Cycle',\n) {}\n\nexport const layerDockerCycleInitial: Layer.Layer<DockerCycle> = Layer.effect(\n\tDockerCycle,\n\tEffect.gen(function* () {\n\t\tconst ref = yield* Ref.make(0);\n\t\treturn ref;\n\t}),\n);\n\n// -----------------------------------------------------------------------------\n// Layer — wire the subsystems into the contract interface\n// -----------------------------------------------------------------------------\n\nconst mapToContractError = <R, A>(\n\teff: Effect.Effect<A, import('./errors.ts').DockerRuntimeError, R>,\n): Effect.Effect<A, ContainerRuntimeError, R> => eff.pipe(Effect.mapError(toContractError));\n\nconst snapshotTempTag = (containerName: string): string => {\n\tconst safeName = containerName.replace(/[^A-Za-z0-9_.-]/g, '-');\n\tconst suffix = randomUUID().replace(/-/g, '').slice(0, 12);\n\treturn `devstack-snapshot:${safeName}-${suffix}`;\n};\n\nconst stableRelativePath = (root: string, path: string): string => {\n\tconst rel = relative(root, path);\n\treturn rel.length === 0 ? '.' : rel.split(sep).join('/');\n};\n\nconst updateContextEntryHash = (\n\thash: ReturnType<typeof createHash>,\n\troot: string,\n\tpath: string,\n): void => {\n\tconst stat = lstatSync(path);\n\tconst rel = stableRelativePath(root, path);\n\n\tif (stat.isDirectory()) {\n\t\thash.update('dir\\0');\n\t\thash.update(rel);\n\t\thash.update('\\0');\n\t\tfor (const child of readdirSync(path).sort((a, b) => a.localeCompare(b))) {\n\t\t\tupdateContextEntryHash(hash, root, join(path, child));\n\t\t}\n\t\treturn;\n\t}\n\n\tif (stat.isFile()) {\n\t\thash.update('file\\0');\n\t\thash.update(rel);\n\t\thash.update('\\0');\n\t\thash.update(String(stat.mode));\n\t\thash.update('\\0');\n\t\thash.update(readFileSync(path));\n\t\thash.update('\\0');\n\t\treturn;\n\t}\n\n\tif (stat.isSymbolicLink()) {\n\t\thash.update('symlink\\0');\n\t\thash.update(rel);\n\t\thash.update('\\0');\n\t\thash.update(readlinkSync(path));\n\t\thash.update('\\0');\n\t\treturn;\n\t}\n\n\thash.update('other\\0');\n\thash.update(rel);\n\thash.update('\\0');\n\thash.update(String(stat.mode));\n\thash.update('\\0');\n};\n\nconst normalizeFingerprintPath = (path: string): string =>\n\tpath\n\t\t.split(/[\\\\/]+/g)\n\t\t.filter((part) => part.length > 0)\n\t\t.join('/');\n\nconst normalizeFingerprintPaths = (\n\tpaths: ReadonlyArray<string> | undefined,\n): ReadonlyArray<string> =>\n\t[...new Set((paths ?? []).map(normalizeFingerprintPath).filter((path) => path.length > 0))].sort(\n\t\t(a, b) => a.localeCompare(b),\n\t);\n\nconst buildContextFingerprint = (\n\tcontextPath: string,\n\tfingerprintPaths?: ReadonlyArray<string>,\n): string => {\n\tconst hash = createHash('sha256');\n\tconst requestedPaths = normalizeFingerprintPaths(fingerprintPaths);\n\tconst paths = requestedPaths.length === 0 ? null : requestedPaths;\n\ttry {\n\t\tif (paths === null) {\n\t\t\tupdateContextEntryHash(hash, contextPath, contextPath);\n\t\t} else {\n\t\t\tfor (const relPath of paths) {\n\t\t\t\thash.update('fingerprint-path\\0');\n\t\t\t\thash.update(relPath);\n\t\t\t\thash.update('\\0');\n\t\t\t\tupdateContextEntryHash(hash, contextPath, join(contextPath, relPath));\n\t\t\t}\n\t\t}\n\t} catch (err) {\n\t\thash.update('unreadable\\0');\n\t\thash.update(String(err));\n\t\thash.update('\\0');\n\t}\n\treturn hash.digest('hex');\n};\n\n/** Stable content hash for the build context. Sorts build args so two\n * equivalent specs whose key insertion order differs produce the same\n * hash. The Docker build context's files are part of the key: changing\n * a vendored entrypoint script must force a new managed image tag. */\nexport const buildContentHash = (ctx: ContainerBuildContext): string => {\n\tconst dockerfile = ctx.dockerfile ?? 'Dockerfile';\n\tconst sortedArgs = Object.entries(ctx.buildArgs ?? {}).sort(([a], [b]) => a.localeCompare(b));\n\tconst argsKey = sortedArgs.map(([k, v]) => `${k}=${v}`).join('\\x00');\n\tconst platform = ctx.platform ?? '';\n\tconst fingerprintPathsKey = normalizeFingerprintPaths(ctx.fingerprintPaths).join('\\x00');\n\treturn createHash('sha256')\n\t\t.update(ctx.contextPath)\n\t\t.update('\\x00')\n\t\t.update(dockerfile)\n\t\t.update('\\x00')\n\t\t.update(platform)\n\t\t.update('\\x00')\n\t\t.update(argsKey)\n\t\t.update('\\x00')\n\t\t.update(fingerprintPathsKey)\n\t\t.update('\\x00')\n\t\t.update(buildContextFingerprint(ctx.contextPath, ctx.fingerprintPaths))\n\t\t.digest('hex');\n};\n\nconst DOCKER_ARCH_ALIASES: Readonly<Record<string, string>> = {\n\taarch64: 'arm64',\n\tarm64: 'arm64',\n\tx86_64: 'amd64',\n\tamd64: 'amd64',\n};\n\nexport const normalizeDockerInfoPlatform = (raw: string): string | null => {\n\tconst trimmed = raw.trim();\n\tconst slash = trimmed.indexOf('/');\n\tif (slash <= 0 || slash === trimmed.length - 1) return null;\n\tconst os = trimmed.slice(0, slash);\n\tconst arch = trimmed.slice(slash + 1);\n\tconst normalizedArch = DOCKER_ARCH_ALIASES[arch] ?? arch;\n\treturn `${os}/${normalizedArch}`;\n};\n\nconst inferDockerBuildPlatform = (): Effect.Effect<\n\tstring | null,\n\tnever,\n\tDockerHost | DockerSpawner\n> =>\n\tdockerRunOk('info', ['--format', '{{.OSType}}/{{.Architecture}}']).pipe(\n\t\tEffect.map((result) =>\n\t\t\tresult.exitCode === 0 ? normalizeDockerInfoPlatform(result.stdout) : null,\n\t\t),\n\t\tEffect.catch(() => Effect.succeed(null)),\n\t);\n\nexport const layerContainerRuntimeDocker: Layer.Layer<\n\tContainerRuntimeService,\n\tnever,\n\tCacheService | DockerHost | DockerSpawner | DockerCycle | StackPathsService\n> = Layer.effect(\n\tContainerRuntimeService,\n\tEffect.gen(function* () {\n\t\tconst cycleRef = yield* DockerCycle;\n\t\t// Snapshot the substrate services so we can provide them to the\n\t\t// closures that implement the contract's R=never surface.\n\t\tconst dockerHost = yield* DockerHost;\n\t\tconst dockerSpawner = yield* DockerSpawner;\n\t\tconst stackPaths = yield* StackPathsService;\n\t\tconst cache = yield* CacheService;\n\t\tconst baseCtx = Context.empty().pipe(\n\t\t\tContext.add(DockerHost, dockerHost),\n\t\t\tContext.add(DockerSpawner, dockerSpawner),\n\t\t\tContext.add(StackPathsService, stackPaths),\n\t\t\tContext.add(CacheService, cache),\n\t\t);\n\t\t// Per-name in-process serialization. Architecture invariant:\n\t\t// two concurrent ensureContainer calls for the same name must\n\t\t// not interleave docker inspect/create/start. The cross-process\n\t\t// safety is the daemon's `--name` atomicity (see container.ts\n\t\t// collision recovery). The in-process side is this ref.\n\t\tconst perNameLock = yield* Ref.make<PerNameLockState>(new Map());\n\n\t\tconst ensureImage = (\n\t\t\tctx: ContainerBuildContext,\n\t\t\texpected?: ImageRef,\n\t\t): Effect.Effect<ImageRef, ContainerRuntimeError> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst inferredPlatform =\n\t\t\t\t\tctx.platform === undefined\n\t\t\t\t\t\t? yield* inferDockerBuildPlatform().pipe(Effect.provide(baseCtx))\n\t\t\t\t\t\t: null;\n\t\t\t\tconst effectiveCtx =\n\t\t\t\t\tctx.platform === undefined && inferredPlatform !== null\n\t\t\t\t\t\t? { ...ctx, platform: inferredPlatform }\n\t\t\t\t\t\t: ctx;\n\t\t\t\t// Architecture §8: bring-your-own-image vs build is a closed sum.\n\t\t\t\t// The contract accepts `ContainerBuildContext` (build path);\n\t\t\t\t// pull is exposed via `image.ts::pull` directly to plugins\n\t\t\t\t// that need it (not through this contract entry point).\n\t\t\t\t//\n\t\t\t\t// Content-addressed cache: namespace is the constant\n\t\t\t\t// `runtime-docker-build` (one substrate-owned namespace);\n\t\t\t\t// chain is `n/a` (build artifacts are chain-independent);\n\t\t\t\t// contentHash is a hash of the build context's identifying\n\t\t\t\t// fields. The caller-supplied `expected.tag`, when present,\n\t\t\t\t// is honoured as the on-host tag; absent, we derive a tag\n\t\t\t\t// from the content hash so two unrelated contexts cannot\n\t\t\t\t// collide on the sanitized contextPath form.\n\t\t\t\tconst hash = buildContentHash(effectiveCtx);\n\t\t\t\tconst tag = expected?.tag ?? `devstack-build:${hash.slice(0, 16)}`;\n\t\t\t\treturn yield* ensureImageCached(\n\t\t\t\t\t{\n\t\t\t\t\t\tcontextPath: effectiveCtx.contextPath,\n\t\t\t\t\t\tdockerfile: effectiveCtx.dockerfile,\n\t\t\t\t\t\tplatform: effectiveCtx.platform,\n\t\t\t\t\t\tbuildArgs: effectiveCtx.buildArgs,\n\t\t\t\t\t\ttag,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tnamespace: 'runtime-docker-build',\n\t\t\t\t\t\tchain: chainId('n/a'),\n\t\t\t\t\t\tcontentHash: contentHash(hash),\n\t\t\t\t\t},\n\t\t\t\t).pipe(\n\t\t\t\t\tEffect.map((digest) => refOf(digest, tag)),\n\t\t\t\t\tmapToContractError,\n\t\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\t\tEffect.withSpan('runtime.docker.contract.ensureImage'),\n\t\t\t\t);\n\t\t\t});\n\n\t\tconst ensureNetworkContractImpl = (\n\t\t\tspec: EnsureNetworkSpec,\n\t\t): Effect.Effect<string, ContainerRuntimeError> =>\n\t\t\tensureNetworkImpl(spec.name, {\n\t\t\t\tapp: spec.app,\n\t\t\t\tstack: spec.stack,\n\t\t\t\t...(spec.subnet === undefined ? {} : { subnet: spec.subnet }),\n\t\t\t\t...(spec.gateway === undefined ? {} : { gateway: spec.gateway }),\n\t\t\t}).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.ensureNetwork'),\n\t\t\t);\n\n\t\tconst pullImageContractImpl = (ref: string): Effect.Effect<ImageRef, ContainerRuntimeError> =>\n\t\t\tpullImageImpl(ref).pipe(\n\t\t\t\tEffect.map((digest) => refOf(digest, ref)),\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.pullImage'),\n\t\t\t);\n\n\t\tconst ensureContainerImpl = (\n\t\t\tspec: EnsureContainerSpec,\n\t\t): Effect.Effect<ContainerHandle, ContainerRuntimeError, import('effect').Scope.Scope> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst cycle = yield* Ref.get(cycleRef);\n\t\t\t\treturn yield* ensureContainer(spec, { cycle, perNameLock });\n\t\t\t}).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.ensureContainer'),\n\t\t\t);\n\n\t\tconst inspectByLabels = (\n\t\t\tlabels: ContainerLabelTuple,\n\t\t): Effect.Effect<ReadonlyArray<ContainerHandle>, ContainerRuntimeError> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst summaries = yield* listContainers(labels);\n\t\t\t\treturn yield* Effect.forEach(\n\t\t\t\t\tsummaries,\n\t\t\t\t\t(s) =>\n\t\t\t\t\t\tinspectContainer(s.name).pipe(\n\t\t\t\t\t\t\tEffect.map(\n\t\t\t\t\t\t\t\t(facts): ContainerHandle => ({\n\t\t\t\t\t\t\t\t\tid: facts?.id ?? s.id,\n\t\t\t\t\t\t\t\t\tname: s.name,\n\t\t\t\t\t\t\t\t\tlabels,\n\t\t\t\t\t\t\t\t\timageName: facts?.image ?? s.image,\n\t\t\t\t\t\t\t\t\tstatus: (facts?.paused\n\t\t\t\t\t\t\t\t\t\t? 'paused'\n\t\t\t\t\t\t\t\t\t\t: (facts?.running ?? s.state === 'running')\n\t\t\t\t\t\t\t\t\t\t\t? 'running'\n\t\t\t\t\t\t\t\t\t\t\t: s.state === 'paused'\n\t\t\t\t\t\t\t\t\t\t\t\t? 'paused'\n\t\t\t\t\t\t\t\t\t\t\t\t: s.state === 'created'\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 'created'\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'exited') as ContainerHandle['status'],\n\t\t\t\t\t\t\t\t\tips: [],\n\t\t\t\t\t\t\t\t\t...(facts?.ports !== undefined ? { ports: facts.ports } : {}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t{ concurrency: 'unbounded' },\n\t\t\t\t);\n\t\t\t}).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.inspectByLabels'),\n\t\t\t);\n\n\t\tconst followLogsImpl = (\n\t\t\thandle: ContainerHandle,\n\t\t): Stream.Stream<string, ContainerRuntimeError> =>\n\t\t\tfollowLogsStream(handle.name).pipe(\n\t\t\t\tStream.mapError(toContractError),\n\t\t\t\t// R-channel: the underlying stream needs DockerHost +\n\t\t\t\t// DockerSpawner from the spawn step. Provide the\n\t\t\t\t// snapshotted base context so the contract surface is\n\t\t\t\t// `R = never`. `Stream.mapError` does NOT drop R; the\n\t\t\t\t// `as`-cast in the previous shape was a release-blocker\n\t\t\t\t// per runtime-docker review issue #3.\n\t\t\t\tStream.provideContext(baseCtx),\n\t\t\t);\n\n\t\tconst pauseAndCommitImpl = (\n\t\t\thandle: ContainerHandle,\n\t\t): Effect.Effect<TaggedImageRef, ContainerRuntimeError> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tyield* assertContainerHandleOwned(handle);\n\t\t\t\tif (handle.status === 'running') {\n\t\t\t\t\tyield* pause(handle.name);\n\t\t\t\t\tyield* assertContainerHandleOwned(handle);\n\t\t\t\t}\n\t\t\t\tconst tag = snapshotTempTag(handle.name);\n\t\t\t\tconst digest = yield* commit(handle.name, tag);\n\t\t\t\treturn { digest, tag };\n\t\t\t}).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.pauseAndCommit'),\n\t\t\t);\n\n\t\tconst pauseImpl = (handle: ContainerHandle): Effect.Effect<void, ContainerRuntimeError> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tyield* assertContainerHandleOwned(handle);\n\t\t\t\tyield* pause(handle.name);\n\t\t\t}).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.pause'),\n\t\t\t);\n\n\t\tconst unpauseImpl = (handle: ContainerHandle): Effect.Effect<void, ContainerRuntimeError> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tyield* assertContainerHandleOwned(handle);\n\t\t\t\tyield* unpause(handle.name);\n\t\t\t}).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.unpause'),\n\t\t\t);\n\n\t\tconst stopImpl = (\n\t\t\thandle: ContainerHandle,\n\t\t\tgrace: Duration.Duration,\n\t\t): Effect.Effect<void, ContainerRuntimeError> => {\n\t\t\tconst seconds = Math.max(0, Math.ceil(Duration.toMillis(grace) / 1000));\n\t\t\treturn Effect.gen(function* () {\n\t\t\t\tyield* assertContainerHandleOwned(handle);\n\t\t\t\tyield* stopContainer(handle.name, seconds);\n\t\t\t}).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.stop'),\n\t\t\t);\n\t\t};\n\n\t\tconst sweepOrphansImpl = (\n\t\t\tlabelMatch: Partial<ContainerLabelTuple>,\n\t\t): Effect.Effect<number, ContainerRuntimeError> =>\n\t\t\tsweepOrphans(labelMatch).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.sweepOrphans'),\n\t\t\t);\n\n\t\tconst removeManagedContainersImpl = (\n\t\t\tlabelMatch: Partial<ContainerLabelTuple>,\n\t\t): Effect.Effect<number, ContainerRuntimeError> =>\n\t\t\tremoveManagedContainers(labelMatch).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.removeManagedContainers'),\n\t\t\t);\n\n\t\tconst removeManagedImagesImpl = (\n\t\t\tlabelMatch: Partial<ContainerLabelTuple>,\n\t\t): Effect.Effect<number, ContainerRuntimeError> =>\n\t\t\tremoveManagedImages(labelMatch).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.removeManagedImages'),\n\t\t\t);\n\n\t\tconst removeManagedNetworksImpl = (\n\t\t\tlabelMatch: Partial<ContainerLabelTuple>,\n\t\t): Effect.Effect<number, ContainerRuntimeError> =>\n\t\t\tremoveManagedNetworks(labelMatch).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.removeManagedNetworks'),\n\t\t\t);\n\n\t\tconst removeManagedVolumesImpl = (\n\t\t\tlabelMatch: Partial<ContainerLabelTuple>,\n\t\t): Effect.Effect<number, ContainerRuntimeError> =>\n\t\t\tremoveManagedVolumes(labelMatch).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.removeManagedVolumes'),\n\t\t\t);\n\n\t\tconst execImpl = (\n\t\t\thandle: ContainerHandle,\n\t\t\targv: ReadonlyArray<string>,\n\t\t\topts?: ExecOptions,\n\t\t): Effect.Effect<ExecResult, ContainerRuntimeError> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tyield* assertContainerHandleOwned(handle);\n\t\t\t\treturn yield* dockerExec(handle.name, argv, {\n\t\t\t\t\tuser: opts?.user,\n\t\t\t\t\tenv: opts?.env,\n\t\t\t\t\tworkdir: opts?.workdir,\n\t\t\t\t});\n\t\t\t}).pipe(\n\t\t\t\t// Contract surface: NEVER promote non-zero exit to failure\n\t\t\t\t// here. The caller is the policy holder.\n\t\t\t\tEffect.map(\n\t\t\t\t\t(r): ExecResult => ({\n\t\t\t\t\t\texitCode: r.exitCode,\n\t\t\t\t\t\tstdout: r.stdout,\n\t\t\t\t\t\tstderr: r.stderr,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.exec'),\n\t\t\t);\n\n\t\tconst saveImageImpl = (\n\t\t\tref: ImageRef,\n\t\t\topts?: SaveImageOptions,\n\t\t): Stream.Stream<Uint8Array, ContainerRuntimeError> => {\n\t\t\tconst resolved = ref.tag ?? ref.digest;\n\t\t\treturn saveImageStream(resolved, opts).pipe(\n\t\t\t\tStream.mapError(toContractError),\n\t\t\t\tStream.provideContext(baseCtx),\n\t\t\t);\n\t\t};\n\t\tconst saveImagesImpl = (\n\t\t\trefs: ReadonlyArray<ImageRef>,\n\t\t\topts?: SaveImageOptions,\n\t\t): Stream.Stream<Uint8Array, ContainerRuntimeError> => {\n\t\t\tconst resolved = refs.map((ref) => ref.tag ?? ref.digest);\n\t\t\treturn saveImagesStream(resolved, opts).pipe(\n\t\t\t\tStream.mapError(toContractError),\n\t\t\t\tStream.provideContext(baseCtx),\n\t\t\t);\n\t\t};\n\n\t\tconst loadImageContractImpl = (\n\t\t\ttar: Stream.Stream<Uint8Array, unknown>,\n\t\t): Effect.Effect<LoadedImageBundle, ContainerRuntimeError> =>\n\t\t\tloadImageImpl(tar).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.loadImage'),\n\t\t\t);\n\n\t\tconst tagImageContractImpl = (\n\t\t\tsrc: ImageRef,\n\t\t\tnewTag: string,\n\t\t\topts?: TagImageOptions,\n\t\t): Effect.Effect<void, ContainerRuntimeError> => {\n\t\t\tconst resolved = src.tag ?? src.digest;\n\t\t\treturn tagImageImpl(resolved, newTag, opts).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.tagImage'),\n\t\t\t);\n\t\t};\n\n\t\tconst removeImageContractImpl = (ref: ImageRef): Effect.Effect<void, ContainerRuntimeError> => {\n\t\t\tconst resolved = ref.tag ?? ref.digest;\n\t\t\treturn removeImageImpl(resolved).pipe(\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.removeImage'),\n\t\t\t);\n\t\t};\n\n\t\tconst runOneShotImpl = (\n\t\t\tspec: OneShotSpec,\n\t\t): Effect.Effect<ExecResult, ContainerRuntimeError, import('effect').Scope.Scope> =>\n\t\t\tdockerRunOneShot({\n\t\t\t\timage: spec.image.tag ?? spec.image.digest,\n\t\t\t\targv: spec.argv,\n\t\t\t\tenv: spec.env,\n\t\t\t\tmounts: spec.mounts,\n\t\t\t\tnetwork: spec.network,\n\t\t\t\tentrypoint: spec.entrypoint,\n\t\t\t\tuser: spec.user,\n\t\t\t\ttimeoutMillis: spec.timeoutMillis,\n\t\t\t\textraHosts: spec.extraHosts,\n\t\t\t}).pipe(\n\t\t\t\t// Same contract: never promote non-zero exit to failure.\n\t\t\t\tEffect.map(\n\t\t\t\t\t(r): ExecResult => ({\n\t\t\t\t\t\texitCode: r.exitCode,\n\t\t\t\t\t\tstdout: r.stdout,\n\t\t\t\t\t\tstderr: r.stderr,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tmapToContractError,\n\t\t\t\tEffect.provide(baseCtx),\n\t\t\t\tEffect.withSpan('runtime.docker.contract.runOneShot'),\n\t\t\t);\n\n\t\treturn ContainerRuntimeService.of({\n\t\t\tensureImage,\n\t\t\tpullImage: pullImageContractImpl,\n\t\t\tensureNetwork: ensureNetworkContractImpl,\n\t\t\tensureContainer: ensureContainerImpl,\n\t\t\texec: execImpl,\n\t\t\trunOneShot: runOneShotImpl,\n\t\t\tinspectByLabels,\n\t\t\tfollowLogs: followLogsImpl,\n\t\t\tpause: pauseImpl,\n\t\t\tpauseAndCommit: pauseAndCommitImpl,\n\t\t\tsaveImage: saveImageImpl,\n\t\t\tsaveImages: saveImagesImpl,\n\t\t\tloadImage: loadImageContractImpl,\n\t\t\ttagImage: tagImageContractImpl,\n\t\t\tremoveImage: removeImageContractImpl,\n\t\t\tunpause: unpauseImpl,\n\t\t\tstop: stopImpl,\n\t\t\tsweepOrphans: sweepOrphansImpl,\n\t\t\tremoveManagedContainers: removeManagedContainersImpl,\n\t\t\tremoveManagedImages: removeManagedImagesImpl,\n\t\t\tremoveManagedNetworks: removeManagedNetworksImpl,\n\t\t\tremoveManagedVolumes: removeManagedVolumesImpl,\n\t\t});\n\t}),\n);\n"],"mappings":"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"}
|