@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,278 @@
|
|
|
1
|
+
import { decodeJsonTextSync } from "../../substrate/runtime/runtime-decode.mjs";
|
|
2
|
+
import { CacheService } from "../../substrate/runtime/cache/service.mjs";
|
|
3
|
+
import { DockerHost, DockerSpawner, dockerCommand, dockerRun, dockerRunOk } from "./client.mjs";
|
|
4
|
+
import { ImageLoadFailed, ImageNotFound, ImageRemoveFailed, ImageSaveFailed, ImageTagFailed } from "./errors.mjs";
|
|
5
|
+
import { isImageNotFoundStderr, wrapBuildError, wrapGeneric, wrapPullError } from "./wrap.mjs";
|
|
6
|
+
import { Effect, Fiber, Schema, Stream } from "effect";
|
|
7
|
+
//#region src/runtime/docker/image.ts
|
|
8
|
+
const SNAPSHOT_TEMP_TAG_PREFIX = "devstack-snapshot:";
|
|
9
|
+
const isSnapshotTempTag = (ref) => ref.startsWith(SNAPSHOT_TEMP_TAG_PREFIX);
|
|
10
|
+
const cleanupSnapshotTempTag = (ref) => {
|
|
11
|
+
if (!isSnapshotTempTag(ref)) return Effect.void;
|
|
12
|
+
return dockerRunOk("image", ["rm", ref]).pipe(Effect.catch(() => Effect.void), Effect.asVoid);
|
|
13
|
+
};
|
|
14
|
+
/** Encode/decode the cache entry — we store the resolved image digest
|
|
15
|
+
* as plain UTF-8 bytes so the cache primitive's byte shape works. */
|
|
16
|
+
const encodeDigest = (digest) => new TextEncoder().encode(JSON.stringify({ digest }));
|
|
17
|
+
const DigestDoc = Schema.Struct({ digest: Schema.String });
|
|
18
|
+
const decodeDigest = (bytes) => {
|
|
19
|
+
try {
|
|
20
|
+
return decodeJsonTextSync(DigestDoc, new TextDecoder().decode(bytes), {
|
|
21
|
+
source: "docker image digest cache",
|
|
22
|
+
mkError: (issue) => issue
|
|
23
|
+
}).digest;
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/** `docker image inspect <ref>` — returns the digest, or null on miss. */
|
|
29
|
+
const imageExists = (ref) => Effect.gen(function* () {
|
|
30
|
+
const res = yield* dockerRunOk("image", [
|
|
31
|
+
"inspect",
|
|
32
|
+
"--format",
|
|
33
|
+
"{{.Id}}",
|
|
34
|
+
ref
|
|
35
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.image.inspect")));
|
|
36
|
+
if (res.exitCode !== 0) return null;
|
|
37
|
+
const id = res.stdout.trim();
|
|
38
|
+
return id.length > 0 ? id : null;
|
|
39
|
+
}).pipe(Effect.withSpan("runtime.docker.image.exists"));
|
|
40
|
+
/** Strict variant — surfaces `ImageNotFound` if the inspect misses. */
|
|
41
|
+
const inspectDigest = (ref) => Effect.gen(function* () {
|
|
42
|
+
const id = yield* imageExists(ref);
|
|
43
|
+
if (id === null) return yield* Effect.fail(new ImageNotFound({
|
|
44
|
+
ref,
|
|
45
|
+
detail: "docker image inspect returned empty"
|
|
46
|
+
}));
|
|
47
|
+
return id;
|
|
48
|
+
}).pipe(Effect.withSpan("runtime.docker.image.inspectDigest"));
|
|
49
|
+
/** `docker pull <ref>` — surfaces ImageNotFound / ImagePullFailed.
|
|
50
|
+
* Per-line progress emission opt-in via `onLine`. */
|
|
51
|
+
const pull = (ref, onLine) => Effect.gen(function* () {
|
|
52
|
+
yield* dockerRun("pull", [ref], { onStdoutLine: onLine }).pipe(Effect.mapError(wrapPullError(ref)));
|
|
53
|
+
return yield* inspectDigest(ref);
|
|
54
|
+
}).pipe(Effect.withSpan("runtime.docker.image.pull"));
|
|
55
|
+
/** `docker build -t <tag> [-f Dockerfile] <ctx>`. On exit-0 the
|
|
56
|
+
* resulting tag is on-host; we read its digest and return.
|
|
57
|
+
*
|
|
58
|
+
* NOTE: the content-addressed cache integration is in `ensureImageCached`
|
|
59
|
+
* below — this verb is the unconditional build, used when the cache
|
|
60
|
+
* has missed AND the on-host tag-exists probe also missed. */
|
|
61
|
+
const build = (opts) => Effect.gen(function* () {
|
|
62
|
+
const args = ["-t", opts.tag];
|
|
63
|
+
if (opts.platform !== void 0) args.push("--platform", opts.platform);
|
|
64
|
+
if (opts.dockerfile && opts.dockerfile !== "Dockerfile") {
|
|
65
|
+
const resolved = opts.dockerfile.startsWith("/") || /^[A-Za-z]:/.test(opts.dockerfile) ? opts.dockerfile : `${opts.contextPath.replace(/\/$/, "")}/${opts.dockerfile}`;
|
|
66
|
+
args.push("-f", resolved);
|
|
67
|
+
}
|
|
68
|
+
if (opts.buildArgs) for (const [k, v] of Object.entries(opts.buildArgs)) args.push("--build-arg", `${k}=${v}`);
|
|
69
|
+
args.push(opts.contextPath);
|
|
70
|
+
yield* dockerRun("build", args, {
|
|
71
|
+
onStdoutLine: opts.onLine,
|
|
72
|
+
onStderrLine: opts.onLine
|
|
73
|
+
}).pipe(Effect.mapError(wrapBuildError(opts.contextPath, opts.dockerfile)));
|
|
74
|
+
return yield* inspectDigest(opts.tag);
|
|
75
|
+
}).pipe(Effect.withSpan("runtime.docker.image.build"));
|
|
76
|
+
/** `docker tag <src> <dst>` — used by snapshot restore to alias a
|
|
77
|
+
* loaded image back to its original tag. */
|
|
78
|
+
const tagImage = (src, dst, opts = {}) => Effect.gen(function* () {
|
|
79
|
+
const res = yield* dockerRunOk("tag", [src, dst]).pipe(Effect.mapError(wrapGeneric("docker.tag")));
|
|
80
|
+
if (res.exitCode !== 0) {
|
|
81
|
+
if (isImageNotFoundStderr(res.stderr)) return yield* Effect.fail(new ImageNotFound({
|
|
82
|
+
ref: src,
|
|
83
|
+
detail: `tag source missing: ${res.stderr}`
|
|
84
|
+
}));
|
|
85
|
+
return yield* Effect.fail(new ImageTagFailed({
|
|
86
|
+
src,
|
|
87
|
+
dst,
|
|
88
|
+
stderr: res.stderr
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
if (opts.removeSourceAfterTag === true && src !== dst) yield* cleanupSnapshotTempTag(src);
|
|
92
|
+
}).pipe(Effect.withSpan("runtime.docker.image.tag"));
|
|
93
|
+
const isMissingImageStderr = (stderr) => /no such image|not found|reference does not exist/i.test(stderr);
|
|
94
|
+
const removeImage = (ref) => Effect.gen(function* () {
|
|
95
|
+
const res = yield* dockerRunOk("image", [
|
|
96
|
+
"rm",
|
|
97
|
+
"-f",
|
|
98
|
+
ref
|
|
99
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.image.rm")));
|
|
100
|
+
if (res.exitCode === 0 || isMissingImageStderr(res.stderr)) return;
|
|
101
|
+
return yield* Effect.fail(new ImageRemoveFailed({
|
|
102
|
+
ref,
|
|
103
|
+
stderr: res.stderr,
|
|
104
|
+
exitCode: res.exitCode
|
|
105
|
+
}));
|
|
106
|
+
}).pipe(Effect.withSpan("runtime.docker.image.remove"));
|
|
107
|
+
/** Stream the bytes of `docker save <ref>` to the consumer. Stdout
|
|
108
|
+
* stays streaming so large images never materialise in memory; stderr
|
|
109
|
+
* and exit are drained concurrently so a missing image cannot look
|
|
110
|
+
* like a successful empty tar. */
|
|
111
|
+
const saveImages = (refs, opts = {}) => {
|
|
112
|
+
const mapSpawnError = (cause) => new ImageSaveFailed({
|
|
113
|
+
ref: refs.join(" "),
|
|
114
|
+
detail: refs.length === 0 ? "docker save called with no image refs" : "docker save spawn failed",
|
|
115
|
+
cause
|
|
116
|
+
});
|
|
117
|
+
if (refs.length === 0) return Stream.fail(mapSpawnError(/* @__PURE__ */ new Error("empty docker save ref list")));
|
|
118
|
+
return Stream.unwrap(Effect.gen(function* () {
|
|
119
|
+
const host = yield* DockerHost;
|
|
120
|
+
const spawner = yield* DockerSpawner;
|
|
121
|
+
const cmd = dockerCommand(host, "save", refs);
|
|
122
|
+
const handle = yield* spawner.spawn(cmd).pipe(Effect.mapError(mapSpawnError));
|
|
123
|
+
const stderrFiber = yield* Effect.forkChild(Stream.mkString(Stream.decodeText(handle.stderr)).pipe(Effect.mapError((cause) => new ImageSaveFailed({
|
|
124
|
+
ref: refs.join(" "),
|
|
125
|
+
detail: "docker save stderr drain failed",
|
|
126
|
+
cause
|
|
127
|
+
}))));
|
|
128
|
+
const exitFiber = yield* Effect.forkChild(handle.exitCode.pipe(Effect.mapError((cause) => new ImageSaveFailed({
|
|
129
|
+
ref: refs.join(" "),
|
|
130
|
+
detail: "docker save exit failed",
|
|
131
|
+
cause
|
|
132
|
+
}))));
|
|
133
|
+
const checkExit = Effect.gen(function* () {
|
|
134
|
+
const [stderrText, exitCode] = yield* Effect.all([Fiber.join(stderrFiber), Fiber.join(exitFiber)], { concurrency: "unbounded" });
|
|
135
|
+
if (exitCode !== 0) return yield* Effect.fail(new ImageSaveFailed({
|
|
136
|
+
ref: refs.join(" "),
|
|
137
|
+
detail: `docker save exited ${exitCode}${stderrText.length > 0 ? `: ${stderrText}` : ""}`
|
|
138
|
+
}));
|
|
139
|
+
});
|
|
140
|
+
const cleanupTag = opts.removeAfterSave === true ? Effect.forEach(refs, cleanupSnapshotTempTag, { concurrency: "unbounded" }).pipe(Effect.asVoid) : Effect.void;
|
|
141
|
+
const cleanup = Effect.all([
|
|
142
|
+
cleanupTag,
|
|
143
|
+
Fiber.interrupt(stderrFiber),
|
|
144
|
+
Fiber.interrupt(exitFiber)
|
|
145
|
+
], { concurrency: "unbounded" }).pipe(Effect.asVoid);
|
|
146
|
+
return handle.stdout.pipe(Stream.mapError((cause) => new ImageSaveFailed({
|
|
147
|
+
ref: refs.join(" "),
|
|
148
|
+
detail: "docker save stdout pipe failed",
|
|
149
|
+
cause
|
|
150
|
+
})), Stream.onEnd(checkExit), Stream.ensuring(cleanup));
|
|
151
|
+
}));
|
|
152
|
+
};
|
|
153
|
+
const saveImage = (ref, opts = {}) => saveImages([ref], opts);
|
|
154
|
+
/** Parse `docker load` stdout lines to extract the loaded image refs.
|
|
155
|
+
* Docker's output is one of:
|
|
156
|
+
* - `Loaded image: <tag>`
|
|
157
|
+
* - `Loaded image ID: sha256:<digest>`
|
|
158
|
+
* Exported for direct testing without a docker dependency. */
|
|
159
|
+
const parseLoadedRefs = (stdout) => {
|
|
160
|
+
const refs = [];
|
|
161
|
+
for (const rawLine of stdout.split(/\r?\n/)) {
|
|
162
|
+
const line = rawLine.trim();
|
|
163
|
+
const taggedMatch = /^Loaded image: (\S+)$/.exec(line);
|
|
164
|
+
if (taggedMatch?.[1]) {
|
|
165
|
+
refs.push({ tag: taggedMatch[1] });
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const digestMatch = /^Loaded image ID: (sha256:\S+)$/.exec(line);
|
|
169
|
+
if (digestMatch?.[1]) refs.push({ digest: digestMatch[1] });
|
|
170
|
+
}
|
|
171
|
+
return refs;
|
|
172
|
+
};
|
|
173
|
+
/** `docker load < <tar-stream>`. Returns every freshly-loaded ref
|
|
174
|
+
* Docker reported on stdout. Symmetric with `saveImage`/`saveImages`.
|
|
175
|
+
* Upstream stream errors (e.g. file-read failures from a snapshot
|
|
176
|
+
* tar) are projected to `ImageLoadFailed` so callers see one shape.
|
|
177
|
+
*
|
|
178
|
+
* Stdin lifetime: the supplied stream is fed in via the spawner's
|
|
179
|
+
* `stdin` sink under the same scope as the spawn itself; both close
|
|
180
|
+
* when the child exits. */
|
|
181
|
+
const loadImage = (tar) => Effect.gen(function* () {
|
|
182
|
+
const host = yield* DockerHost;
|
|
183
|
+
const spawner = yield* DockerSpawner;
|
|
184
|
+
const cmd = dockerCommand(host, "load", []);
|
|
185
|
+
const mapSpawnError = (cause) => new ImageLoadFailed({
|
|
186
|
+
detail: "docker load spawn failed",
|
|
187
|
+
cause
|
|
188
|
+
});
|
|
189
|
+
return yield* Effect.scoped(Effect.gen(function* () {
|
|
190
|
+
const handle = yield* spawner.spawn(cmd).pipe(Effect.mapError(mapSpawnError));
|
|
191
|
+
const writeStdin = Stream.run(tar, handle.stdin).pipe(Effect.mapError((cause) => new ImageLoadFailed({
|
|
192
|
+
detail: "docker load stdin pipe failed",
|
|
193
|
+
cause
|
|
194
|
+
})));
|
|
195
|
+
const stdoutDrain = Stream.mkString(Stream.decodeText(handle.stdout)).pipe(Effect.mapError((cause) => new ImageLoadFailed({
|
|
196
|
+
detail: "docker load stdout drain failed",
|
|
197
|
+
cause
|
|
198
|
+
})));
|
|
199
|
+
const stderrDrain = Stream.mkString(Stream.decodeText(handle.stderr)).pipe(Effect.mapError((cause) => new ImageLoadFailed({
|
|
200
|
+
detail: "docker load stderr drain failed",
|
|
201
|
+
cause
|
|
202
|
+
})));
|
|
203
|
+
const exit = handle.exitCode.pipe(Effect.mapError((cause) => new ImageLoadFailed({
|
|
204
|
+
detail: "docker load exit failed",
|
|
205
|
+
cause
|
|
206
|
+
})));
|
|
207
|
+
const [, stdoutText, stderrText, exitCode] = yield* Effect.all([
|
|
208
|
+
writeStdin,
|
|
209
|
+
stdoutDrain,
|
|
210
|
+
stderrDrain,
|
|
211
|
+
exit
|
|
212
|
+
], { concurrency: "unbounded" });
|
|
213
|
+
if (exitCode !== 0) return yield* Effect.fail(new ImageLoadFailed({
|
|
214
|
+
detail: `docker load exited ${exitCode}`,
|
|
215
|
+
stderr: stderrText
|
|
216
|
+
}));
|
|
217
|
+
const parsed = parseLoadedRefs(stdoutText);
|
|
218
|
+
if (parsed.length === 0) return yield* Effect.fail(new ImageLoadFailed({
|
|
219
|
+
detail: "docker load succeeded but no Loaded image lines found",
|
|
220
|
+
stderr: stdoutText
|
|
221
|
+
}));
|
|
222
|
+
return { refs: yield* Effect.forEach(parsed, (ref) => Effect.gen(function* () {
|
|
223
|
+
if (ref.digest !== void 0) return refOf(ref.digest, ref.tag);
|
|
224
|
+
const digest = yield* imageExists(ref.tag);
|
|
225
|
+
if (digest === null) return yield* Effect.fail(new ImageLoadFailed({ detail: `loaded image '${ref.tag}' not visible to inspect` }));
|
|
226
|
+
return refOf(digest, ref.tag);
|
|
227
|
+
}), { concurrency: "unbounded" }) };
|
|
228
|
+
}));
|
|
229
|
+
}).pipe(Effect.withSpan("runtime.docker.image.load"));
|
|
230
|
+
/** Content-addressed image build:
|
|
231
|
+
*
|
|
232
|
+
* 1. cache lookup keyed by (namespace, chainId, contentHash)
|
|
233
|
+
* 2. on hit, verify the on-host tag still resolves; if so return
|
|
234
|
+
* 3. on miss, run `docker build`, then write the resolved digest
|
|
235
|
+
* to the cache (best-effort — write failure does not roll back
|
|
236
|
+
* the on-host build).
|
|
237
|
+
*
|
|
238
|
+
* Caller-supplied tag is the content-addressed name; the cache key
|
|
239
|
+
* is independent so an unrelated invalidation (e.g. base-image
|
|
240
|
+
* bump) can drop the cache without disturbing the tag scheme. */
|
|
241
|
+
const ensureImageCached = (opts, key) => Effect.gen(function* () {
|
|
242
|
+
const cache = yield* CacheService;
|
|
243
|
+
const hit = yield* cache.lookup({
|
|
244
|
+
namespace: key.namespace,
|
|
245
|
+
chain: key.chain,
|
|
246
|
+
contentHash: key.contentHash
|
|
247
|
+
}).pipe(Effect.catch(() => Effect.succeed(null)));
|
|
248
|
+
if (hit !== null) {
|
|
249
|
+
if (decodeDigest(hit.bytes) !== null) {
|
|
250
|
+
const existing = yield* imageExists(opts.tag);
|
|
251
|
+
if (existing !== null) return existing;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const onHost = yield* imageExists(opts.tag);
|
|
255
|
+
if (onHost !== null) {
|
|
256
|
+
yield* cache.write({
|
|
257
|
+
namespace: key.namespace,
|
|
258
|
+
chain: key.chain,
|
|
259
|
+
contentHash: key.contentHash
|
|
260
|
+
}, encodeDigest(onHost)).pipe(Effect.catch(() => Effect.void));
|
|
261
|
+
return onHost;
|
|
262
|
+
}
|
|
263
|
+
const digest = yield* build(opts);
|
|
264
|
+
yield* cache.write({
|
|
265
|
+
namespace: key.namespace,
|
|
266
|
+
chain: key.chain,
|
|
267
|
+
contentHash: key.contentHash
|
|
268
|
+
}, encodeDigest(digest)).pipe(Effect.catch(() => Effect.void));
|
|
269
|
+
return digest;
|
|
270
|
+
}).pipe(Effect.withSpan("runtime.docker.image.ensureCached"));
|
|
271
|
+
const refOf = (digest, tag) => tag !== void 0 ? {
|
|
272
|
+
digest,
|
|
273
|
+
tag
|
|
274
|
+
} : { digest };
|
|
275
|
+
//#endregion
|
|
276
|
+
export { ensureImageCached, loadImage, pull, refOf, removeImage, saveImage, saveImages, tagImage };
|
|
277
|
+
|
|
278
|
+
//# sourceMappingURL=image.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.mjs","names":[],"sources":["../../../src/runtime/docker/image.ts"],"sourcesContent":["// Docker image lifecycle.\n//\n// Architecture § Docker backend § Images:\n// - Bring-your-own-image vs build is a CLOSED SUM (architecture §8):\n// either the caller supplies an image ref (`docker pull`) or a\n// `ContainerBuildContext` (`docker build`); no third option.\n// - Content-addressed build cache: the substrate's L0 cache holds\n// the `(namespace, chainId, contentHash) → imageDigest` mapping.\n// When the cache hits we short-circuit the build. The `docker\n// build` itself is then a no-op when the resulting tag already\n// exists on the host (defense-in-depth — cache miss but on-host\n// tag-exists still skips the build).\n// - Pull progress narration is wired through `onStdoutLine` /\n// `onStderrLine` per-line callbacks on the L0 capture; the L1\n// observability sink promotes WARN/ERROR markers.\n//\n// Surface:\n// - `imageExists(ref)` — `docker inspect` short-circuit\n// - `pull(ref)` — `docker pull`; surfaces ImageNotFound /\n// ImagePullFailed via wrap.ts\n// - `build(ctx, tag)` — `docker build -t <tag> <ctx>`; surfaces\n// BuildFailed via wrap.ts; integrates with\n// the L0 cache\n// - `tag(src, dst)` — `docker tag`\n// - `inspectDigest` — read the on-host digest of a tag\n\nimport { Effect, Fiber, Schema, Stream } from 'effect';\n\nimport type { ChainId, ContentHash } from '../../substrate/brand.ts';\nimport { CacheService } from '../../substrate/runtime/cache/index.ts';\nimport { decodeJsonTextSync } from '../../substrate/runtime/runtime-decode.ts';\nimport type { ImageRef, LoadedImageBundle } from '../../contracts/container-runtime.ts';\nimport { DockerHost, DockerSpawner, dockerCommand, dockerRun, dockerRunOk } from './client.ts';\nimport type { DockerRuntimeError } from './errors.ts';\nimport {\n\tImageLoadFailed,\n\tImageNotFound,\n\tImageRemoveFailed,\n\tImageSaveFailed,\n\tImageTagFailed,\n} from './errors.ts';\nimport { isImageNotFoundStderr, wrapBuildError, wrapGeneric, wrapPullError } from './wrap.ts';\n\n// -----------------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------------\n\nconst SNAPSHOT_TEMP_TAG_PREFIX = 'devstack-snapshot:';\n\nconst isSnapshotTempTag = (ref: string): boolean => ref.startsWith(SNAPSHOT_TEMP_TAG_PREFIX);\n\nconst cleanupSnapshotTempTag = (\n\tref: string,\n): Effect.Effect<void, never, DockerHost | DockerSpawner> => {\n\tif (!isSnapshotTempTag(ref)) return Effect.void;\n\treturn dockerRunOk('image', ['rm', ref]).pipe(\n\t\tEffect.catch(() => Effect.void),\n\t\tEffect.asVoid,\n\t);\n};\n\nexport interface SaveImageOptions {\n\treadonly removeAfterSave?: boolean;\n}\n\nexport interface TagImageOptions {\n\treadonly removeSourceAfterTag?: boolean;\n}\n\n/** Encode/decode the cache entry — we store the resolved image digest\n * as plain UTF-8 bytes so the cache primitive's byte shape works. */\nconst encodeDigest = (digest: string): Uint8Array =>\n\tnew TextEncoder().encode(JSON.stringify({ digest } satisfies { digest: string }));\n\nconst DigestDoc = Schema.Struct({ digest: Schema.String });\n\nconst decodeDigest = (bytes: Uint8Array): string | null => {\n\ttry {\n\t\treturn decodeJsonTextSync(DigestDoc, new TextDecoder().decode(bytes), {\n\t\t\tsource: 'docker image digest cache',\n\t\t\tmkError: (issue) => issue,\n\t\t}).digest;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Exists / inspect\n// -----------------------------------------------------------------------------\n\n/** `docker image inspect <ref>` — returns the digest, or null on miss. */\nexport const imageExists = (\n\tref: string,\n): Effect.Effect<string | null, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('image', ['inspect', '--format', '{{.Id}}', ref]).pipe(\n\t\t\tEffect.mapError(wrapGeneric('docker.image.inspect')),\n\t\t);\n\t\tif (res.exitCode !== 0) return null;\n\t\tconst id = res.stdout.trim();\n\t\treturn id.length > 0 ? id : null;\n\t}).pipe(Effect.withSpan('runtime.docker.image.exists'));\n\n/** Strict variant — surfaces `ImageNotFound` if the inspect misses. */\nexport const inspectDigest = (\n\tref: string,\n): Effect.Effect<string, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst id = yield* imageExists(ref);\n\t\tif (id === null) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew ImageNotFound({ ref, detail: 'docker image inspect returned empty' }),\n\t\t\t);\n\t\t}\n\t\treturn id;\n\t}).pipe(Effect.withSpan('runtime.docker.image.inspectDigest'));\n\n// -----------------------------------------------------------------------------\n// Pull\n// -----------------------------------------------------------------------------\n\n/** `docker pull <ref>` — surfaces ImageNotFound / ImagePullFailed.\n * Per-line progress emission opt-in via `onLine`. */\nexport const pull = (\n\tref: string,\n\tonLine?: (line: string) => Effect.Effect<void>,\n): Effect.Effect<string, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tyield* dockerRun('pull', [ref], { onStdoutLine: onLine }).pipe(\n\t\t\tEffect.mapError(wrapPullError(ref)),\n\t\t);\n\t\treturn yield* inspectDigest(ref);\n\t}).pipe(Effect.withSpan('runtime.docker.image.pull'));\n\n// -----------------------------------------------------------------------------\n// Build (content-addressed)\n// -----------------------------------------------------------------------------\n\nexport interface BuildOptions {\n\treadonly contextPath: string;\n\treadonly dockerfile?: string;\n\treadonly platform?: string;\n\treadonly buildArgs?: Readonly<Record<string, string>>;\n\treadonly tag: string;\n\treadonly onLine?: (line: string) => Effect.Effect<void>;\n}\n\n/** `docker build -t <tag> [-f Dockerfile] <ctx>`. On exit-0 the\n * resulting tag is on-host; we read its digest and return.\n *\n * NOTE: the content-addressed cache integration is in `ensureImageCached`\n * below — this verb is the unconditional build, used when the cache\n * has missed AND the on-host tag-exists probe also missed. */\nexport const build = (\n\topts: BuildOptions,\n): Effect.Effect<string, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst args: Array<string> = ['-t', opts.tag];\n\t\tif (opts.platform !== undefined) {\n\t\t\targs.push('--platform', opts.platform);\n\t\t}\n\t\t// `-f` is resolved relative to the docker CLI's CWD, NOT the\n\t\t// context directory. Skip `-f` entirely when the dockerfile is\n\t\t// the canonical default name (`Dockerfile`) and the context is a\n\t\t// directory — docker buildx then auto-discovers `<ctx>/Dockerfile`.\n\t\t// When the user names a non-default dockerfile, resolve it against\n\t\t// the context so `docker build -f a/b/Dockerfile.x .` works\n\t\t// regardless of CWD.\n\t\tif (opts.dockerfile && opts.dockerfile !== 'Dockerfile') {\n\t\t\tconst isAbs = opts.dockerfile.startsWith('/') || /^[A-Za-z]:/.test(opts.dockerfile);\n\t\t\tconst resolved = isAbs\n\t\t\t\t? opts.dockerfile\n\t\t\t\t: `${opts.contextPath.replace(/\\/$/, '')}/${opts.dockerfile}`;\n\t\t\targs.push('-f', resolved);\n\t\t}\n\t\tif (opts.buildArgs) {\n\t\t\tfor (const [k, v] of Object.entries(opts.buildArgs)) {\n\t\t\t\targs.push('--build-arg', `${k}=${v}`);\n\t\t\t}\n\t\t}\n\t\targs.push(opts.contextPath);\n\t\tyield* dockerRun('build', args, {\n\t\t\tonStdoutLine: opts.onLine,\n\t\t\tonStderrLine: opts.onLine,\n\t\t}).pipe(Effect.mapError(wrapBuildError(opts.contextPath, opts.dockerfile)));\n\t\treturn yield* inspectDigest(opts.tag);\n\t}).pipe(Effect.withSpan('runtime.docker.image.build'));\n\n// -----------------------------------------------------------------------------\n// Tag\n// -----------------------------------------------------------------------------\n\n/** `docker tag <src> <dst>` — used by snapshot restore to alias a\n * loaded image back to its original tag. */\nexport const tagImage = (\n\tsrc: string,\n\tdst: string,\n\topts: TagImageOptions = {},\n): Effect.Effect<void, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('tag', [src, dst]).pipe(\n\t\t\tEffect.mapError(wrapGeneric('docker.tag')),\n\t\t);\n\t\tif (res.exitCode !== 0) {\n\t\t\tif (isImageNotFoundStderr(res.stderr)) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\tnew ImageNotFound({ ref: src, detail: `tag source missing: ${res.stderr}` }),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn yield* Effect.fail(new ImageTagFailed({ src, dst, stderr: res.stderr }));\n\t\t}\n\t\tif (opts.removeSourceAfterTag === true && src !== dst) {\n\t\t\tyield* cleanupSnapshotTempTag(src);\n\t\t}\n\t}).pipe(Effect.withSpan('runtime.docker.image.tag'));\n\nconst isMissingImageStderr = (stderr: string): boolean =>\n\t/no such image|not found|reference does not exist/i.test(stderr);\n\nexport const removeImage = (\n\tref: string,\n): Effect.Effect<void, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('image', ['rm', '-f', ref]).pipe(\n\t\t\tEffect.mapError(wrapGeneric('docker.image.rm')),\n\t\t);\n\t\tif (res.exitCode === 0 || isMissingImageStderr(res.stderr)) return;\n\t\treturn yield* Effect.fail(\n\t\t\tnew ImageRemoveFailed({\n\t\t\t\tref,\n\t\t\t\tstderr: res.stderr,\n\t\t\t\texitCode: res.exitCode,\n\t\t\t}),\n\t\t);\n\t}).pipe(Effect.withSpan('runtime.docker.image.remove'));\n\n// -----------------------------------------------------------------------------\n// Save (image → tar stream)\n// -----------------------------------------------------------------------------\n\n/** Stream the bytes of `docker save <ref>` to the consumer. Stdout\n * stays streaming so large images never materialise in memory; stderr\n * and exit are drained concurrently so a missing image cannot look\n * like a successful empty tar. */\nexport const saveImages = (\n\trefs: ReadonlyArray<string>,\n\topts: SaveImageOptions = {},\n): Stream.Stream<Uint8Array, DockerRuntimeError, DockerHost | DockerSpawner> => {\n\tconst mapSpawnError = (cause: unknown): DockerRuntimeError =>\n\t\tnew ImageSaveFailed({\n\t\t\tref: refs.join(' '),\n\t\t\tdetail:\n\t\t\t\trefs.length === 0 ? 'docker save called with no image refs' : 'docker save spawn failed',\n\t\t\tcause,\n\t\t});\n\tif (refs.length === 0) {\n\t\treturn Stream.fail(mapSpawnError(new Error('empty docker save ref list')));\n\t}\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, 'save', refs);\n\t\t\tconst handle = yield* spawner.spawn(cmd).pipe(Effect.mapError(mapSpawnError));\n\t\t\tconst stderrFiber = yield* Effect.forkChild(\n\t\t\t\tStream.mkString(Stream.decodeText(handle.stderr)).pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause): DockerRuntimeError =>\n\t\t\t\t\t\t\tnew ImageSaveFailed({\n\t\t\t\t\t\t\t\tref: refs.join(' '),\n\t\t\t\t\t\t\t\tdetail: 'docker save stderr drain failed',\n\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst exitFiber = yield* Effect.forkChild(\n\t\t\t\thandle.exitCode.pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause): DockerRuntimeError =>\n\t\t\t\t\t\t\tnew ImageSaveFailed({\n\t\t\t\t\t\t\t\tref: refs.join(' '),\n\t\t\t\t\t\t\t\tdetail: 'docker save exit failed',\n\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst checkExit = Effect.gen(function* () {\n\t\t\t\tconst [stderrText, exitCode] = yield* Effect.all(\n\t\t\t\t\t[Fiber.join(stderrFiber), Fiber.join(exitFiber)] as const,\n\t\t\t\t\t{ concurrency: 'unbounded' },\n\t\t\t\t);\n\t\t\t\tif (exitCode !== 0) {\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\tnew ImageSaveFailed({\n\t\t\t\t\t\t\tref: refs.join(' '),\n\t\t\t\t\t\t\tdetail: `docker save exited ${exitCode}${\n\t\t\t\t\t\t\t\tstderrText.length > 0 ? `: ${stderrText}` : ''\n\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst cleanupTag =\n\t\t\t\topts.removeAfterSave === true\n\t\t\t\t\t? Effect.forEach(refs, cleanupSnapshotTempTag, { concurrency: 'unbounded' }).pipe(\n\t\t\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\t\t)\n\t\t\t\t\t: Effect.void;\n\t\t\tconst cleanup = Effect.all(\n\t\t\t\t[cleanupTag, Fiber.interrupt(stderrFiber), Fiber.interrupt(exitFiber)],\n\t\t\t\t{ concurrency: 'unbounded' },\n\t\t\t).pipe(Effect.asVoid);\n\t\t\treturn handle.stdout.pipe(\n\t\t\t\tStream.mapError(\n\t\t\t\t\t(cause): DockerRuntimeError =>\n\t\t\t\t\t\tnew ImageSaveFailed({\n\t\t\t\t\t\t\tref: refs.join(' '),\n\t\t\t\t\t\t\tdetail: 'docker save stdout pipe failed',\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tStream.onEnd(checkExit),\n\t\t\t\tStream.ensuring(cleanup),\n\t\t\t);\n\t\t}),\n\t);\n};\n\nexport const saveImage = (\n\tref: string,\n\topts: SaveImageOptions = {},\n): Stream.Stream<Uint8Array, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tsaveImages([ref], opts);\n\n// -----------------------------------------------------------------------------\n// Load (tar stream → image)\n// -----------------------------------------------------------------------------\n\n/** Parse `docker load` stdout lines to extract the loaded image refs.\n * Docker's output is one of:\n * - `Loaded image: <tag>`\n * - `Loaded image ID: sha256:<digest>`\n * Exported for direct testing without a docker dependency. */\nexport const parseLoadedRefs = (\n\tstdout: string,\n): ReadonlyArray<{ readonly tag?: string; readonly digest?: string }> => {\n\tconst refs: Array<{ tag?: string; digest?: string }> = [];\n\tfor (const rawLine of stdout.split(/\\r?\\n/)) {\n\t\tconst line = rawLine.trim();\n\t\tconst taggedMatch = /^Loaded image: (\\S+)$/.exec(line);\n\t\tif (taggedMatch?.[1]) {\n\t\t\trefs.push({ tag: taggedMatch[1] });\n\t\t\tcontinue;\n\t\t}\n\t\tconst digestMatch = /^Loaded image ID: (sha256:\\S+)$/.exec(line);\n\t\tif (digestMatch?.[1]) {\n\t\t\trefs.push({ digest: digestMatch[1] });\n\t\t}\n\t}\n\treturn refs;\n};\n\n/** `docker load < <tar-stream>`. Returns every freshly-loaded ref\n * Docker reported on stdout. Symmetric with `saveImage`/`saveImages`.\n * Upstream stream errors (e.g. file-read failures from a snapshot\n * tar) are projected to `ImageLoadFailed` so callers see one shape.\n *\n * Stdin lifetime: the supplied stream is fed in via the spawner's\n * `stdin` sink under the same scope as the spawn itself; both close\n * when the child exits. */\nexport const loadImage = (\n\ttar: Stream.Stream<Uint8Array, unknown>,\n): Effect.Effect<LoadedImageBundle, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst host = yield* DockerHost;\n\t\tconst spawner = yield* DockerSpawner;\n\t\tconst cmd = dockerCommand(host, 'load', []);\n\t\tconst mapSpawnError = (cause: unknown): DockerRuntimeError =>\n\t\t\tnew ImageLoadFailed({ detail: 'docker load spawn failed', cause });\n\t\treturn yield* Effect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst handle = yield* spawner.spawn(cmd).pipe(Effect.mapError(mapSpawnError));\n\t\t\t\t// Concurrently:\n\t\t\t\t// - pump the supplied tar into stdin\n\t\t\t\t// - drain stdout (the \"Loaded image: …\" lines)\n\t\t\t\t// - drain stderr\n\t\t\t\t// - wait for exit\n\t\t\t\tconst writeStdin = Stream.run(tar, handle.stdin).pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause: unknown): DockerRuntimeError =>\n\t\t\t\t\t\t\tnew ImageLoadFailed({ detail: 'docker load stdin pipe failed', cause }),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tconst stdoutDrain = Stream.mkString(Stream.decodeText(handle.stdout)).pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause): DockerRuntimeError =>\n\t\t\t\t\t\t\tnew ImageLoadFailed({ detail: 'docker load stdout drain failed', cause }),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tconst stderrDrain = Stream.mkString(Stream.decodeText(handle.stderr)).pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause): DockerRuntimeError =>\n\t\t\t\t\t\t\tnew ImageLoadFailed({ detail: 'docker load stderr drain failed', cause }),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tconst exit = handle.exitCode.pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause): DockerRuntimeError =>\n\t\t\t\t\t\t\tnew ImageLoadFailed({ detail: 'docker load exit failed', cause }),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tconst [, stdoutText, stderrText, exitCode] = yield* Effect.all(\n\t\t\t\t\t[writeStdin, stdoutDrain, stderrDrain, exit] as const,\n\t\t\t\t\t{ concurrency: 'unbounded' },\n\t\t\t\t);\n\t\t\t\tif (exitCode !== 0) {\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\tnew ImageLoadFailed({\n\t\t\t\t\t\t\tdetail: `docker load exited ${exitCode}`,\n\t\t\t\t\t\t\tstderr: stderrText,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst parsed = parseLoadedRefs(stdoutText);\n\t\t\t\tif (parsed.length === 0) {\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\tnew ImageLoadFailed({\n\t\t\t\t\t\t\tdetail: 'docker load succeeded but no Loaded image lines found',\n\t\t\t\t\t\t\tstderr: stdoutText,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst refs = yield* Effect.forEach(\n\t\t\t\t\tparsed,\n\t\t\t\t\t(ref) =>\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tif (ref.digest !== undefined) {\n\t\t\t\t\t\t\t\treturn refOf(ref.digest, ref.tag);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst digest = yield* imageExists(ref.tag!);\n\t\t\t\t\t\t\tif (digest === null) {\n\t\t\t\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\t\t\t\tnew ImageLoadFailed({\n\t\t\t\t\t\t\t\t\t\tdetail: `loaded image '${ref.tag}' not visible to inspect`,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn refOf(digest, ref.tag);\n\t\t\t\t\t\t}),\n\t\t\t\t\t{ concurrency: 'unbounded' },\n\t\t\t\t);\n\t\t\t\treturn { refs };\n\t\t\t}),\n\t\t);\n\t}).pipe(Effect.withSpan('runtime.docker.image.load'));\n\n// -----------------------------------------------------------------------------\n// Cache integration\n// -----------------------------------------------------------------------------\n\nexport interface CachedBuildKey {\n\treadonly namespace: string;\n\treadonly chain: ChainId;\n\treadonly contentHash: ContentHash;\n}\n\n/** Content-addressed image build:\n *\n * 1. cache lookup keyed by (namespace, chainId, contentHash)\n * 2. on hit, verify the on-host tag still resolves; if so return\n * 3. on miss, run `docker build`, then write the resolved digest\n * to the cache (best-effort — write failure does not roll back\n * the on-host build).\n *\n * Caller-supplied tag is the content-addressed name; the cache key\n * is independent so an unrelated invalidation (e.g. base-image\n * bump) can drop the cache without disturbing the tag scheme. */\nexport const ensureImageCached = (\n\topts: BuildOptions,\n\tkey: CachedBuildKey,\n): Effect.Effect<string, DockerRuntimeError, CacheService | DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst cache = yield* CacheService;\n\t\tconst hit = yield* cache\n\t\t\t.lookup({ namespace: key.namespace, chain: key.chain, contentHash: key.contentHash })\n\t\t\t.pipe(\n\t\t\t\t// Cache-side failures collapse to MISS — the contract is\n\t\t\t\t// best-effort. We still build.\n\t\t\t\tEffect.catch(() => Effect.succeed(null)),\n\t\t\t);\n\t\tif (hit !== null) {\n\t\t\tconst cached = decodeDigest(hit.bytes);\n\t\t\tif (cached !== null) {\n\t\t\t\t// Verify the on-host tag still resolves to something —\n\t\t\t\t// the cached digest may have been pruned out from under us.\n\t\t\t\tconst existing = yield* imageExists(opts.tag);\n\t\t\t\tif (existing !== null) {\n\t\t\t\t\treturn existing;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// On-host tag-exists short-circuit (defence-in-depth).\n\t\tconst onHost = yield* imageExists(opts.tag);\n\t\tif (onHost !== null) {\n\t\t\tyield* cache\n\t\t\t\t.write(\n\t\t\t\t\t{ namespace: key.namespace, chain: key.chain, contentHash: key.contentHash },\n\t\t\t\t\tencodeDigest(onHost),\n\t\t\t\t)\n\t\t\t\t.pipe(Effect.catch(() => Effect.void));\n\t\t\treturn onHost;\n\t\t}\n\t\tconst digest = yield* build(opts);\n\t\tyield* cache\n\t\t\t.write(\n\t\t\t\t{ namespace: key.namespace, chain: key.chain, contentHash: key.contentHash },\n\t\t\t\tencodeDigest(digest),\n\t\t\t)\n\t\t\t.pipe(Effect.catch(() => Effect.void));\n\t\treturn digest;\n\t}).pipe(Effect.withSpan('runtime.docker.image.ensureCached'));\n\n// -----------------------------------------------------------------------------\n// Contract-shaped ImageRef helpers\n// -----------------------------------------------------------------------------\n\nexport const refOf = (digest: string, tag?: string): ImageRef =>\n\ttag !== undefined ? { digest, tag } : { digest };\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { ContainerRuntimeService } from "./service.mjs";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { decodeJsonTextSync } from "../../substrate/runtime/runtime-decode.mjs";
|
|
2
|
+
import { dockerRunOk } from "./client.mjs";
|
|
3
|
+
import { LabelKey, renderFilterArgs } from "./labels.mjs";
|
|
4
|
+
import { wrapGeneric } from "./wrap.mjs";
|
|
5
|
+
import { Effect, Schema } from "effect";
|
|
6
|
+
//#region src/runtime/docker/inventory.ts
|
|
7
|
+
const PsLine = Schema.Struct({
|
|
8
|
+
ID: Schema.String,
|
|
9
|
+
Names: Schema.String,
|
|
10
|
+
Image: Schema.String,
|
|
11
|
+
Status: Schema.String,
|
|
12
|
+
State: Schema.String,
|
|
13
|
+
Labels: Schema.optional(Schema.String)
|
|
14
|
+
});
|
|
15
|
+
const ImagesLine = Schema.Struct({
|
|
16
|
+
ID: Schema.String,
|
|
17
|
+
Repository: Schema.String,
|
|
18
|
+
Tag: Schema.String,
|
|
19
|
+
Labels: Schema.optional(Schema.String)
|
|
20
|
+
});
|
|
21
|
+
const NetworksLine = Schema.Struct({
|
|
22
|
+
ID: Schema.String,
|
|
23
|
+
Name: Schema.String,
|
|
24
|
+
Driver: Schema.String,
|
|
25
|
+
Labels: Schema.optional(Schema.String)
|
|
26
|
+
});
|
|
27
|
+
const VolumesLine = Schema.Struct({
|
|
28
|
+
Name: Schema.String,
|
|
29
|
+
Driver: Schema.String,
|
|
30
|
+
Mountpoint: Schema.String,
|
|
31
|
+
Labels: Schema.optional(Schema.String)
|
|
32
|
+
});
|
|
33
|
+
const parseLabelString = (s) => {
|
|
34
|
+
if (!s) return {};
|
|
35
|
+
const out = {};
|
|
36
|
+
for (const part of s.split(",")) {
|
|
37
|
+
const i = part.indexOf("=");
|
|
38
|
+
if (i < 0) continue;
|
|
39
|
+
out[part.slice(0, i).trim()] = part.slice(i + 1).trim();
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
};
|
|
43
|
+
const parseJsonLines = (schema, stdout) => {
|
|
44
|
+
const lines = stdout.split("\n").filter((l) => l.trim().length > 0);
|
|
45
|
+
const out = [];
|
|
46
|
+
for (const [index, line] of lines.entries()) try {
|
|
47
|
+
out.push(decodeJsonTextSync(schema, line, {
|
|
48
|
+
source: `docker inventory:${index + 1}`,
|
|
49
|
+
mkError: (issue) => issue
|
|
50
|
+
}));
|
|
51
|
+
} catch {}
|
|
52
|
+
return out;
|
|
53
|
+
};
|
|
54
|
+
const toContainerSummaries = (stdout) => {
|
|
55
|
+
return parseJsonLines(PsLine, stdout).map((l) => ({
|
|
56
|
+
id: l.ID,
|
|
57
|
+
name: l.Names.split(",")[0] ?? l.Names,
|
|
58
|
+
image: l.Image,
|
|
59
|
+
status: l.Status,
|
|
60
|
+
state: l.State,
|
|
61
|
+
labels: parseLabelString(l.Labels)
|
|
62
|
+
}));
|
|
63
|
+
};
|
|
64
|
+
const toImageSummaries = (stdout) => {
|
|
65
|
+
return parseJsonLines(ImagesLine, stdout).map((l) => ({
|
|
66
|
+
id: l.ID,
|
|
67
|
+
tag: `${l.Repository}:${l.Tag}`,
|
|
68
|
+
labels: parseLabelString(l.Labels)
|
|
69
|
+
}));
|
|
70
|
+
};
|
|
71
|
+
const toNetworkSummaries = (stdout) => {
|
|
72
|
+
return parseJsonLines(NetworksLine, stdout).map((l) => ({
|
|
73
|
+
id: l.ID,
|
|
74
|
+
name: l.Name,
|
|
75
|
+
driver: l.Driver,
|
|
76
|
+
labels: parseLabelString(l.Labels)
|
|
77
|
+
}));
|
|
78
|
+
};
|
|
79
|
+
const toVolumeSummaries = (stdout) => {
|
|
80
|
+
return parseJsonLines(VolumesLine, stdout).map((l) => ({
|
|
81
|
+
name: l.Name,
|
|
82
|
+
driver: l.Driver,
|
|
83
|
+
mountpoint: l.Mountpoint,
|
|
84
|
+
labels: parseLabelString(l.Labels)
|
|
85
|
+
}));
|
|
86
|
+
};
|
|
87
|
+
const devstackAppFilterArgs = ["--filter", `label=${LabelKey.app}`];
|
|
88
|
+
const devstackRouterFilterArgs = [
|
|
89
|
+
"--filter",
|
|
90
|
+
`label=${LabelKey.managed}=true`,
|
|
91
|
+
"--filter",
|
|
92
|
+
`label=${LabelKey.routerMarker}=true`
|
|
93
|
+
];
|
|
94
|
+
const listContainers = (match) => Effect.gen(function* () {
|
|
95
|
+
return toContainerSummaries((yield* dockerRunOk("ps", [
|
|
96
|
+
"-a",
|
|
97
|
+
"--format",
|
|
98
|
+
"{{json .}}",
|
|
99
|
+
...renderFilterArgs(match)
|
|
100
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.ps")))).stdout);
|
|
101
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.containers"));
|
|
102
|
+
const listDevstackContainers = () => Effect.gen(function* () {
|
|
103
|
+
return toContainerSummaries((yield* dockerRunOk("ps", [
|
|
104
|
+
"-a",
|
|
105
|
+
"--format",
|
|
106
|
+
"{{json .}}",
|
|
107
|
+
...devstackAppFilterArgs
|
|
108
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.ps")))).stdout);
|
|
109
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.devstackContainers"));
|
|
110
|
+
const listDevstackRouterContainers = () => Effect.gen(function* () {
|
|
111
|
+
return toContainerSummaries((yield* dockerRunOk("ps", [
|
|
112
|
+
"-a",
|
|
113
|
+
"--format",
|
|
114
|
+
"{{json .}}",
|
|
115
|
+
...devstackRouterFilterArgs
|
|
116
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.ps")))).stdout);
|
|
117
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.devstackRouterContainers"));
|
|
118
|
+
const listImages = (match) => Effect.gen(function* () {
|
|
119
|
+
return toImageSummaries((yield* dockerRunOk("images", [
|
|
120
|
+
"--format",
|
|
121
|
+
"{{json .}}",
|
|
122
|
+
...renderFilterArgs(match)
|
|
123
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.images")))).stdout);
|
|
124
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.images"));
|
|
125
|
+
const listDevstackImages = () => Effect.gen(function* () {
|
|
126
|
+
return toImageSummaries((yield* dockerRunOk("images", [
|
|
127
|
+
"--format",
|
|
128
|
+
"{{json .}}",
|
|
129
|
+
...devstackAppFilterArgs
|
|
130
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.images")))).stdout);
|
|
131
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.devstackImages"));
|
|
132
|
+
const listNetworks = (match) => Effect.gen(function* () {
|
|
133
|
+
return toNetworkSummaries((yield* dockerRunOk("network", [
|
|
134
|
+
"ls",
|
|
135
|
+
"--format",
|
|
136
|
+
"{{json .}}",
|
|
137
|
+
...renderFilterArgs(match)
|
|
138
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.network.ls")))).stdout);
|
|
139
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.networks"));
|
|
140
|
+
const listDevstackNetworks = () => Effect.gen(function* () {
|
|
141
|
+
return toNetworkSummaries((yield* dockerRunOk("network", [
|
|
142
|
+
"ls",
|
|
143
|
+
"--format",
|
|
144
|
+
"{{json .}}",
|
|
145
|
+
...devstackAppFilterArgs
|
|
146
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.network.ls")))).stdout);
|
|
147
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.devstackNetworks"));
|
|
148
|
+
const listVolumes = (match) => Effect.gen(function* () {
|
|
149
|
+
return toVolumeSummaries((yield* dockerRunOk("volume", [
|
|
150
|
+
"ls",
|
|
151
|
+
"--format",
|
|
152
|
+
"{{json .}}",
|
|
153
|
+
...renderFilterArgs(match)
|
|
154
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.volume.ls")))).stdout);
|
|
155
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.volumes"));
|
|
156
|
+
const listDevstackVolumes = () => Effect.gen(function* () {
|
|
157
|
+
return toVolumeSummaries((yield* dockerRunOk("volume", [
|
|
158
|
+
"ls",
|
|
159
|
+
"--format",
|
|
160
|
+
"{{json .}}",
|
|
161
|
+
...devstackAppFilterArgs
|
|
162
|
+
]).pipe(Effect.mapError(wrapGeneric("docker.volume.ls")))).stdout);
|
|
163
|
+
}).pipe(Effect.withSpan("runtime.docker.inventory.devstackVolumes"));
|
|
164
|
+
//#endregion
|
|
165
|
+
export { listContainers, listDevstackContainers, listDevstackImages, listDevstackNetworks, listDevstackRouterContainers, listDevstackVolumes, listImages, listNetworks, listVolumes };
|
|
166
|
+
|
|
167
|
+
//# sourceMappingURL=inventory.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.mjs","names":[],"sources":["../../../src/runtime/docker/inventory.ts"],"sourcesContent":["// Label-driven inventory.\n//\n// Architecture § Container runtime § Label-driven inventory:\n// inventory NEVER greps stdout for container names; it ALWAYS\n// filters by labels via `--filter label=...`. The output format is\n// the `--format` JSON line shape, which we parse line-by-line.\n//\n// Surface:\n// - `listContainers(match)` → ContainerSummary[]\n// - `listImages(match)` → ImageSummary[]\n// - `listNetworks(match)` → NetworkSummary[]\n// - `listVolumes(match)` → VolumeSummary[]\n\nimport { Effect, Schema } from 'effect';\n\nimport type { ContainerLabelTuple } from '../../contracts/snapshotable.ts';\nimport { decodeJsonTextSync } from '../../substrate/runtime/runtime-decode.ts';\nimport { DockerHost, DockerSpawner, dockerRunOk } from './client.ts';\nimport type { DockerRuntimeError } from './errors.ts';\nimport { LabelKey, renderFilterArgs } from './labels.ts';\nimport { wrapGeneric } from './wrap.ts';\n\n// -----------------------------------------------------------------------------\n// Summary shapes — what the label-filter listers return\n// -----------------------------------------------------------------------------\n\nexport interface ContainerSummary {\n\treadonly id: string;\n\treadonly name: string;\n\treadonly image: string;\n\treadonly status: string;\n\treadonly state: string;\n\treadonly labels: Readonly<Record<string, string>>;\n}\n\nexport interface ImageSummary {\n\treadonly id: string;\n\treadonly tag: string;\n\treadonly labels: Readonly<Record<string, string>>;\n}\n\nexport interface NetworkSummary {\n\treadonly id: string;\n\treadonly name: string;\n\treadonly driver: string;\n\treadonly labels: Readonly<Record<string, string>>;\n}\n\nexport interface VolumeSummary {\n\treadonly name: string;\n\treadonly driver: string;\n\treadonly mountpoint: string;\n\treadonly labels: Readonly<Record<string, string>>;\n}\n\n// -----------------------------------------------------------------------------\n// JSON-line schemas (docker --format '{{json .}}')\n// -----------------------------------------------------------------------------\n\nconst PsLine = Schema.Struct({\n\tID: Schema.String,\n\tNames: Schema.String,\n\tImage: Schema.String,\n\tStatus: Schema.String,\n\tState: Schema.String,\n\tLabels: Schema.optional(Schema.String),\n});\n\nconst ImagesLine = Schema.Struct({\n\tID: Schema.String,\n\tRepository: Schema.String,\n\tTag: Schema.String,\n\tLabels: Schema.optional(Schema.String),\n});\n\nconst NetworksLine = Schema.Struct({\n\tID: Schema.String,\n\tName: Schema.String,\n\tDriver: Schema.String,\n\tLabels: Schema.optional(Schema.String),\n});\n\nconst VolumesLine = Schema.Struct({\n\tName: Schema.String,\n\tDriver: Schema.String,\n\tMountpoint: Schema.String,\n\tLabels: Schema.optional(Schema.String),\n});\n\n// -----------------------------------------------------------------------------\n// Label parsing — docker's `Labels` field is a comma-joined `k=v,k=v`\n// -----------------------------------------------------------------------------\n\nconst parseLabelString = (s: string | undefined): Record<string, string> => {\n\tif (!s) return {};\n\tconst out: Record<string, string> = {};\n\tfor (const part of s.split(',')) {\n\t\tconst i = part.indexOf('=');\n\t\tif (i < 0) continue;\n\t\tout[part.slice(0, i).trim()] = part.slice(i + 1).trim();\n\t}\n\treturn out;\n};\n\nconst parseJsonLines = <S extends Schema.Decoder<unknown>>(\n\tschema: S,\n\tstdout: string,\n): ReadonlyArray<S['Type']> => {\n\tconst lines = stdout.split('\\n').filter((l) => l.trim().length > 0);\n\tconst out: Array<S['Type']> = [];\n\tfor (const [index, line] of lines.entries()) {\n\t\ttry {\n\t\t\tout.push(\n\t\t\t\tdecodeJsonTextSync(schema, line, {\n\t\t\t\t\tsource: `docker inventory:${index + 1}`,\n\t\t\t\t\tmkError: (issue) => issue,\n\t\t\t\t}),\n\t\t\t);\n\t\t} catch {\n\t\t\t// Malformed line — skip. Inventory is best-effort; a single\n\t\t\t// torn line shouldn't poison the whole sweep.\n\t\t}\n\t}\n\treturn out;\n};\n\n// -----------------------------------------------------------------------------\n// Listers\n// -----------------------------------------------------------------------------\n\nconst toContainerSummaries = (stdout: string): ReadonlyArray<ContainerSummary> => {\n\tconst lines = parseJsonLines(PsLine, stdout);\n\treturn lines.map(\n\t\t(l): ContainerSummary => ({\n\t\t\tid: l.ID,\n\t\t\tname: l.Names.split(',')[0] ?? l.Names,\n\t\t\timage: l.Image,\n\t\t\tstatus: l.Status,\n\t\t\tstate: l.State,\n\t\t\tlabels: parseLabelString(l.Labels),\n\t\t}),\n\t);\n};\n\nconst toImageSummaries = (stdout: string): ReadonlyArray<ImageSummary> => {\n\tconst lines = parseJsonLines(ImagesLine, stdout);\n\treturn lines.map(\n\t\t(l): ImageSummary => ({\n\t\t\tid: l.ID,\n\t\t\ttag: `${l.Repository}:${l.Tag}`,\n\t\t\tlabels: parseLabelString(l.Labels),\n\t\t}),\n\t);\n};\n\nconst toNetworkSummaries = (stdout: string): ReadonlyArray<NetworkSummary> => {\n\tconst lines = parseJsonLines(NetworksLine, stdout);\n\treturn lines.map(\n\t\t(l): NetworkSummary => ({\n\t\t\tid: l.ID,\n\t\t\tname: l.Name,\n\t\t\tdriver: l.Driver,\n\t\t\tlabels: parseLabelString(l.Labels),\n\t\t}),\n\t);\n};\n\nconst toVolumeSummaries = (stdout: string): ReadonlyArray<VolumeSummary> => {\n\tconst lines = parseJsonLines(VolumesLine, stdout);\n\treturn lines.map(\n\t\t(l): VolumeSummary => ({\n\t\t\tname: l.Name,\n\t\t\tdriver: l.Driver,\n\t\t\tmountpoint: l.Mountpoint,\n\t\t\tlabels: parseLabelString(l.Labels),\n\t\t}),\n\t);\n};\n\nconst devstackAppFilterArgs: ReadonlyArray<string> = ['--filter', `label=${LabelKey.app}`];\nconst devstackRouterFilterArgs: ReadonlyArray<string> = [\n\t'--filter',\n\t`label=${LabelKey.managed}=true`,\n\t'--filter',\n\t`label=${LabelKey.routerMarker}=true`,\n];\n\nexport const listContainers = (\n\tmatch: Partial<ContainerLabelTuple>,\n): Effect.Effect<ReadonlyArray<ContainerSummary>, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst filters = renderFilterArgs(match);\n\t\tconst res = yield* dockerRunOk('ps', ['-a', '--format', '{{json .}}', ...filters]).pipe(\n\t\t\tEffect.mapError(wrapGeneric('docker.ps')),\n\t\t);\n\t\treturn toContainerSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.containers'));\n\nexport const listDevstackContainers = (): Effect.Effect<\n\tReadonlyArray<ContainerSummary>,\n\tDockerRuntimeError,\n\tDockerHost | DockerSpawner\n> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('ps', [\n\t\t\t'-a',\n\t\t\t'--format',\n\t\t\t'{{json .}}',\n\t\t\t...devstackAppFilterArgs,\n\t\t]).pipe(Effect.mapError(wrapGeneric('docker.ps')));\n\t\treturn toContainerSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.devstackContainers'));\n\nexport const listDevstackRouterContainers = (): Effect.Effect<\n\tReadonlyArray<ContainerSummary>,\n\tDockerRuntimeError,\n\tDockerHost | DockerSpawner\n> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('ps', [\n\t\t\t'-a',\n\t\t\t'--format',\n\t\t\t'{{json .}}',\n\t\t\t...devstackRouterFilterArgs,\n\t\t]).pipe(Effect.mapError(wrapGeneric('docker.ps')));\n\t\treturn toContainerSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.devstackRouterContainers'));\n\nexport const listImages = (\n\tmatch: Partial<ContainerLabelTuple>,\n): Effect.Effect<ReadonlyArray<ImageSummary>, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst filters = renderFilterArgs(match);\n\t\tconst res = yield* dockerRunOk('images', ['--format', '{{json .}}', ...filters]).pipe(\n\t\t\tEffect.mapError(wrapGeneric('docker.images')),\n\t\t);\n\t\treturn toImageSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.images'));\n\nexport const listDevstackImages = (): Effect.Effect<\n\tReadonlyArray<ImageSummary>,\n\tDockerRuntimeError,\n\tDockerHost | DockerSpawner\n> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('images', [\n\t\t\t'--format',\n\t\t\t'{{json .}}',\n\t\t\t...devstackAppFilterArgs,\n\t\t]).pipe(Effect.mapError(wrapGeneric('docker.images')));\n\t\treturn toImageSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.devstackImages'));\n\nexport const listNetworks = (\n\tmatch: Partial<ContainerLabelTuple>,\n): Effect.Effect<ReadonlyArray<NetworkSummary>, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst filters = renderFilterArgs(match);\n\t\tconst res = yield* dockerRunOk('network', ['ls', '--format', '{{json .}}', ...filters]).pipe(\n\t\t\tEffect.mapError(wrapGeneric('docker.network.ls')),\n\t\t);\n\t\treturn toNetworkSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.networks'));\n\nexport const listDevstackNetworks = (): Effect.Effect<\n\tReadonlyArray<NetworkSummary>,\n\tDockerRuntimeError,\n\tDockerHost | DockerSpawner\n> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('network', [\n\t\t\t'ls',\n\t\t\t'--format',\n\t\t\t'{{json .}}',\n\t\t\t...devstackAppFilterArgs,\n\t\t]).pipe(Effect.mapError(wrapGeneric('docker.network.ls')));\n\t\treturn toNetworkSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.devstackNetworks'));\n\nexport const listVolumes = (\n\tmatch: Partial<ContainerLabelTuple>,\n): Effect.Effect<ReadonlyArray<VolumeSummary>, DockerRuntimeError, DockerHost | DockerSpawner> =>\n\tEffect.gen(function* () {\n\t\tconst filters = renderFilterArgs(match);\n\t\tconst res = yield* dockerRunOk('volume', ['ls', '--format', '{{json .}}', ...filters]).pipe(\n\t\t\tEffect.mapError(wrapGeneric('docker.volume.ls')),\n\t\t);\n\t\treturn toVolumeSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.volumes'));\n\nexport const listDevstackVolumes = (): Effect.Effect<\n\tReadonlyArray<VolumeSummary>,\n\tDockerRuntimeError,\n\tDockerHost | DockerSpawner\n> =>\n\tEffect.gen(function* () {\n\t\tconst res = yield* dockerRunOk('volume', [\n\t\t\t'ls',\n\t\t\t'--format',\n\t\t\t'{{json .}}',\n\t\t\t...devstackAppFilterArgs,\n\t\t]).pipe(Effect.mapError(wrapGeneric('docker.volume.ls')));\n\t\treturn toVolumeSummaries(res.stdout);\n\t}).pipe(Effect.withSpan('runtime.docker.inventory.devstackVolumes'));\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//#region src/runtime/docker/labels.ts
|
|
2
|
+
/** Canonical label keys. Single source of truth. */
|
|
3
|
+
const LabelKey = {
|
|
4
|
+
app: "devstack.app",
|
|
5
|
+
stack: "devstack.stack",
|
|
6
|
+
plugin: "devstack.plugin",
|
|
7
|
+
role: "devstack.role",
|
|
8
|
+
cycle: "devstack.cycle",
|
|
9
|
+
configHash: "devstack.config-hash",
|
|
10
|
+
managed: "devstack.managed",
|
|
11
|
+
networkMarker: "devstack.network",
|
|
12
|
+
volumeMarker: "devstack.volume",
|
|
13
|
+
routerMarker: "devstack.router",
|
|
14
|
+
routerProfile: "devstack.router.profile",
|
|
15
|
+
routerSpecVersion: "devstack.router.spec-version"
|
|
16
|
+
};
|
|
17
|
+
/** Docker Compose-compatible labels used only for Docker Desktop grouping.
|
|
18
|
+
* Cleanup and inventory remain keyed by `LabelKey` above. */
|
|
19
|
+
const ComposeLabelKey = {
|
|
20
|
+
project: "com.docker.compose.project",
|
|
21
|
+
service: "com.docker.compose.service",
|
|
22
|
+
containerNumber: "com.docker.compose.container-number",
|
|
23
|
+
version: "com.docker.compose.version",
|
|
24
|
+
oneoff: "com.docker.compose.oneoff",
|
|
25
|
+
network: "com.docker.compose.network",
|
|
26
|
+
volume: "com.docker.compose.volume"
|
|
27
|
+
};
|
|
28
|
+
const COMPOSE_UI_VERSION = "2.0.0";
|
|
29
|
+
const normalizeComposeSegment = (value) => {
|
|
30
|
+
const normalized = value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
31
|
+
return normalized.length > 0 ? normalized : "unnamed";
|
|
32
|
+
};
|
|
33
|
+
const composeProjectId = (app, stack) => `${normalizeComposeSegment(app)}-${normalizeComposeSegment(stack)}`;
|
|
34
|
+
const composeServiceId = (tuple) => `${normalizeComposeSegment(tuple.plugin)}.${normalizeComposeSegment(tuple.role)}`;
|
|
35
|
+
const renderComposeContainerLabels = (tuple) => [
|
|
36
|
+
`${ComposeLabelKey.project}=${composeProjectId(tuple.app, tuple.stack)}`,
|
|
37
|
+
`${ComposeLabelKey.service}=${composeServiceId(tuple)}`,
|
|
38
|
+
`${ComposeLabelKey.containerNumber}=1`,
|
|
39
|
+
`${ComposeLabelKey.version}=${COMPOSE_UI_VERSION}`,
|
|
40
|
+
`${ComposeLabelKey.oneoff}=False`
|
|
41
|
+
];
|
|
42
|
+
const renderComposeNetworkLabels = (name, app, stack) => [
|
|
43
|
+
`${ComposeLabelKey.project}=${composeProjectId(app, stack)}`,
|
|
44
|
+
`${ComposeLabelKey.network}=${name}`,
|
|
45
|
+
`${ComposeLabelKey.version}=${COMPOSE_UI_VERSION}`
|
|
46
|
+
];
|
|
47
|
+
const expectedContainerOwnershipLabels = (tuple) => ({
|
|
48
|
+
[LabelKey.managed]: "true",
|
|
49
|
+
[LabelKey.app]: tuple.app,
|
|
50
|
+
[LabelKey.stack]: tuple.stack,
|
|
51
|
+
[LabelKey.plugin]: tuple.plugin,
|
|
52
|
+
[LabelKey.role]: tuple.role
|
|
53
|
+
});
|
|
54
|
+
const expectedNetworkOwnershipLabels = (app, stack) => ({
|
|
55
|
+
[LabelKey.managed]: "true",
|
|
56
|
+
[LabelKey.networkMarker]: "true",
|
|
57
|
+
[LabelKey.app]: app,
|
|
58
|
+
[LabelKey.stack]: stack
|
|
59
|
+
});
|
|
60
|
+
const ownershipMismatchDetail = (expected, actual) => {
|
|
61
|
+
const mismatches = [];
|
|
62
|
+
for (const [key, expectedValue] of Object.entries(expected)) {
|
|
63
|
+
const actualValue = actual[key];
|
|
64
|
+
if (actualValue !== expectedValue) mismatches.push(`${key}: expected ${expectedValue}, found ${actualValue ?? "<missing>"}`);
|
|
65
|
+
}
|
|
66
|
+
return mismatches.length === 0 ? null : mismatches.join("; ");
|
|
67
|
+
};
|
|
68
|
+
/** Render a `ContainerLabelTuple` to docker `--label key=value` pairs.
|
|
69
|
+
* The cycle/managed labels are stamped at create time by `container.ts`. */
|
|
70
|
+
const renderContainerLabels = (tuple, cycle, extra = {}) => {
|
|
71
|
+
return [...[
|
|
72
|
+
...Object.entries(expectedContainerOwnershipLabels(tuple)).map(([key, value]) => `${key}=${value}`),
|
|
73
|
+
`${LabelKey.cycle}=${cycle}`,
|
|
74
|
+
...Object.entries(extra).map(([key, value]) => `${key}=${value}`)
|
|
75
|
+
], ...renderComposeContainerLabels(tuple)];
|
|
76
|
+
};
|
|
77
|
+
/** Render a label-tuple as `--filter label=key=value` args for `docker ps`,
|
|
78
|
+
* `docker volume ls`, etc. Partial tuples allowed (sweep / inventory). */
|
|
79
|
+
const renderFilterArgs = (match, extra = {}) => {
|
|
80
|
+
const filters = [`label=${LabelKey.managed}=true`];
|
|
81
|
+
if (match.app !== void 0) filters.push(`label=${LabelKey.app}=${match.app}`);
|
|
82
|
+
if (match.stack !== void 0) filters.push(`label=${LabelKey.stack}=${match.stack}`);
|
|
83
|
+
if (match.plugin !== void 0) filters.push(`label=${LabelKey.plugin}=${match.plugin}`);
|
|
84
|
+
if (match.role !== void 0) filters.push(`label=${LabelKey.role}=${match.role}`);
|
|
85
|
+
for (const [k, v] of Object.entries(extra)) filters.push(`label=${k}=${v}`);
|
|
86
|
+
return filters.flatMap((f) => ["--filter", f]);
|
|
87
|
+
};
|
|
88
|
+
/** Network-specific labels (shared `devstack` network is cross-stack;
|
|
89
|
+
* per-stack networks would stamp the full tuple). */
|
|
90
|
+
const renderNetworkLabels = (name, app, stack, opts = {}) => {
|
|
91
|
+
const ownership = Object.entries(expectedNetworkOwnershipLabels(app, stack)).map(([key, value]) => `${key}=${value}`);
|
|
92
|
+
return opts.composeUi === false ? ownership : [...ownership, ...renderComposeNetworkLabels(name, app, stack)];
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
export { ComposeLabelKey, LabelKey, expectedContainerOwnershipLabels, expectedNetworkOwnershipLabels, ownershipMismatchDetail, renderContainerLabels, renderFilterArgs, renderNetworkLabels };
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=labels.mjs.map
|