spawnfile 0.1.13 → 0.1.14
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/README.md +50 -11
- package/dist/audit/auditCli.d.ts +19 -0
- package/dist/audit/auditCli.js +63 -0
- package/dist/audit/checks.d.ts +100 -0
- package/dist/audit/checks.js +279 -0
- package/dist/audit/checksShared.d.ts +74 -0
- package/dist/audit/checksShared.js +37 -0
- package/dist/audit/generateAudit.d.ts +19 -0
- package/dist/audit/generateAudit.js +122 -0
- package/dist/audit/index.d.ts +4 -0
- package/dist/audit/index.js +4 -0
- package/dist/audit/readAudit.d.ts +50 -0
- package/dist/audit/readAudit.js +59 -0
- package/dist/audit/types.d.ts +40 -0
- package/dist/audit/types.js +8 -0
- package/dist/auth/credentialEnvFile.d.ts +11 -0
- package/dist/auth/credentialEnvFile.js +60 -0
- package/dist/auth/credentialProvisioning.d.ts +15 -0
- package/dist/auth/credentialProvisioning.js +75 -0
- package/dist/auth/credentialProvisioningReceipt.d.ts +28 -0
- package/dist/auth/credentialProvisioningReceipt.js +70 -0
- package/dist/auth/credentialProvisioningRequest.d.ts +51 -0
- package/dist/auth/credentialProvisioningRequest.js +169 -0
- package/dist/auth/credentialWorldBindings.d.ts +21 -0
- package/dist/auth/credentialWorldBindings.js +104 -0
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.js +7 -0
- package/dist/auth/paths.d.ts +11 -0
- package/dist/auth/paths.js +21 -0
- package/dist/auth/targetSecretSourceAuthor.d.ts +18 -0
- package/dist/auth/targetSecretSourceAuthor.js +52 -0
- package/dist/auth/targetSecretSourceFsPublish.d.ts +15 -0
- package/dist/auth/targetSecretSourceFsPublish.js +49 -0
- package/dist/auth/targetSecretSourceFsPublishImmutable.d.ts +16 -0
- package/dist/auth/targetSecretSourceFsPublishImmutable.js +435 -0
- package/dist/auth/targetSecretSourceFsRead.d.ts +14 -0
- package/dist/auth/targetSecretSourceFsRead.js +198 -0
- package/dist/auth/targetSecretSourceGrant.d.ts +16 -0
- package/dist/auth/targetSecretSourceGrant.js +99 -0
- package/dist/auth/targetSecretSourceGrantRecords.d.ts +84 -0
- package/dist/auth/targetSecretSourceGrantRecords.js +214 -0
- package/dist/auth/targetSecretSourceLifecycle.d.ts +30 -0
- package/dist/auth/targetSecretSourceLifecycle.js +52 -0
- package/dist/auth/targetSecretSourceOwnerEntropy.d.ts +6 -0
- package/dist/auth/targetSecretSourceOwnerEntropy.js +28 -0
- package/dist/auth/targetSecretSourceRecordCommon.d.ts +14 -0
- package/dist/auth/targetSecretSourceRecordCommon.js +100 -0
- package/dist/auth/targetSecretSourceRecordPublish.d.ts +10 -0
- package/dist/auth/targetSecretSourceRecordPublish.js +104 -0
- package/dist/auth/targetSecretSourceResolver.d.ts +10 -0
- package/dist/auth/targetSecretSourceResolver.js +137 -0
- package/dist/auth/targetSecretSourceRevoke.d.ts +20 -0
- package/dist/auth/targetSecretSourceRevoke.js +92 -0
- package/dist/auth/targetSecretSourceRotate.d.ts +19 -0
- package/dist/auth/targetSecretSourceRotate.js +121 -0
- package/dist/auth/targetSecretSourceVersionRecords.d.ts +49 -0
- package/dist/auth/targetSecretSourceVersionRecords.js +166 -0
- package/dist/cli/artifactsCommands.d.ts +27 -0
- package/dist/cli/artifactsCommands.js +132 -0
- package/dist/cli/authCommands.d.ts +5 -0
- package/dist/cli/authCommands.js +221 -0
- package/dist/cli/compileBuildCommands.d.ts +3 -0
- package/dist/cli/compileBuildCommands.js +35 -0
- package/dist/cli/containerBundleCommand.d.ts +6 -0
- package/dist/cli/containerBundleCommand.js +116 -0
- package/dist/cli/downCommand.d.ts +25 -0
- package/dist/cli/downCommand.js +134 -0
- package/dist/cli/index.js +6 -3
- package/dist/cli/lifecycleCommands.d.ts +1 -1
- package/dist/cli/lifecycleCommands.js +11 -181
- package/dist/cli/lifecycleMachine.d.ts +19 -0
- package/dist/cli/lifecycleMachine.js +78 -0
- package/dist/cli/lifecyclePlan.d.ts +35 -0
- package/dist/cli/lifecyclePlan.js +240 -0
- package/dist/cli/lifecyclePlanningCommands.d.ts +3 -0
- package/dist/cli/lifecyclePlanningCommands.js +30 -0
- package/dist/cli/runCli.d.ts +9 -2
- package/dist/cli/runCli.js +27 -71
- package/dist/cli/runPublishCommands.d.ts +3 -0
- package/dist/cli/runPublishCommands.js +70 -0
- package/dist/cli/statusCommand.d.ts +3 -33
- package/dist/cli/statusCommand.js +19 -249
- package/dist/cli/statusCommandLive.d.ts +20 -0
- package/dist/cli/statusCommandLive.js +188 -0
- package/dist/cli/statusCommandOptions.d.ts +40 -0
- package/dist/cli/statusCommandOptions.js +42 -0
- package/dist/cli/targetCliRoute.d.ts +2 -0
- package/dist/cli/targetCliRoute.js +30 -0
- package/dist/cli/targetCommands.d.ts +33 -0
- package/dist/cli/targetCommands.js +257 -0
- package/dist/cli/targetComposedPreparationCommand.d.ts +6 -0
- package/dist/cli/targetComposedPreparationCommand.js +39 -0
- package/dist/cli/targetDefaultArtifactAuthority.d.ts +5 -0
- package/dist/cli/targetDefaultArtifactAuthority.js +28 -0
- package/dist/cli/targetDefaultAuthorities.d.ts +53 -0
- package/dist/cli/targetDefaultAuthorities.js +210 -0
- package/dist/cli/targetDefaultConfig.d.ts +68 -0
- package/dist/cli/targetDefaultConfig.js +317 -0
- package/dist/cli/targetDefaultConfigStdin.d.ts +13 -0
- package/dist/cli/targetDefaultConfigStdin.js +215 -0
- package/dist/cli/targetDefaultEnvelope.d.ts +1 -0
- package/dist/cli/targetDefaultEnvelope.js +13 -0
- package/dist/cli/targetDefaultHandlerFactory.d.ts +28 -0
- package/dist/cli/targetDefaultHandlerFactory.js +247 -0
- package/dist/cli/targetDefaultHandlers.d.ts +21 -0
- package/dist/cli/targetDefaultHandlers.js +72 -0
- package/dist/cli/targetDefaultJournalAuthority.d.ts +35 -0
- package/dist/cli/targetDefaultJournalAuthority.js +135 -0
- package/dist/cli/targetDefaultWorldClock.d.ts +4 -0
- package/dist/cli/targetDefaultWorldClock.js +14 -0
- package/dist/cli/targetDefaultWorldQueries.d.ts +5 -0
- package/dist/cli/targetDefaultWorldQueries.js +11 -0
- package/dist/cli/targetDefaultWorldReadiness.d.ts +4 -0
- package/dist/cli/targetDefaultWorldReadiness.js +17 -0
- package/dist/cli/targetEvidenceHelperResolution.d.ts +14 -0
- package/dist/cli/targetEvidenceHelperResolution.js +23 -0
- package/dist/cli/targetLookupCli.d.ts +3 -0
- package/dist/cli/targetLookupCli.js +31 -0
- package/dist/cli/targetLookupCommands.d.ts +12 -0
- package/dist/cli/targetLookupCommands.js +69 -0
- package/dist/cli/targetOperationDispatch.d.ts +58 -0
- package/dist/cli/targetOperationDispatch.js +21 -0
- package/dist/cli/targetReceiptOutput.d.ts +14 -0
- package/dist/cli/targetReceiptOutput.js +21 -0
- package/dist/cli/targetRequestFile.d.ts +14 -0
- package/dist/cli/targetRequestFile.js +63 -0
- package/dist/cli/targetSecretSourceInput.d.ts +28 -0
- package/dist/cli/targetSecretSourceInput.js +121 -0
- package/dist/cli/targetWorldClockCommand.d.ts +10 -0
- package/dist/cli/targetWorldClockCommand.js +42 -0
- package/dist/cli/targetWorldClockCrossProcess.test-helper.d.ts +13 -0
- package/dist/cli/targetWorldClockCrossProcess.test-helper.js +109 -0
- package/dist/cli/targetWorldReadinessCommand.d.ts +10 -0
- package/dist/cli/targetWorldReadinessCommand.js +43 -0
- package/dist/cli/upCommand.d.ts +3 -0
- package/dist/cli/upCommand.js +133 -0
- package/dist/cli/upImageCommand.d.ts +11 -0
- package/dist/cli/upImageCommand.js +41 -0
- package/dist/cli/upLifecycleInvocation.d.ts +41 -0
- package/dist/cli/upLifecycleInvocation.js +48 -0
- package/dist/cli/upLifecycleRecovery.d.ts +4 -0
- package/dist/cli/upLifecycleRecovery.js +53 -0
- package/dist/compiler/agentNodeMerge.d.ts +2 -0
- package/dist/compiler/agentNodeMerge.js +79 -0
- package/dist/compiler/agentSurfaces.js +11 -1
- package/dist/compiler/buildCompilePlan.js +17 -0
- package/dist/compiler/buildCompilePlanAgent.d.ts +11 -0
- package/dist/compiler/buildCompilePlanAgent.js +56 -0
- package/dist/compiler/buildCompilePlanTeams.d.ts +1 -0
- package/dist/compiler/buildCompilePlanTeams.js +4 -1
- package/dist/compiler/buildCompilePlanTraversal.js +75 -82
- package/dist/compiler/buildProject.d.ts +11 -0
- package/dist/compiler/buildProject.js +77 -2
- package/dist/compiler/compilePlanHelpers.js +2 -0
- package/dist/compiler/compileProject.d.ts +13 -0
- package/dist/compiler/compileProject.js +26 -74
- package/dist/compiler/compileProjectPolicy.d.ts +5 -0
- package/dist/compiler/compileProjectPolicy.js +21 -0
- package/dist/compiler/compileProjectReports.d.ts +9 -0
- package/dist/compiler/compileProjectReports.js +52 -0
- package/dist/compiler/containerArtifactSummaries.d.ts +7 -0
- package/dist/compiler/containerArtifactSummaries.js +138 -0
- package/dist/compiler/containerArtifacts.d.ts +10 -0
- package/dist/compiler/containerArtifacts.js +126 -125
- package/dist/compiler/containerArtifactsPlans.d.ts +5 -3
- package/dist/compiler/containerArtifactsPlans.js +31 -118
- package/dist/compiler/containerArtifactsRender.d.ts +3 -1
- package/dist/compiler/containerArtifactsRender.js +15 -12
- package/dist/compiler/containerArtifactsTypes.d.ts +12 -0
- package/dist/compiler/containerConfigEnvRender.d.ts +3 -0
- package/dist/compiler/containerConfigEnvRender.js +54 -0
- package/dist/compiler/containerEntrypointRender.d.ts +1 -0
- package/dist/compiler/containerEntrypointRender.js +56 -52
- package/dist/compiler/containerEntrypointShell.d.ts +5 -0
- package/dist/compiler/containerEntrypointShell.js +29 -0
- package/dist/compiler/containerPackageOverrides.d.ts +27 -0
- package/dist/compiler/containerPackageOverrides.js +63 -0
- package/dist/compiler/containerTargetPlanResolution.d.ts +20 -0
- package/dist/compiler/containerTargetPlanResolution.js +97 -0
- package/dist/compiler/daimonTelemetryArtifacts.d.ts +22 -0
- package/dist/compiler/daimonTelemetryArtifacts.js +61 -0
- package/dist/compiler/dockerBuildContext.d.ts +16 -0
- package/dist/compiler/dockerBuildContext.js +159 -0
- package/dist/compiler/dockerBuildSkip.d.ts +30 -0
- package/dist/compiler/dockerBuildSkip.js +81 -0
- package/dist/compiler/index.d.ts +4 -0
- package/dist/compiler/index.js +4 -0
- package/dist/compiler/memoryArtifacts.d.ts +26 -0
- package/dist/compiler/memoryArtifacts.js +134 -0
- package/dist/compiler/memoryResolution.d.ts +4 -0
- package/dist/compiler/memoryResolution.js +147 -0
- package/dist/compiler/modelEnv.d.ts +2 -0
- package/dist/compiler/modelEnv.js +6 -0
- package/dist/compiler/moltnetAllowedWakeSendersValidation.d.ts +2 -0
- package/dist/compiler/moltnetAllowedWakeSendersValidation.js +42 -0
- package/dist/compiler/moltnetArtifactPaths.d.ts +26 -0
- package/dist/compiler/moltnetArtifactPaths.js +49 -0
- package/dist/compiler/moltnetArtifactTypes.d.ts +46 -0
- package/dist/compiler/moltnetArtifactTypes.js +1 -0
- package/dist/compiler/moltnetArtifacts.d.ts +2 -40
- package/dist/compiler/moltnetArtifacts.js +43 -97
- package/dist/compiler/moltnetBinaries.d.ts +21 -4
- package/dist/compiler/moltnetBinaries.js +134 -27
- package/dist/compiler/moltnetClientConfig.js +7 -2
- package/dist/compiler/moltnetConfigLowering.d.ts +16 -1
- package/dist/compiler/moltnetConfigLowering.js +67 -5
- package/dist/compiler/moltnetExternalParticipantArtifact.d.ts +38 -0
- package/dist/compiler/moltnetExternalParticipantArtifact.js +188 -0
- package/dist/compiler/moltnetNodeConfig.js +7 -2
- package/dist/compiler/moltnetReleaseAuthority.d.ts +17 -0
- package/dist/compiler/moltnetReleaseAuthority.js +73 -0
- package/dist/compiler/moltnetReleaseDownload.d.ts +12 -0
- package/dist/compiler/moltnetReleaseDownload.js +85 -0
- package/dist/compiler/moltnetRepresentativeResolution.d.ts +1 -0
- package/dist/compiler/moltnetRepresentativeResolution.js +16 -2
- package/dist/compiler/moltnetResolution.js +72 -20
- package/dist/compiler/moltnetRoomMemberships.js +37 -9
- package/dist/compiler/moltnetServerPlans.d.ts +9 -0
- package/dist/compiler/moltnetServerPlans.js +132 -0
- package/dist/compiler/organizationIdentity.d.ts +27 -0
- package/dist/compiler/organizationIdentity.js +297 -0
- package/dist/compiler/organizationReadyEvidence.d.ts +49 -0
- package/dist/compiler/organizationReadyEvidence.js +261 -0
- package/dist/compiler/projectManifestGraph.d.ts +4 -0
- package/dist/compiler/projectManifestGraph.js +24 -0
- package/dist/compiler/runProject.d.ts +4 -0
- package/dist/compiler/runProject.js +30 -21
- package/dist/compiler/runProjectAuth.d.ts +7 -1
- package/dist/compiler/runProjectAuth.js +87 -9
- package/dist/compiler/runProjectDocker.d.ts +7 -0
- package/dist/compiler/runProjectDocker.js +31 -8
- package/dist/compiler/runProjectLifecycle.d.ts +7 -0
- package/dist/compiler/runProjectLifecycle.js +40 -0
- package/dist/compiler/syncProjectAuth.js +4 -1
- package/dist/compiler/teamContextActiveEnvironments.d.ts +13 -0
- package/dist/compiler/teamContextActiveEnvironments.js +255 -0
- package/dist/compiler/teamContextSupport.js +32 -40
- package/dist/compiler/teamContextTypes.d.ts +2 -0
- package/dist/compiler/types.d.ts +82 -1
- package/dist/compiler/upProject.d.ts +5 -0
- package/dist/compiler/upProject.js +256 -20
- package/dist/compiler/upReceipt.d.ts +36 -0
- package/dist/compiler/upReceipt.js +82 -0
- package/dist/compiler/updateProjectModels.js +42 -60
- package/dist/compiler/updateProjectRuntime.js +22 -35
- package/dist/compiler/updateProjectSurfaces.js +53 -47
- package/dist/compiler/worldBindings.d.ts +39 -0
- package/dist/compiler/worldBindings.js +247 -0
- package/dist/compiler/worldBindingsFile.d.ts +5 -0
- package/dist/compiler/worldBindingsFile.js +162 -0
- package/dist/deployment/artifactsExport.d.ts +49 -0
- package/dist/deployment/artifactsExport.js +217 -0
- package/dist/deployment/artifactsExportDocker.d.ts +48 -0
- package/dist/deployment/artifactsExportDocker.js +91 -0
- package/dist/deployment/artifactsExportPlan.d.ts +24 -0
- package/dist/deployment/artifactsExportPlan.js +135 -0
- package/dist/deployment/artifactsExportTypes.d.ts +50 -0
- package/dist/deployment/artifactsExportTypes.js +52 -0
- package/dist/deployment/buildImageCacheStore.d.ts +23 -0
- package/dist/deployment/buildImageCacheStore.js +54 -0
- package/dist/deployment/deploymentLifecycleCorrelation.d.ts +11 -0
- package/dist/deployment/deploymentLifecycleCorrelation.js +33 -0
- package/dist/deployment/dockerInspect.d.ts +9 -0
- package/dist/deployment/dockerInspect.js +24 -1
- package/dist/deployment/dockerLabels.d.ts +2 -0
- package/dist/deployment/dockerLabels.js +2 -0
- package/dist/deployment/dockerLogs.js +2 -10
- package/dist/deployment/dockerManager.d.ts +51 -0
- package/dist/deployment/dockerManager.js +118 -1
- package/dist/deployment/dockerProbeGateway.js +64 -5
- package/dist/deployment/dockerRecover.js +9 -1
- package/dist/deployment/dockerTeardown.d.ts +32 -0
- package/dist/deployment/dockerTeardown.js +61 -0
- package/dist/deployment/downDeployment.d.ts +34 -0
- package/dist/deployment/downDeployment.js +147 -0
- package/dist/deployment/downReceiptTypes.d.ts +21 -0
- package/dist/deployment/downReceiptTypes.js +30 -0
- package/dist/deployment/index.d.ts +16 -0
- package/dist/deployment/index.js +17 -0
- package/dist/deployment/lifecycleCompletion.d.ts +37 -0
- package/dist/deployment/lifecycleCompletion.js +236 -0
- package/dist/deployment/lifecycleCompletionContracts.d.ts +158 -0
- package/dist/deployment/lifecycleCompletionContracts.js +106 -0
- package/dist/deployment/lifecycleCompletionHeartbeat.d.ts +2 -0
- package/dist/deployment/lifecycleCompletionHeartbeat.js +50 -0
- package/dist/deployment/lifecycleCompletionLookup.d.ts +18 -0
- package/dist/deployment/lifecycleCompletionLookup.js +88 -0
- package/dist/deployment/lifecycleCompletionOwner.d.ts +8 -0
- package/dist/deployment/lifecycleCompletionOwner.js +31 -0
- package/dist/deployment/lifecycleCompletionParsing.d.ts +12 -0
- package/dist/deployment/lifecycleCompletionParsing.js +108 -0
- package/dist/deployment/lifecycleCompletionPaths.d.ts +9 -0
- package/dist/deployment/lifecycleCompletionPaths.js +16 -0
- package/dist/deployment/lifecycleCompletionPublication.d.ts +5 -0
- package/dist/deployment/lifecycleCompletionPublication.js +35 -0
- package/dist/deployment/lifecycleCompletionRecovery.d.ts +21 -0
- package/dist/deployment/lifecycleCompletionRecovery.js +56 -0
- package/dist/deployment/lifecycleCompletionRoot.d.ts +21 -0
- package/dist/deployment/lifecycleCompletionRoot.js +243 -0
- package/dist/deployment/lifecycleCompletionStore.d.ts +6 -0
- package/dist/deployment/lifecycleCompletionStore.js +151 -0
- package/dist/deployment/organizationHandoffAuthorityFsClient.d.ts +17 -0
- package/dist/deployment/organizationHandoffAuthorityFsClient.js +132 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorker.d.ts +1 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorker.js +285 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorkerParent.fixture.d.ts +1 -0
- package/dist/deployment/organizationHandoffAuthorityFsWorkerParent.fixture.js +26 -0
- package/dist/deployment/organizationHandoffAuthorityStore.d.ts +41 -0
- package/dist/deployment/organizationHandoffAuthorityStore.js +348 -0
- package/dist/deployment/organizationHandoffAuthorityTypes.d.ts +76 -0
- package/dist/deployment/organizationHandoffAuthorityTypes.js +148 -0
- package/dist/deployment/organizationHandoffTypes.d.ts +29 -0
- package/dist/deployment/organizationHandoffTypes.js +80 -0
- package/dist/deployment/organizationReady.d.ts +52 -0
- package/dist/deployment/organizationReady.js +200 -0
- package/dist/deployment/privateArtifactsExport.d.ts +18 -0
- package/dist/deployment/privateArtifactsExport.js +80 -0
- package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.d.ts +8 -0
- package/dist/deployment/providerRuntimeBoundaryScanner.test-helper.js +60 -0
- package/dist/deployment/record.d.ts +26 -1
- package/dist/deployment/record.js +49 -4
- package/dist/deployment/simfileFixtureBoundary.test-helper.d.ts +8 -0
- package/dist/deployment/simfileFixtureBoundary.test-helper.js +103 -0
- package/dist/deployment/target.d.ts +1 -35
- package/dist/deployment/target.js +1 -96
- package/dist/deployment/upReceiptTypes.d.ts +111 -0
- package/dist/deployment/upReceiptTypes.js +164 -0
- package/dist/dev/project.js +15 -9
- package/dist/distribution/buildDistributionReport.d.ts +2 -1
- package/dist/distribution/buildDistributionReport.js +2 -1
- package/dist/distribution/distributionReportSchema.d.ts +5 -0
- package/dist/distribution/distributionReportSchema.js +7 -2
- package/dist/distribution/index.d.ts +2 -2
- package/dist/distribution/index.js +1 -1
- package/dist/distribution/types.d.ts +7 -0
- package/dist/distribution/types.js +1 -0
- package/dist/filesystem/paths.js +10 -1
- package/dist/ledger/causalConformanceCli.d.ts +1 -0
- package/dist/ledger/causalConformanceCli.js +41 -0
- package/dist/ledger/causeNamespace.d.ts +8 -0
- package/dist/ledger/causeNamespace.js +24 -0
- package/dist/ledger/conformance.d.ts +83 -0
- package/dist/ledger/conformance.js +259 -0
- package/dist/ledger/emitters.d.ts +76 -0
- package/dist/ledger/emitters.js +188 -0
- package/dist/ledger/index.d.ts +4 -0
- package/dist/ledger/index.js +4 -0
- package/dist/ledger/principal.d.ts +96 -0
- package/dist/ledger/principal.js +121 -0
- package/dist/manifest/externalParticipantSchemas.d.ts +18 -0
- package/dist/manifest/externalParticipantSchemas.js +17 -0
- package/dist/manifest/index.d.ts +1 -0
- package/dist/manifest/index.js +1 -0
- package/dist/manifest/inlineAgentMember.d.ts +2 -0
- package/dist/manifest/inlineAgentMember.js +9 -0
- package/dist/manifest/loadManifest.js +14 -8
- package/dist/manifest/mcpSchemas.d.ts +17 -0
- package/dist/manifest/mcpSchemas.js +41 -0
- package/dist/manifest/memorySchemas.d.ts +245 -0
- package/dist/manifest/memorySchemas.js +148 -0
- package/dist/manifest/renderSpawnfile.js +22 -131
- package/dist/manifest/renderSpawnfileNetworks.js +9 -2
- package/dist/manifest/renderSpawnfileSurfaces.d.ts +2 -0
- package/dist/manifest/renderSpawnfileSurfaces.js +134 -0
- package/dist/manifest/schemas.d.ts +1868 -99
- package/dist/manifest/schemas.js +78 -32
- package/dist/manifest/surfaceSchemas.d.ts +17 -0
- package/dist/manifest/surfaceSchemas.js +24 -1
- package/dist/manifest/teamNetworkAccessSchemas.d.ts +1 -1
- package/dist/manifest/teamNetworkAuthSchemas.d.ts +48 -0
- package/dist/manifest/teamNetworkAuthSchemas.js +103 -0
- package/dist/manifest/teamNetworkSchemas.d.ts +8 -187
- package/dist/manifest/teamNetworkSchemas.js +3 -317
- package/dist/manifest/teamNetworkServerSchemas.d.ts +150 -0
- package/dist/manifest/teamNetworkServerSchemas.js +199 -0
- package/dist/ownership/siblingBuildFreshness.d.ts +20 -0
- package/dist/ownership/siblingBuildFreshness.js +20 -0
- package/dist/ownership/simfileRunOperatorInputs.d.ts +103 -0
- package/dist/ownership/simfileRunOperatorInputs.js +139 -0
- package/dist/report/types.d.ts +142 -0
- package/dist/runtime/common.d.ts +35 -0
- package/dist/runtime/common.js +55 -0
- package/dist/runtime/container.d.ts +28 -1
- package/dist/runtime/container.js +38 -5
- package/dist/runtime/containerPackageOverrides.d.ts +37 -0
- package/dist/runtime/containerPackageOverrides.js +33 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/mnemeMcp.d.ts +15 -0
- package/dist/runtime/mnemeMcp.js +109 -0
- package/dist/runtime/openclaw/adapter.js +15 -4
- package/dist/runtime/openclaw/mcp.d.ts +10 -0
- package/dist/runtime/openclaw/mcp.js +69 -0
- package/dist/runtime/openclaw/runAuth.js +2 -2
- package/dist/runtime/openclaw/scaffold.js +1 -1
- package/dist/runtime/openclaw/schedules.d.ts +38 -0
- package/dist/runtime/openclaw/schedules.js +74 -0
- package/dist/runtime/pi/adapter.d.ts +1 -1
- package/dist/runtime/pi/adapter.js +86 -53
- package/dist/runtime/pi/appActivitySource.js +114 -2
- package/dist/runtime/pi/appAgentConfig.d.ts +11 -0
- package/dist/runtime/pi/appAgentConfig.js +264 -0
- package/dist/runtime/pi/appCliEnginesSource.d.ts +1 -0
- package/dist/runtime/pi/appCliEnginesSource.js +183 -0
- package/dist/runtime/pi/appCliSource.d.ts +1 -0
- package/dist/runtime/pi/appCliSource.js +353 -0
- package/dist/runtime/pi/appControlSource.d.ts +1 -0
- package/dist/runtime/pi/appControlSource.js +390 -0
- package/dist/runtime/pi/appControlWakeIdentitySource.d.ts +1 -0
- package/dist/runtime/pi/appControlWakeIdentitySource.js +19 -0
- package/dist/runtime/pi/appCoreSource.d.ts +4 -1
- package/dist/runtime/pi/appCoreSource.js +104 -214
- package/dist/runtime/pi/appPreludeSource.js +140 -52
- package/dist/runtime/pi/appScheduleSource.d.ts +1 -0
- package/dist/runtime/pi/appScheduleSource.js +80 -0
- package/dist/runtime/pi/appScriptedEngine.d.ts +31 -0
- package/dist/runtime/pi/appScriptedEngine.js +42 -0
- package/dist/runtime/pi/appSource.d.ts +4 -1
- package/dist/runtime/pi/appSource.js +6 -2
- package/dist/runtime/pi/appTemplate.d.ts +8 -22
- package/dist/runtime/pi/appTemplate.js +9 -126
- package/dist/runtime/pi/appTemplateTypes.d.ts +64 -0
- package/dist/runtime/pi/appTemplateTypes.js +18 -0
- package/dist/runtime/pi/appWakeContextSource.d.ts +1 -0
- package/dist/runtime/pi/appWakeContextSource.js +398 -0
- package/dist/runtime/pi/containerTargets.d.ts +4 -0
- package/dist/runtime/pi/containerTargets.js +57 -0
- package/dist/runtime/pi/runAuth.js +126 -9
- package/dist/runtime/pi/testHelpers.d.ts +2 -0
- package/dist/runtime/pi/testHelpers.js +40 -0
- package/dist/runtime/picoclaw/adapter.js +23 -27
- package/dist/runtime/picoclaw/mcp.d.ts +4 -0
- package/dist/runtime/picoclaw/mcp.js +43 -0
- package/dist/runtime/picoclaw/memory.d.ts +7 -0
- package/dist/runtime/picoclaw/memory.js +17 -0
- package/dist/runtime/picoclaw/runAuth.js +1 -1
- package/dist/runtime/picoclaw/scaffold.js +1 -1
- package/dist/runtime/picoclaw/schedules.d.ts +26 -0
- package/dist/runtime/picoclaw/schedules.js +62 -3
- package/dist/runtime/scheduleUtils.d.ts +2 -0
- package/dist/runtime/scheduleUtils.js +15 -0
- package/dist/runtime/types.d.ts +25 -2
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.js +2 -2
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/redaction.d.ts +2 -0
- package/dist/shared/redaction.js +10 -0
- package/dist/status/buildStatus.d.ts +1 -0
- package/dist/status/buildStatus.js +2 -0
- package/dist/status/compileReport.d.ts +22 -0
- package/dist/status/compileReport.js +16 -2
- package/dist/status/compiledProbeCollection.d.ts +21 -0
- package/dist/status/compiledProbeCollection.js +27 -0
- package/dist/status/imageStatusReport.js +6 -0
- package/dist/status/index.d.ts +3 -0
- package/dist/status/index.js +3 -0
- package/dist/status/lifecycleProbes.d.ts +19 -0
- package/dist/status/lifecycleProbes.js +174 -0
- package/dist/status/moltnetProbes.d.ts +7 -8
- package/dist/status/moltnetProbes.js +27 -198
- package/dist/status/moltnetWiringProbes.d.ts +19 -0
- package/dist/status/moltnetWiringProbes.js +178 -0
- package/dist/target/cleanupRun.d.ts +41 -0
- package/dist/target/cleanupRun.js +139 -0
- package/dist/target/cleanupRunDocker.d.ts +16 -0
- package/dist/target/cleanupRunDocker.js +66 -0
- package/dist/target/cleanupRunDocker.test-helper.d.ts +67 -0
- package/dist/target/cleanupRunDocker.test-helper.js +238 -0
- package/dist/target/cleanupRunDockerPreflight.d.ts +17 -0
- package/dist/target/cleanupRunDockerPreflight.js +224 -0
- package/dist/target/composedPreparation.d.ts +205 -0
- package/dist/target/composedPreparation.js +223 -0
- package/dist/target/containerBundle.d.ts +82 -0
- package/dist/target/containerBundle.js +243 -0
- package/dist/target/containerBundleArchive.d.ts +31 -0
- package/dist/target/containerBundleArchive.js +140 -0
- package/dist/target/containerBundleAuthority.d.ts +25 -0
- package/dist/target/containerBundleAuthority.js +65 -0
- package/dist/target/containerBundleContracts.d.ts +114 -0
- package/dist/target/containerBundleContracts.js +173 -0
- package/dist/target/containerBundleFilesystemStore.d.ts +3 -0
- package/dist/target/containerBundleFilesystemStore.js +247 -0
- package/dist/target/containerBundlePolicy.d.ts +33 -0
- package/dist/target/containerBundlePolicy.js +64 -0
- package/dist/target/containerBundleStore.d.ts +127 -0
- package/dist/target/containerBundleStore.js +284 -0
- package/dist/target/contracts.d.ts +538 -0
- package/dist/target/contracts.js +373 -0
- package/dist/target/dockerArtifactIdentityTypes.d.ts +56 -0
- package/dist/target/dockerArtifactIdentityTypes.js +1 -0
- package/dist/target/dockerArtifactInspection.d.ts +40 -0
- package/dist/target/dockerArtifactInspection.js +125 -0
- package/dist/target/dockerArtifacts.d.ts +21 -0
- package/dist/target/dockerArtifacts.js +110 -0
- package/dist/target/dockerArtifactsProvider.d.ts +41 -0
- package/dist/target/dockerArtifactsProvider.js +449 -0
- package/dist/target/dockerCommandExecutor.d.ts +27 -0
- package/dist/target/dockerCommandExecutor.js +200 -0
- package/dist/target/dockerCommandExecutorCore.d.ts +34 -0
- package/dist/target/dockerCommandExecutorCore.js +273 -0
- package/dist/target/dockerContainerBundleBuilder.d.ts +8 -0
- package/dist/target/dockerContainerBundleBuilder.js +256 -0
- package/dist/target/dockerContextSnapshot.d.ts +21 -0
- package/dist/target/dockerContextSnapshot.js +158 -0
- package/dist/target/dockerEndpointFingerprint.d.ts +1 -0
- package/dist/target/dockerEndpointFingerprint.js +9 -0
- package/dist/target/dockerPreparedArtifact.d.ts +48 -0
- package/dist/target/dockerPreparedArtifact.js +131 -0
- package/dist/target/dockerProjectionJson.d.ts +1 -0
- package/dist/target/dockerProjectionJson.js +80 -0
- package/dist/target/dockerPublicArtifactSnapshot.d.ts +17 -0
- package/dist/target/dockerPublicArtifactSnapshot.js +99 -0
- package/dist/target/dockerResources.d.ts +26 -0
- package/dist/target/dockerResources.js +162 -0
- package/dist/target/dockerResourcesProvider.d.ts +44 -0
- package/dist/target/dockerResourcesProvider.js +207 -0
- package/dist/target/dockerSecrets.d.ts +39 -0
- package/dist/target/dockerSecrets.js +249 -0
- package/dist/target/dockerSecretsAuthority.d.ts +26 -0
- package/dist/target/dockerSecretsAuthority.js +216 -0
- package/dist/target/dockerSecretsLifecycle.d.ts +25 -0
- package/dist/target/dockerSecretsLifecycle.js +133 -0
- package/dist/target/dockerSecretsProvider.d.ts +68 -0
- package/dist/target/dockerSecretsProvider.js +329 -0
- package/dist/target/dockerTarget.d.ts +52 -0
- package/dist/target/dockerTarget.js +48 -0
- package/dist/target/dockerTargetBinding.d.ts +14 -0
- package/dist/target/dockerTargetBinding.js +96 -0
- package/dist/target/dockerWorldClock.d.ts +17 -0
- package/dist/target/dockerWorldClock.js +111 -0
- package/dist/target/dockerWorldReadiness.d.ts +17 -0
- package/dist/target/dockerWorldReadiness.js +119 -0
- package/dist/target/dockerWorldService.d.ts +23 -0
- package/dist/target/dockerWorldService.js +216 -0
- package/dist/target/dockerWorldServiceAuthority.d.ts +80 -0
- package/dist/target/dockerWorldServiceAuthority.js +182 -0
- package/dist/target/dockerWorldServiceLifecycle.d.ts +41 -0
- package/dist/target/dockerWorldServiceLifecycle.js +275 -0
- package/dist/target/dockerWorldServiceProvider.d.ts +60 -0
- package/dist/target/dockerWorldServiceProvider.js +318 -0
- package/dist/target/dockerWorldServiceStore.d.ts +73 -0
- package/dist/target/dockerWorldServiceStore.js +367 -0
- package/dist/target/evidenceExport.d.ts +55 -0
- package/dist/target/evidenceExport.js +518 -0
- package/dist/target/evidenceExportArchive.d.ts +10 -0
- package/dist/target/evidenceExportArchive.js +302 -0
- package/dist/target/evidenceExportContract.d.ts +27 -0
- package/dist/target/evidenceExportContract.js +40 -0
- package/dist/target/evidenceExportOperationsTestKit.d.ts +87 -0
- package/dist/target/evidenceExportOperationsTestKit.js +312 -0
- package/dist/target/evidenceExportProvider.d.ts +85 -0
- package/dist/target/evidenceExportProvider.js +187 -0
- package/dist/target/evidenceExportPublicationTypes.d.ts +16 -0
- package/dist/target/evidenceExportPublicationTypes.js +1 -0
- package/dist/target/evidenceExportStore.d.ts +70 -0
- package/dist/target/evidenceExportStore.js +498 -0
- package/dist/target/evidenceExportStorePublication.d.ts +7 -0
- package/dist/target/evidenceExportStorePublication.js +395 -0
- package/dist/target/handles.d.ts +20 -0
- package/dist/target/handles.js +56 -0
- package/dist/target/index.d.ts +12 -0
- package/dist/target/index.js +11 -0
- package/dist/target/journal.d.ts +59 -0
- package/dist/target/journal.js +529 -0
- package/dist/target/journalFilesystem.d.ts +3 -0
- package/dist/target/journalFilesystem.js +111 -0
- package/dist/target/journalRoot.d.ts +4 -0
- package/dist/target/journalRoot.js +6 -0
- package/dist/target/organizationAttachment.d.ts +23 -0
- package/dist/target/organizationAttachment.js +263 -0
- package/dist/target/organizationAttachmentAuthority.d.ts +65 -0
- package/dist/target/organizationAttachmentAuthority.js +161 -0
- package/dist/target/organizationAttachmentLifecycle.d.ts +17 -0
- package/dist/target/organizationAttachmentLifecycle.js +101 -0
- package/dist/target/organizationAttachmentProvider.d.ts +76 -0
- package/dist/target/organizationAttachmentProvider.js +289 -0
- package/dist/target/organizationAttachmentStore.d.ts +51 -0
- package/dist/target/organizationAttachmentStore.js +316 -0
- package/dist/target/publicArtifactSnapshot.d.ts +41 -0
- package/dist/target/publicArtifactSnapshot.js +150 -0
- package/dist/target/topologyActivation.d.ts +51 -0
- package/dist/target/topologyActivation.js +149 -0
- package/dist/target/topologyAttestation.d.ts +37 -0
- package/dist/target/topologyAttestation.js +300 -0
- package/dist/target/topologyAttestationErrors.d.ts +1 -0
- package/dist/target/topologyAttestationErrors.js +1 -0
- package/dist/target/worldClock.d.ts +60 -0
- package/dist/target/worldClock.js +129 -0
- package/dist/target/worldReadiness.d.ts +103 -0
- package/dist/target/worldReadiness.js +153 -0
- package/moltnet-releases.json +20 -0
- package/package.json +27 -11
- package/runtimes.yaml +8 -23
- package/dist/runtime/openclaw/scaffold-assets/CLAUDE.md +0 -5
- package/dist/runtime/picoclaw/scaffold-assets/CLAUDE.md +0 -5
- /package/dist/runtime/openclaw/scaffold-assets/{AGENTS.md → WORKSPACE_AGENTS.md} +0 -0
- /package/dist/runtime/picoclaw/scaffold-assets/{AGENTS.md → WORKSPACE_AGENTS.md} +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
2
|
+
import { parseTargetResourceRequest } from "./contracts.js";
|
|
3
|
+
import { DOCKER_ARTIFACT_ERROR, createDockerArtifactSpec, executeDockerArtifact, isExpectedDockerArtifact, parseDockerArtifactMappings } from "./dockerArtifactsProvider.js";
|
|
4
|
+
import { selectTarget } from "./dockerTarget.js";
|
|
5
|
+
import { createTargetReceiptDigest } from "./handles.js";
|
|
6
|
+
const CONTEXT_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/u;
|
|
7
|
+
const fail = () => { throw new SpawnfileError("runtime_error", DOCKER_ARTIFACT_ERROR); };
|
|
8
|
+
const same = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
9
|
+
const exactContext = (value) => CONTEXT_PATTERN.exec(value)?.[0] === value;
|
|
10
|
+
const validOptions = (raw) => {
|
|
11
|
+
try {
|
|
12
|
+
if (typeof raw.context !== "string" || !exactContext(raw.context)
|
|
13
|
+
|| typeof raw.executor !== "function" || !raw.identityStore || typeof raw.identityStore.bind !== "function" || !raw.journal
|
|
14
|
+
|| typeof raw.timeoutMs !== "undefined" && (typeof raw.timeoutMs !== "number" || !Number.isSafeInteger(raw.timeoutMs) || raw.timeoutMs < 1 || raw.timeoutMs > 120_000))
|
|
15
|
+
return fail();
|
|
16
|
+
return {
|
|
17
|
+
context: raw.context, executor: raw.executor, identityStore: raw.identityStore, journal: raw.journal,
|
|
18
|
+
mappings: parseDockerArtifactMappings(raw.mappings), signal: raw.signal, timeoutMs: raw.timeoutMs ?? 10_000
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return fail();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const parseRequest = (raw) => {
|
|
26
|
+
const request = parseTargetResourceRequest(raw);
|
|
27
|
+
if (request.operation !== "resolve_world_artifact")
|
|
28
|
+
return fail();
|
|
29
|
+
return request;
|
|
30
|
+
};
|
|
31
|
+
const mappingFor = (request, options) => options.mappings.find((mapping) => mapping.artifact_manifest_digest === request.artifact_manifest_digest) ?? fail();
|
|
32
|
+
const selectedContextMatches = async (request, options) => {
|
|
33
|
+
const selected = await selectTarget({
|
|
34
|
+
context: options.context, dockerCommand: "docker",
|
|
35
|
+
execFile: async (_file, args, commandOptions) => executeDockerArtifact({ args, executor: options.executor, signal: commandOptions.signal, timeoutMs: commandOptions.timeout }),
|
|
36
|
+
signal: options.signal, timeoutMs: options.timeoutMs
|
|
37
|
+
});
|
|
38
|
+
if (!same({ fingerprint: selected.fingerprint, handle: selected.handle }, request.selected_target))
|
|
39
|
+
return fail();
|
|
40
|
+
};
|
|
41
|
+
const receiptFor = async (input) => {
|
|
42
|
+
const revision = (await input.journal.read()).revision + 1;
|
|
43
|
+
const raw = {
|
|
44
|
+
cleanup_state: "not_requested", descriptor_digest: input.request.descriptor_digest, export_state: "not_requested",
|
|
45
|
+
labels: Object.entries(input.labels).map(([key, value]) => ({ key, value })), operation: input.request.operation,
|
|
46
|
+
operation_handle: input.claim.operationHandle, receipt_digest: `sha256:${"0".repeat(64)}`,
|
|
47
|
+
request_digest: input.claim.requestDigest, result_handle: input.resultHandle, resulting_revision: revision,
|
|
48
|
+
run_id: input.request.run_id, selected_target: input.request.selected_target, version: "spawnfile.target-resource.receipt.v1"
|
|
49
|
+
};
|
|
50
|
+
return { ...raw, receipt_digest: createTargetReceiptDigest(raw) };
|
|
51
|
+
};
|
|
52
|
+
class DockerArtifactOperationsImpl {
|
|
53
|
+
#live = new Map();
|
|
54
|
+
#options;
|
|
55
|
+
constructor(options) { this.#options = options; }
|
|
56
|
+
execute(raw) {
|
|
57
|
+
let request;
|
|
58
|
+
let mapping;
|
|
59
|
+
try {
|
|
60
|
+
request = parseRequest(raw);
|
|
61
|
+
mapping = mappingFor(request, this.#options);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return Promise.reject(new SpawnfileError("runtime_error", DOCKER_ARTIFACT_ERROR));
|
|
65
|
+
}
|
|
66
|
+
const active = this.#live.get(request.idempotency_key);
|
|
67
|
+
if (active)
|
|
68
|
+
return same(active.request, request) ? active.promise : Promise.reject(new SpawnfileError("runtime_error", DOCKER_ARTIFACT_ERROR));
|
|
69
|
+
let resolve;
|
|
70
|
+
let reject;
|
|
71
|
+
const promise = new Promise((accept, refuse) => { resolve = accept; reject = refuse; });
|
|
72
|
+
this.#live.set(request.idempotency_key, { promise, request });
|
|
73
|
+
void this.executeOwner(request, mapping).then(resolve, reject).finally(() => {
|
|
74
|
+
if (this.#live.get(request.idempotency_key)?.promise === promise)
|
|
75
|
+
this.#live.delete(request.idempotency_key);
|
|
76
|
+
});
|
|
77
|
+
return promise;
|
|
78
|
+
}
|
|
79
|
+
async executeOwner(request, mapping) {
|
|
80
|
+
try {
|
|
81
|
+
const reservation = await this.#options.journal.reserve(request);
|
|
82
|
+
if (reservation.kind === "replay")
|
|
83
|
+
return { receipt: reservation.receipt, receiptBytes: reservation.receiptBytes };
|
|
84
|
+
const spec = createDockerArtifactSpec({
|
|
85
|
+
artifactManifestDigest: request.artifact_manifest_digest, imageDigest: mapping.image_digest,
|
|
86
|
+
imageReference: mapping.image_reference, operationHandle: reservation.claim.operationHandle,
|
|
87
|
+
requestDigest: reservation.claim.requestDigest, selectedTargetHandle: request.selected_target.handle
|
|
88
|
+
});
|
|
89
|
+
await this.#options.identityStore.bind({
|
|
90
|
+
artifactManifestDigest: request.artifact_manifest_digest, imageDigest: mapping.image_digest,
|
|
91
|
+
imageReference: mapping.image_reference, operationHandle: reservation.claim.operationHandle,
|
|
92
|
+
requestDigest: reservation.claim.requestDigest, resultHandle: spec.resultHandle,
|
|
93
|
+
selectedTargetHandle: request.selected_target.handle
|
|
94
|
+
});
|
|
95
|
+
await selectedContextMatches(request, this.#options);
|
|
96
|
+
const result = await executeDockerArtifact({
|
|
97
|
+
args: ["--context", this.#options.context, "image", "inspect", "--format", spec.inspectionFormat, spec.imageReference],
|
|
98
|
+
executor: this.#options.executor, signal: this.#options.signal, timeoutMs: this.#options.timeoutMs
|
|
99
|
+
});
|
|
100
|
+
if (!isExpectedDockerArtifact(result.stdout, spec))
|
|
101
|
+
return fail();
|
|
102
|
+
const receipt = await receiptFor({ claim: reservation.claim, journal: this.#options.journal, labels: spec.labels, request, resultHandle: spec.resultHandle });
|
|
103
|
+
return await this.#options.journal.complete(reservation.claim, receipt);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return fail();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export const createDockerArtifactOperations = (options) => new DockerArtifactOperationsImpl(validOptions(options));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type OpaqueTargetHandle } from "./contracts.js";
|
|
2
|
+
import type { DockerArtifactIdentityStore, DockerArtifactIdentityStoreOptions } from "./dockerArtifactIdentityTypes.js";
|
|
3
|
+
export type { DockerArtifactIdentityBinding, DockerArtifactIdentityStore, DockerArtifactIdentityStoreOptions, DockerConfigArtifactIdentityBinding, DockerOciArtifactIdentityBinding } from "./dockerArtifactIdentityTypes.js";
|
|
4
|
+
export declare const DOCKER_ARTIFACT_ERROR = "Docker artifact resolution failed";
|
|
5
|
+
export declare const DOCKER_ARTIFACT_INSPECTION_FORMAT = "[{\"RepoDigests\":{{json .RepoDigests}}}]";
|
|
6
|
+
export interface DockerArtifactExecutor {
|
|
7
|
+
(file: string, args: string[], options: {
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
timeout: number;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
stderr: string;
|
|
12
|
+
stdout: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
export declare class DockerArtifactProviderError extends Error {
|
|
16
|
+
readonly kind: "image_not_found";
|
|
17
|
+
constructor(kind: "image_not_found");
|
|
18
|
+
}
|
|
19
|
+
export interface DockerArtifactMapping {
|
|
20
|
+
readonly artifact_manifest_digest: string;
|
|
21
|
+
readonly image_digest: string;
|
|
22
|
+
readonly image_reference: string;
|
|
23
|
+
}
|
|
24
|
+
export interface DockerArtifactSpec {
|
|
25
|
+
readonly imageDigest: string;
|
|
26
|
+
readonly imageReference: string;
|
|
27
|
+
readonly inspectionFormat: typeof DOCKER_ARTIFACT_INSPECTION_FORMAT;
|
|
28
|
+
readonly labels: Readonly<Record<string, string>>;
|
|
29
|
+
readonly resultHandle: OpaqueTargetHandle;
|
|
30
|
+
}
|
|
31
|
+
export interface DockerConfigArtifactSpec {
|
|
32
|
+
readonly configId: string;
|
|
33
|
+
readonly imageDigest: string;
|
|
34
|
+
readonly imageReference: string;
|
|
35
|
+
readonly labels: Readonly<Record<string, string>>;
|
|
36
|
+
readonly resultHandle: OpaqueTargetHandle;
|
|
37
|
+
}
|
|
38
|
+
export declare const isImmutableDockerImageReference: (value: unknown) => value is string;
|
|
39
|
+
export declare const parseDockerArtifactMappings: (raw: unknown) => readonly DockerArtifactMapping[];
|
|
40
|
+
export declare const initializeDockerArtifactIdentityStore: (root: unknown, options?: DockerArtifactIdentityStoreOptions) => Promise<DockerArtifactIdentityStore>;
|
|
41
|
+
export { createDockerArtifactSpec, createDockerConfigArtifactSpec, executeDockerArtifact, isExpectedDockerArtifact } from "./dockerArtifactInspection.js";
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { constants } from "node:fs";
|
|
4
|
+
import { chmod, link, lstat, mkdir, open, unlink } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { assertOrdinaryJsonGraph, parseOpaqueTargetHandle } from "./contracts.js";
|
|
7
|
+
export const DOCKER_ARTIFACT_ERROR = "Docker artifact resolution failed";
|
|
8
|
+
export const DOCKER_ARTIFACT_INSPECTION_FORMAT = "[{\"RepoDigests\":{{json .RepoDigests}}}]";
|
|
9
|
+
const MAX_OUTPUT_BYTES = 32_768;
|
|
10
|
+
const MAX_REPOSITORY_BYTES = 255;
|
|
11
|
+
const MAX_REFERENCE_BYTES = MAX_REPOSITORY_BYTES + 72;
|
|
12
|
+
const MAX_IDENTITY_BYTES = 262_144;
|
|
13
|
+
const DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/u;
|
|
14
|
+
const PORT_PATTERN = /^[1-9][0-9]{0,4}$/u;
|
|
15
|
+
const NAME_COMPONENT_PATTERN = /^[a-z0-9]+(?:(?:[._]|__|[-]+)[a-z0-9]+)*$/u;
|
|
16
|
+
const DOMAIN_COMPONENT_PATTERN = /^(?:[a-z0-9]|[a-z0-9][a-z0-9-]{0,61}[a-z0-9])$/u;
|
|
17
|
+
export class DockerArtifactProviderError extends Error {
|
|
18
|
+
kind;
|
|
19
|
+
constructor(kind) {
|
|
20
|
+
super(DOCKER_ARTIFACT_ERROR);
|
|
21
|
+
this.kind = kind;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const fail = () => { throw new Error(DOCKER_ARTIFACT_ERROR); };
|
|
25
|
+
const bytes = (value) => Buffer.byteLength(value, "utf8");
|
|
26
|
+
const exactMatch = (pattern, value) => pattern.exec(value)?.[0] === value;
|
|
27
|
+
const digest = (domain, value) => createHash("sha256")
|
|
28
|
+
.update(`spawnfile.target-artifact.${domain}.v1\0`, "utf8").update(value, "utf8").digest("hex");
|
|
29
|
+
const label = (prefix, value) => `${prefix}${digest("label", value).slice(0, 63)}`;
|
|
30
|
+
const isDigest = (value) => typeof value === "string" && exactMatch(DIGEST_PATTERN, value);
|
|
31
|
+
const isRegistry = (value) => {
|
|
32
|
+
const colon = value.lastIndexOf(":");
|
|
33
|
+
const host = colon < 0 ? value : value.slice(0, colon);
|
|
34
|
+
const port = colon < 0 ? null : value.slice(colon + 1);
|
|
35
|
+
if (host.length < 1 || host.length > 253 || host.includes(":"))
|
|
36
|
+
return false;
|
|
37
|
+
if (port !== null && (!exactMatch(PORT_PATTERN, port) || Number(port) > 65_535))
|
|
38
|
+
return false;
|
|
39
|
+
return host.split(".").every((part) => exactMatch(DOMAIN_COMPONENT_PATTERN, part));
|
|
40
|
+
};
|
|
41
|
+
const isRepository = (value) => {
|
|
42
|
+
const parts = value.split("/");
|
|
43
|
+
if (parts.some((part) => part.length === 0))
|
|
44
|
+
return false;
|
|
45
|
+
if (parts.length > 1 && (parts[0] === "localhost" || parts[0].includes(".") || parts[0].includes(":"))) {
|
|
46
|
+
if (!isRegistry(parts.shift()))
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return parts.length > 0 && parts.every((part) => exactMatch(NAME_COMPONENT_PATTERN, part));
|
|
50
|
+
};
|
|
51
|
+
export const isImmutableDockerImageReference = (value) => {
|
|
52
|
+
if (typeof value !== "string" || bytes(value) > MAX_REFERENCE_BYTES || value !== value.toLowerCase())
|
|
53
|
+
return false;
|
|
54
|
+
const separator = value.indexOf("@");
|
|
55
|
+
if (separator < 1 || separator !== value.lastIndexOf("@"))
|
|
56
|
+
return false;
|
|
57
|
+
const repository = value.slice(0, separator);
|
|
58
|
+
return bytes(repository) <= MAX_REPOSITORY_BYTES && isRepository(repository) && isDigest(value.slice(separator + 1));
|
|
59
|
+
};
|
|
60
|
+
export const parseDockerArtifactMappings = (raw) => {
|
|
61
|
+
try {
|
|
62
|
+
assertOrdinaryJsonGraph(raw);
|
|
63
|
+
if (!Array.isArray(raw) || raw.length < 1 || raw.length > 32)
|
|
64
|
+
return fail();
|
|
65
|
+
const manifests = new Set();
|
|
66
|
+
const imageDigests = new Set();
|
|
67
|
+
const references = new Set();
|
|
68
|
+
const mappings = raw.map((value) => {
|
|
69
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
70
|
+
return fail();
|
|
71
|
+
const record = value;
|
|
72
|
+
if (Object.keys(record).sort().join("\0") !== "artifact_manifest_digest\0image_digest\0image_reference")
|
|
73
|
+
return fail();
|
|
74
|
+
const manifest = record.artifact_manifest_digest;
|
|
75
|
+
const imageDigest = record.image_digest;
|
|
76
|
+
const reference = record.image_reference;
|
|
77
|
+
if (!isDigest(manifest) || !isDigest(imageDigest)
|
|
78
|
+
|| !isImmutableDockerImageReference(reference) || !reference.endsWith(`@${imageDigest}`)
|
|
79
|
+
|| manifests.has(manifest) || imageDigests.has(imageDigest) || references.has(reference))
|
|
80
|
+
return fail();
|
|
81
|
+
manifests.add(manifest);
|
|
82
|
+
imageDigests.add(imageDigest);
|
|
83
|
+
references.add(reference);
|
|
84
|
+
return Object.freeze({ artifact_manifest_digest: manifest, image_digest: imageDigest, image_reference: reference });
|
|
85
|
+
});
|
|
86
|
+
return Object.freeze(mappings);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return fail();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const identityBase = (input) => {
|
|
93
|
+
const operationHandle = parseOpaqueTargetHandle(input.operationHandle);
|
|
94
|
+
const resultHandle = parseOpaqueTargetHandle(input.resultHandle);
|
|
95
|
+
const selectedTargetHandle = parseOpaqueTargetHandle(input.selectedTargetHandle);
|
|
96
|
+
if (!isDigest(input.requestDigest) || !isDigest(input.artifactManifestDigest))
|
|
97
|
+
return fail();
|
|
98
|
+
return Object.freeze({ artifact_manifest_digest: input.artifactManifestDigest,
|
|
99
|
+
operation_handle: operationHandle, request_digest: input.requestDigest,
|
|
100
|
+
result_handle: resultHandle, selected_target_handle: selectedTargetHandle });
|
|
101
|
+
};
|
|
102
|
+
const bindingBytes = (input) => {
|
|
103
|
+
try {
|
|
104
|
+
if (!input || typeof input !== "object" || Array.isArray(input)
|
|
105
|
+
|| Object.getPrototypeOf(input) !== Object.prototype)
|
|
106
|
+
return fail();
|
|
107
|
+
const descriptors = Object.getOwnPropertyDescriptors(input);
|
|
108
|
+
if (Object.values(descriptors).some((descriptor) => !("value" in descriptor)))
|
|
109
|
+
return fail();
|
|
110
|
+
const keys = Object.keys(input).sort().join("\0");
|
|
111
|
+
const oci = "artifactManifestDigest\0imageDigest\0imageReference\0operationHandle\0requestDigest\0resultHandle\0selectedTargetHandle";
|
|
112
|
+
const ociTagged = `${oci}\0identityKind`.split("\0").sort().join("\0");
|
|
113
|
+
const config = "archiveDigest\0artifactManifestDigest\0baseImageConfigDigest\0buildPolicyDigest\0bundleDigest\0configId\0daemonEpoch\0entrypoint\0gcTag\0identityKind\0launcherDigest\0networkAlias\0operationHandle\0platform\0platformDigest\0preparedOperationHandle\0preparedRequestDigest\0requestDigest\0resultHandle\0selectedTargetHandle";
|
|
114
|
+
if ((input.identityKind === "docker_image_config_digest" && keys !== config)
|
|
115
|
+
|| (input.identityKind !== "docker_image_config_digest" && keys !== oci && keys !== ociTagged))
|
|
116
|
+
return fail();
|
|
117
|
+
if (input.identityKind === "oci_image_manifest" && descriptors.identityKind?.enumerable === false
|
|
118
|
+
&& keys !== oci)
|
|
119
|
+
return fail();
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return fail();
|
|
123
|
+
}
|
|
124
|
+
const base = identityBase(input);
|
|
125
|
+
if (input.identityKind === "docker_image_config_digest") {
|
|
126
|
+
if (!isDigest(input.archiveDigest) || !isDigest(input.baseImageConfigDigest)
|
|
127
|
+
|| !isDigest(input.buildPolicyDigest) || !isDigest(input.bundleDigest) || !isDigest(input.configId)
|
|
128
|
+
|| !isDigest(input.daemonEpoch) || !isDigest(input.launcherDigest) || !isDigest(input.platformDigest)
|
|
129
|
+
|| !isDigest(input.preparedRequestDigest)
|
|
130
|
+
|| typeof input.gcTag !== "string" || !/^spfb_[a-f0-9]{58}$/u.test(input.gcTag)
|
|
131
|
+
|| typeof input.entrypoint !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._/-]{0,239}$/u.test(input.entrypoint)
|
|
132
|
+
|| input.entrypoint.includes("//") || input.entrypoint.split("/").some((part) => part === "." || part === "..")
|
|
133
|
+
|| typeof input.networkAlias !== "string" || !/^[a-z][a-z0-9-]{0,62}$/u.test(input.networkAlias)
|
|
134
|
+
|| !input.platform || (input.platform.architecture !== "amd64" && input.platform.architecture !== "arm64")
|
|
135
|
+
|| input.platform.os !== "linux")
|
|
136
|
+
return fail();
|
|
137
|
+
const preparedOperationHandle = parseOpaqueTargetHandle(input.preparedOperationHandle);
|
|
138
|
+
return JSON.stringify({
|
|
139
|
+
...base, archive_digest: input.archiveDigest, base_image_config_digest: input.baseImageConfigDigest,
|
|
140
|
+
build_policy_digest: input.buildPolicyDigest, bundle_digest: input.bundleDigest, config_id: input.configId,
|
|
141
|
+
daemon_epoch: input.daemonEpoch, entrypoint: input.entrypoint, gc_tag: input.gcTag,
|
|
142
|
+
identity_kind: input.identityKind,
|
|
143
|
+
launcher_digest: input.launcherDigest, network_alias: input.networkAlias,
|
|
144
|
+
platform: input.platform, platform_digest: input.platformDigest,
|
|
145
|
+
prepared_operation_handle: preparedOperationHandle,
|
|
146
|
+
prepared_request_digest: input.preparedRequestDigest,
|
|
147
|
+
version: "spawnfile.target-artifact.identity.v3"
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (input.identityKind !== undefined && input.identityKind !== "oci_image_manifest")
|
|
151
|
+
return fail();
|
|
152
|
+
const [mapping] = parseDockerArtifactMappings([{
|
|
153
|
+
artifact_manifest_digest: input.artifactManifestDigest,
|
|
154
|
+
image_digest: input.imageDigest,
|
|
155
|
+
image_reference: input.imageReference
|
|
156
|
+
}]);
|
|
157
|
+
if (!mapping)
|
|
158
|
+
return fail();
|
|
159
|
+
return JSON.stringify({
|
|
160
|
+
...base, artifact_manifest_digest: mapping.artifact_manifest_digest,
|
|
161
|
+
identity_kind: "oci_image_manifest", image_digest: mapping.image_digest,
|
|
162
|
+
image_reference: mapping.image_reference,
|
|
163
|
+
version: "spawnfile.target-artifact.identity.v2"
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
const parseBinding = (text) => {
|
|
167
|
+
try {
|
|
168
|
+
const value = JSON.parse(text);
|
|
169
|
+
if (value.version !== "spawnfile.target-artifact.identity.v2"
|
|
170
|
+
&& value.version !== "spawnfile.target-artifact.identity.v3")
|
|
171
|
+
return fail();
|
|
172
|
+
let parsed;
|
|
173
|
+
if (value.identity_kind === "oci_image_manifest"
|
|
174
|
+
&& Object.keys(value).sort().join("\0") === "artifact_manifest_digest\0identity_kind\0image_digest\0image_reference\0operation_handle\0request_digest\0result_handle\0selected_target_handle\0version") {
|
|
175
|
+
const oci = {
|
|
176
|
+
artifactManifestDigest: value.artifact_manifest_digest,
|
|
177
|
+
imageDigest: value.image_digest, imageReference: value.image_reference,
|
|
178
|
+
operationHandle: parseOpaqueTargetHandle(value.operation_handle), requestDigest: value.request_digest,
|
|
179
|
+
resultHandle: parseOpaqueTargetHandle(value.result_handle), selectedTargetHandle: parseOpaqueTargetHandle(value.selected_target_handle)
|
|
180
|
+
};
|
|
181
|
+
Object.defineProperty(oci, "identityKind", { enumerable: false, value: "oci_image_manifest" });
|
|
182
|
+
parsed = Object.freeze(oci);
|
|
183
|
+
}
|
|
184
|
+
else if (value.version === "spawnfile.target-artifact.identity.v3"
|
|
185
|
+
&& value.identity_kind === "docker_image_config_digest"
|
|
186
|
+
&& Object.keys(value).sort().join("\0") === "archive_digest\0artifact_manifest_digest\0base_image_config_digest\0build_policy_digest\0bundle_digest\0config_id\0daemon_epoch\0entrypoint\0gc_tag\0identity_kind\0launcher_digest\0network_alias\0operation_handle\0platform\0platform_digest\0prepared_operation_handle\0prepared_request_digest\0request_digest\0result_handle\0selected_target_handle\0version") {
|
|
187
|
+
parsed = Object.freeze({
|
|
188
|
+
archiveDigest: value.archive_digest, artifactManifestDigest: value.artifact_manifest_digest,
|
|
189
|
+
baseImageConfigDigest: value.base_image_config_digest,
|
|
190
|
+
buildPolicyDigest: value.build_policy_digest, bundleDigest: value.bundle_digest,
|
|
191
|
+
configId: value.config_id, daemonEpoch: value.daemon_epoch,
|
|
192
|
+
entrypoint: value.entrypoint, gcTag: value.gc_tag, identityKind: "docker_image_config_digest",
|
|
193
|
+
launcherDigest: value.launcher_digest, networkAlias: value.network_alias,
|
|
194
|
+
operationHandle: parseOpaqueTargetHandle(value.operation_handle), requestDigest: value.request_digest,
|
|
195
|
+
preparedOperationHandle: parseOpaqueTargetHandle(value.prepared_operation_handle),
|
|
196
|
+
preparedRequestDigest: value.prepared_request_digest,
|
|
197
|
+
resultHandle: parseOpaqueTargetHandle(value.result_handle), selectedTargetHandle: parseOpaqueTargetHandle(value.selected_target_handle),
|
|
198
|
+
platform: value.platform, platformDigest: value.platform_digest
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
else
|
|
202
|
+
return fail();
|
|
203
|
+
if (bindingBytes(parsed) !== text)
|
|
204
|
+
return fail();
|
|
205
|
+
return parsed;
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return fail();
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const OWNER = process.getuid?.() ?? -1;
|
|
212
|
+
const checkIdentityRoot = async (raw) => {
|
|
213
|
+
if (typeof raw !== "string" || raw.length < 1 || bytes(raw) > 4_096)
|
|
214
|
+
return fail();
|
|
215
|
+
const root = path.resolve(raw);
|
|
216
|
+
const parsed = path.parse(root);
|
|
217
|
+
/* Never treat the platform filesystem root as a private Spawnfile boundary. */
|
|
218
|
+
if (root === parsed.root)
|
|
219
|
+
return fail();
|
|
220
|
+
let current = parsed.root;
|
|
221
|
+
let createdRoot = false;
|
|
222
|
+
for (const part of root.slice(parsed.root.length).split(path.sep).filter(Boolean)) {
|
|
223
|
+
current = path.join(current, part);
|
|
224
|
+
let stats;
|
|
225
|
+
let created = false;
|
|
226
|
+
try {
|
|
227
|
+
stats = await lstat(current);
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
if (error.code !== "ENOENT")
|
|
231
|
+
return fail();
|
|
232
|
+
try {
|
|
233
|
+
await mkdir(current, { mode: 0o700 });
|
|
234
|
+
created = true;
|
|
235
|
+
}
|
|
236
|
+
catch (mkdirError) {
|
|
237
|
+
if (mkdirError.code !== "EEXIST")
|
|
238
|
+
return fail();
|
|
239
|
+
}
|
|
240
|
+
stats = await lstat(current).catch(fail);
|
|
241
|
+
}
|
|
242
|
+
if (!stats.isDirectory() || stats.isSymbolicLink())
|
|
243
|
+
return fail();
|
|
244
|
+
if (current === root) {
|
|
245
|
+
createdRoot = created;
|
|
246
|
+
if (!createdRoot && (stats.uid !== OWNER || (stats.mode & 0o777) !== 0o700))
|
|
247
|
+
return fail();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (createdRoot)
|
|
251
|
+
await chmod(root, 0o700).catch(fail);
|
|
252
|
+
const final = await lstat(root).catch(fail);
|
|
253
|
+
if (!final.isDirectory() || final.isSymbolicLink() || final.uid !== OWNER || (final.mode & 0o777) !== 0o700)
|
|
254
|
+
return fail();
|
|
255
|
+
return root;
|
|
256
|
+
};
|
|
257
|
+
const secureIdentity = (stats) => {
|
|
258
|
+
if (!stats.isFile() || stats.uid !== OWNER || stats.size > MAX_IDENTITY_BYTES || (stats.mode & 0o777) !== 0o600)
|
|
259
|
+
fail();
|
|
260
|
+
};
|
|
261
|
+
const openSecureIdentity = async (filePath) => {
|
|
262
|
+
let handle;
|
|
263
|
+
try {
|
|
264
|
+
handle = await open(filePath, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
if (error.code === "ENOENT")
|
|
268
|
+
return null;
|
|
269
|
+
return fail();
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
const current = await handle.stat();
|
|
273
|
+
secureIdentity(current);
|
|
274
|
+
return { bytes: await handle.readFile({ encoding: "utf8" }), dev: current.dev, ino: current.ino, nlink: current.nlink };
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
return fail();
|
|
278
|
+
}
|
|
279
|
+
finally {
|
|
280
|
+
await handle.close().catch(() => undefined);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
const openIdentity = async (filePath, links) => {
|
|
284
|
+
const value = await openSecureIdentity(filePath);
|
|
285
|
+
if (value !== null && !links.includes(value.nlink))
|
|
286
|
+
return fail();
|
|
287
|
+
return value;
|
|
288
|
+
};
|
|
289
|
+
const syncDirectory = async (directory) => {
|
|
290
|
+
const handle = await open(directory, constants.O_RDONLY);
|
|
291
|
+
try {
|
|
292
|
+
await handle.sync();
|
|
293
|
+
}
|
|
294
|
+
finally {
|
|
295
|
+
await handle.close();
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
/* One canonical immutable record exists for one exact operation/request pair. */
|
|
299
|
+
const keyPath = (root, operationHandle, requestDigest) => path.join(root, `${digest("identity-operation", `${operationHandle}\0${requestDigest}`)}.identity.json`);
|
|
300
|
+
const pendingPath = (file) => path.join(path.dirname(file), `.${path.basename(file)}.pending`);
|
|
301
|
+
const sameInode = (left, right) => left.dev === right.dev && left.ino === right.ino;
|
|
302
|
+
/*
|
|
303
|
+
* The two names below live in a root owned exclusively by the Spawnfile uid and
|
|
304
|
+
* checked mode-0700 on every store construction. We defend each operation
|
|
305
|
+
* boundary against malformed, linked, wrong-mode, wrong-owner, or symlinked
|
|
306
|
+
* records. A malicious concurrent process with that same uid is out of scope:
|
|
307
|
+
* it already controls Spawnfile state and code. That narrow trust boundary is
|
|
308
|
+
* what makes unlink-after-same-inode-proof safe here.
|
|
309
|
+
*/
|
|
310
|
+
const reconcilePublishedIdentity = async (root, file, expected) => {
|
|
311
|
+
for (let attempt = 0; attempt < 16; attempt += 1) {
|
|
312
|
+
const final = await openIdentity(file, [1, 2]);
|
|
313
|
+
if (!final || final.bytes !== expected)
|
|
314
|
+
return fail();
|
|
315
|
+
const pending = await openIdentity(pendingPath(file), [1, 2]);
|
|
316
|
+
if (final.nlink === 1) {
|
|
317
|
+
if (pending === null)
|
|
318
|
+
return;
|
|
319
|
+
if (pending.bytes !== expected)
|
|
320
|
+
return fail();
|
|
321
|
+
if (pending.nlink !== 1)
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
/* A concurrent unlink can make a just-read two-link final become one-link. */
|
|
326
|
+
if (pending === null || pending.nlink !== 2)
|
|
327
|
+
continue;
|
|
328
|
+
if (!sameInode(final, pending) || pending.bytes !== expected)
|
|
329
|
+
return fail();
|
|
330
|
+
}
|
|
331
|
+
/* Safe only under the trusted-root boundary documented above. */
|
|
332
|
+
await unlink(pendingPath(file)).catch((error) => { if (error.code !== "ENOENT")
|
|
333
|
+
fail(); });
|
|
334
|
+
await syncDirectory(root);
|
|
335
|
+
const repaired = await openIdentity(file, [1]);
|
|
336
|
+
if (!repaired || repaired.bytes !== expected)
|
|
337
|
+
return fail();
|
|
338
|
+
if (await openIdentity(pendingPath(file), [1]) === null)
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
return fail();
|
|
342
|
+
};
|
|
343
|
+
const readPublishedIdentity = async (root, file) => {
|
|
344
|
+
const final = await openIdentity(file, [1, 2]);
|
|
345
|
+
if (final === null)
|
|
346
|
+
return null;
|
|
347
|
+
await reconcilePublishedIdentity(root, file, final.bytes);
|
|
348
|
+
return final.bytes;
|
|
349
|
+
};
|
|
350
|
+
const exactPublishedIdentity = async (root, file, content) => {
|
|
351
|
+
const prior = await readPublishedIdentity(root, file);
|
|
352
|
+
if (prior === null)
|
|
353
|
+
return false;
|
|
354
|
+
if (prior !== content)
|
|
355
|
+
return fail();
|
|
356
|
+
return true;
|
|
357
|
+
};
|
|
358
|
+
const publishIdentity = async (root, file, content, options) => {
|
|
359
|
+
const pending = pendingPath(file);
|
|
360
|
+
for (let attempt = 0; attempt < 16; attempt += 1) {
|
|
361
|
+
if (await exactPublishedIdentity(root, file, content))
|
|
362
|
+
return;
|
|
363
|
+
let created = false;
|
|
364
|
+
let handle;
|
|
365
|
+
try {
|
|
366
|
+
handle = await open(pending, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW, 0o600);
|
|
367
|
+
created = true;
|
|
368
|
+
await handle.chmod(0o600);
|
|
369
|
+
await handle.writeFile(content, "utf8");
|
|
370
|
+
await handle.sync();
|
|
371
|
+
await handle.close();
|
|
372
|
+
handle = undefined;
|
|
373
|
+
await syncDirectory(root);
|
|
374
|
+
}
|
|
375
|
+
catch (error) {
|
|
376
|
+
if (handle)
|
|
377
|
+
await handle.close().catch(() => undefined);
|
|
378
|
+
if (error.code !== "EEXIST")
|
|
379
|
+
return fail();
|
|
380
|
+
await options?.afterPendingExists?.();
|
|
381
|
+
}
|
|
382
|
+
if (created)
|
|
383
|
+
await options?.beforePublish?.();
|
|
384
|
+
const pendingRecord = await openIdentity(pending, [1, 2]);
|
|
385
|
+
if (pendingRecord === null) {
|
|
386
|
+
if (await exactPublishedIdentity(root, file, content))
|
|
387
|
+
return;
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
if (pendingRecord.bytes !== content)
|
|
391
|
+
return fail();
|
|
392
|
+
if (pendingRecord.nlink === 2) {
|
|
393
|
+
if (await exactPublishedIdentity(root, file, content))
|
|
394
|
+
return;
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
if (created)
|
|
398
|
+
await options?.beforeLink?.();
|
|
399
|
+
try {
|
|
400
|
+
await link(pending, file);
|
|
401
|
+
await syncDirectory(root);
|
|
402
|
+
await options?.afterLinkBeforePendingUnlink?.();
|
|
403
|
+
}
|
|
404
|
+
catch (error) {
|
|
405
|
+
const code = error.code;
|
|
406
|
+
if (code !== "EEXIST" && code !== "ENOENT")
|
|
407
|
+
return fail();
|
|
408
|
+
}
|
|
409
|
+
/* EEXIST may mean another exact binder linked first or a final vanished; retry only after an exact proof. */
|
|
410
|
+
if (await exactPublishedIdentity(root, file, content))
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
return fail();
|
|
414
|
+
};
|
|
415
|
+
class FileDockerArtifactIdentityStore {
|
|
416
|
+
#root;
|
|
417
|
+
#options;
|
|
418
|
+
constructor(root, options) { this.#root = root; this.#options = options; }
|
|
419
|
+
async bind(input) {
|
|
420
|
+
try {
|
|
421
|
+
const binding = parseBinding(bindingBytes(input));
|
|
422
|
+
const content = bindingBytes(binding);
|
|
423
|
+
const operation = keyPath(this.#root, binding.operationHandle, binding.requestDigest);
|
|
424
|
+
await publishIdentity(this.#root, operation, content, this.#options);
|
|
425
|
+
}
|
|
426
|
+
catch {
|
|
427
|
+
return fail();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
async resolveOperation(rawOperation, rawRequest) {
|
|
431
|
+
try {
|
|
432
|
+
const operationHandle = parseOpaqueTargetHandle(rawOperation);
|
|
433
|
+
if (!isDigest(rawRequest))
|
|
434
|
+
return fail();
|
|
435
|
+
const text = await readPublishedIdentity(this.#root, keyPath(this.#root, operationHandle, rawRequest));
|
|
436
|
+
if (text === null)
|
|
437
|
+
return null;
|
|
438
|
+
const binding = parseBinding(text);
|
|
439
|
+
if (binding.operationHandle !== operationHandle || binding.requestDigest !== rawRequest)
|
|
440
|
+
return fail();
|
|
441
|
+
return binding;
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
return fail();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
export const initializeDockerArtifactIdentityStore = async (root, options) => new FileDockerArtifactIdentityStore(await checkIdentityRoot(root), options);
|
|
449
|
+
export { createDockerArtifactSpec, createDockerConfigArtifactSpec, executeDockerArtifact, isExpectedDockerArtifact } from "./dockerArtifactInspection.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type DockerOrganizationAttachmentExecutor } from "./organizationAttachmentProvider.js";
|
|
2
|
+
import { type DockerArtifactExecutor } from "./dockerArtifactsProvider.js";
|
|
3
|
+
import { type DockerResourceExecutor } from "./dockerResourcesProvider.js";
|
|
4
|
+
import { type DockerSecretExecutor } from "./dockerSecretsProvider.js";
|
|
5
|
+
import { type DockerWorldServiceExecutor } from "./dockerWorldServiceProvider.js";
|
|
6
|
+
import type { DockerEvidenceExportExecutor } from "./evidenceExportProvider.js";
|
|
7
|
+
import { type DockerCommandSpawn } from "./dockerCommandExecutorCore.js";
|
|
8
|
+
export interface DockerTargetExecutors {
|
|
9
|
+
readonly artifact: DockerArtifactExecutor;
|
|
10
|
+
readonly attachment: DockerOrganizationAttachmentExecutor;
|
|
11
|
+
readonly evidenceExport: DockerEvidenceExportExecutor;
|
|
12
|
+
readonly publicArtifact: (file: string, args: readonly string[], options: {
|
|
13
|
+
readonly signal?: AbortSignal;
|
|
14
|
+
readonly timeout: number;
|
|
15
|
+
}) => Promise<{
|
|
16
|
+
readonly bytes: Uint8Array;
|
|
17
|
+
}>;
|
|
18
|
+
readonly resource: DockerResourceExecutor;
|
|
19
|
+
readonly secret: DockerSecretExecutor;
|
|
20
|
+
readonly world: DockerWorldServiceExecutor;
|
|
21
|
+
}
|
|
22
|
+
export interface CreateDockerTargetExecutorsOptions {
|
|
23
|
+
readonly dockerCommand?: string;
|
|
24
|
+
readonly spawn?: DockerCommandSpawn;
|
|
25
|
+
}
|
|
26
|
+
export declare const createDockerTargetExecutors: (options?: CreateDockerTargetExecutorsOptions) => DockerTargetExecutors;
|
|
27
|
+
export type { DockerCommandSpawn } from "./dockerCommandExecutorCore.js";
|