refactor(main): group ephemeral VM lifecycle modules (#31771)

This commit is contained in:
Neil
2026-10-21 21:31:21 -07:00
committed by GitHub
parent 60f5cd7118
commit 0a7d6bb2d5
27 changed files with 110 additions and 106 deletions
+3 -3
View File
@@ -373,9 +373,9 @@ jobs:
src/shared/orca-yaml-hook-types.ts \
config/scripts/run-ephemeral-vm-runtime-store-rollback-repro.mjs \
config/scripts/ephemeral-vm-runtime-store-cross-version.test.ts \
src/main/ephemeral-vm-runtime-service.ts \
src/main/ephemeral-vm-runtime-provisioning-persistence.ts \
src/main/ephemeral-vm-failed-start-cleanup.ts; then
src/main/ephemeral-vm/runtime-service.ts \
src/main/ephemeral-vm/runtime-provisioning-persistence.ts \
src/main/ephemeral-vm/failed-start-cleanup.ts; then
echo "VM runtime persistence is unchanged."
exit 0
fi
+13 -11
View File
@@ -944,13 +944,13 @@
"invariant": "Decoded stdout and stderr callback contents and order remain unchanged, final tails are the last capped run of raw output bytes with any leading partial UTF-8 sequence dropped, and success or failure releases capture storage without recapturing late output.",
"oracle": "Compare byte-bounded tails against the old per-chunk model and an independent code-point model across compaction, growth, oversized chunks and mid-character splits. Feed split and malformed UTF-8 through actual stream decoding. Require at most 5 MiB moved through the capture for 4 MiB of output with zero encoding, collectible backing buffers after close and error, zero late capture work with preserved callbacks, one decode per stream, unchanged tails on forced cancellation or synchronous kill-close, and every capture limit clamped to a bounded byte count.",
"commands": [
"ORCA_BACKGROUND_LAUNCH=1 pnpm test src/shared/ephemeral-vm-recipe-process.test.ts src/shared/ephemeral-vm-recipe-output-capture.test.ts src/packages/process-host/src/growing-byte-buffer.test.ts src/main/ephemeral-vm-recipe-runner.test.ts"
"ORCA_BACKGROUND_LAUNCH=1 pnpm test src/shared/ephemeral-vm-recipe-process.test.ts src/shared/ephemeral-vm-recipe-output-capture.test.ts src/packages/process-host/src/growing-byte-buffer.test.ts src/main/ephemeral-vm/recipe-runner.test.ts"
],
"testFiles": [
"src/shared/ephemeral-vm-recipe-process.test.ts",
"src/shared/ephemeral-vm-recipe-output-capture.test.ts",
"src/packages/process-host/src/growing-byte-buffer.test.ts",
"src/main/ephemeral-vm-recipe-runner.test.ts"
"src/main/ephemeral-vm/recipe-runner.test.ts"
],
"assertionRefs": [
{
@@ -981,7 +981,8 @@
"command": "ORCA_BACKGROUND_LAUNCH=1 pnpm test src/shared/ephemeral-vm-recipe-process.test.ts src/shared/ephemeral-vm-recipe-output-capture.test.ts src/packages/process-host/src/growing-byte-buffer.test.ts src/main/ephemeral-vm-recipe-runner.test.ts",
"result": "passed",
"durationSeconds": 0.48,
"summary": "60 tests across four suites passed, including forced-GC lifetime, synchronous SIGKILL-close and the shared byte buffer's head-offset cases."
"summary": "60 tests across four suites passed, including forced-GC lifetime, synchronous SIGKILL-close and the shared byte buffer's head-offset cases.",
"currentCommand": "ORCA_BACKGROUND_LAUNCH=1 pnpm test src/shared/ephemeral-vm-recipe-process.test.ts src/shared/ephemeral-vm-recipe-output-capture.test.ts src/packages/process-host/src/growing-byte-buffer.test.ts src/main/ephemeral-vm/recipe-runner.test.ts"
}
],
"runtimeBudget": {
@@ -3239,7 +3240,7 @@
"oracle": "Write one ordinary schema-v1 runtime and one provisioned-root runtime. Require the exact pre-#14352 reader to return both, run the old destroy lifecycle against the projected provisioned record, then require the candidate to retain the cleaned state while restoring schema-v2 and checkout-mode metadata. The same old reader must reject affected-main and fix-reverted bytes. Malformed, oversized, unknown-record, and future-version feature sidecars must leave rollback-compatible records accessible and must not be overwritten during compatible lifecycle mutations. Require destroy to have no implicit deadline, stop a hung destroy through the public desktop action, require cleanup_failed plus a fresh successful retry, prove provider or project-host rollback failure retains every ownership record required to retry, and prove missing recipe context cannot leave an unremovable hidden SSH registration. Supply the source ref's captured commit to create, reject a provisioned checkout on the wrong branch/ref, and reject a resume that changes connection mode or SSH ownership.",
"commands": [
"node config/scripts/run-ephemeral-vm-runtime-store-rollback-repro.mjs config/scripts/ephemeral-vm-runtime-store-cross-version.test.ts",
"pnpm exec vitest run --config config/vitest.config.ts src/shared/ephemeral-vm-runtime-store.test.ts src/shared/ephemeral-vm-runtime-store-rollback.test.ts src/shared/ephemeral-vm-recipe-process.test.ts src/main/ephemeral-vm-runtime-service.test.ts src/main/ephemeral-vm-resume-integrity.test.ts src/main/ephemeral-vm-recipe-runner.test.ts src/main/ephemeral-vm-runtime-ssh-cleanup.test.ts src/main/ipc/ephemeral-vm-runtime-handler-cleanup.test.ts src/main/ipc/ephemeral-vm-provision-cancel.test.ts src/main/ipc/ephemeral-vm-provisioned-root-ref.test.ts src/main/ipc/ephemeral-vm.test.ts src/main/provisioned-root-ssh-adoption.test.ts src/renderer/src/components/settings/EphemeralVmRuntimesSection.test.tsx src/renderer/src/lib/ephemeral-vm-failed-create-cleanup.test.ts src/renderer/src/lib/ephemeral-vm-runtime-cleanup.test.ts src/renderer/src/lib/ephemeral-vm-workspace-target.test.ts src/renderer/src/lib/ephemeral-vm-worktree-creation.test.ts src/renderer/src/lib/provisioned-root-create-options.test.ts src/renderer/src/store/slices/repos-ephemeral-vm-cleanup-retention.test.ts",
"pnpm exec vitest run --config config/vitest.config.ts src/shared/ephemeral-vm-runtime-store.test.ts src/shared/ephemeral-vm-runtime-store-rollback.test.ts src/shared/ephemeral-vm-recipe-process.test.ts src/main/ephemeral-vm/runtime-service.test.ts src/main/ephemeral-vm/resume-integrity.test.ts src/main/ephemeral-vm/recipe-runner.test.ts src/main/ephemeral-vm/runtime-ssh-cleanup.test.ts src/main/ipc/ephemeral-vm-runtime-handler-cleanup.test.ts src/main/ipc/ephemeral-vm-provision-cancel.test.ts src/main/ipc/ephemeral-vm-provisioned-root-ref.test.ts src/main/ipc/ephemeral-vm.test.ts src/main/provisioned-root-ssh-adoption.test.ts src/renderer/src/components/settings/EphemeralVmRuntimesSection.test.tsx src/renderer/src/lib/ephemeral-vm-failed-create-cleanup.test.ts src/renderer/src/lib/ephemeral-vm-runtime-cleanup.test.ts src/renderer/src/lib/ephemeral-vm-workspace-target.test.ts src/renderer/src/lib/ephemeral-vm-worktree-creation.test.ts src/renderer/src/lib/provisioned-root-create-options.test.ts src/renderer/src/store/slices/repos-ephemeral-vm-cleanup-retention.test.ts",
"pnpm exec playwright test tests/e2e/ephemeral-vm-cleanup-retry.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1"
],
"testFiles": [
@@ -3248,10 +3249,10 @@
"src/shared/ephemeral-vm-runtime-store-rollback.test.ts",
"src/shared/ephemeral-vm-runtime-store.test.ts",
"src/shared/ephemeral-vm-recipe-process.test.ts",
"src/main/ephemeral-vm-runtime-service.test.ts",
"src/main/ephemeral-vm-recipe-runner.test.ts",
"src/main/ephemeral-vm-runtime-ssh-cleanup.test.ts",
"src/main/ephemeral-vm-resume-integrity.test.ts",
"src/main/ephemeral-vm/runtime-service.test.ts",
"src/main/ephemeral-vm/recipe-runner.test.ts",
"src/main/ephemeral-vm/runtime-ssh-cleanup.test.ts",
"src/main/ephemeral-vm/resume-integrity.test.ts",
"src/main/ipc/ephemeral-vm-runtime-handler-cleanup.test.ts",
"src/main/ipc/ephemeral-vm-provision-cancel.test.ts",
"src/main/ipc/ephemeral-vm-provisioned-root-ref.test.ts",
@@ -3285,7 +3286,7 @@
]
},
{
"file": "src/main/ephemeral-vm-runtime-service.test.ts",
"file": "src/main/ephemeral-vm/runtime-service.test.ts",
"assertions": [
"an unreadable companion rejects checkout-mode recipes before their create command runs",
"post-create persistence failure destroys the provider resource when possible",
@@ -3349,7 +3350,7 @@
]
},
{
"file": "src/main/ephemeral-vm-resume-integrity.test.ts",
"file": "src/main/ephemeral-vm/resume-integrity.test.ts",
"assertions": [
"resume allows host and port rotation",
"resume rejects connection-mode and stable SSH ownership drift"
@@ -3379,7 +3380,8 @@
"command": "pnpm exec vitest run --config config/vitest.config.ts src/shared/ephemeral-vm-runtime-store.test.ts src/shared/ephemeral-vm-runtime-store-rollback.test.ts src/shared/ephemeral-vm-recipe-process.test.ts src/main/ephemeral-vm-runtime-service.test.ts src/main/ephemeral-vm-resume-integrity.test.ts src/main/ephemeral-vm-recipe-runner.test.ts src/main/ephemeral-vm-runtime-ssh-cleanup.test.ts src/main/ipc/ephemeral-vm-runtime-handler-cleanup.test.ts src/main/ipc/ephemeral-vm-provision-cancel.test.ts src/main/ipc/ephemeral-vm-provisioned-root-ref.test.ts src/main/ipc/ephemeral-vm.test.ts src/main/provisioned-root-ssh-adoption.test.ts src/renderer/src/components/settings/EphemeralVmRuntimesSection.test.tsx src/renderer/src/lib/ephemeral-vm-failed-create-cleanup.test.ts src/renderer/src/lib/ephemeral-vm-runtime-cleanup.test.ts src/renderer/src/lib/ephemeral-vm-workspace-target.test.ts src/renderer/src/lib/ephemeral-vm-worktree-creation.test.ts src/renderer/src/lib/provisioned-root-create-options.test.ts src/renderer/src/store/slices/repos-ephemeral-vm-cleanup-retention.test.ts",
"result": "passed",
"durationSeconds": 3,
"summary": "One hundred twenty-two focused store, recipe-process, lifecycle, cleanup-handler, rendered stop-action, retry-context, source-ref, adoption-integrity, resume-integrity, and provisioning-recovery tests passed."
"summary": "One hundred twenty-two focused store, recipe-process, lifecycle, cleanup-handler, rendered stop-action, retry-context, source-ref, adoption-integrity, resume-integrity, and provisioning-recovery tests passed.",
"currentCommand": "pnpm exec vitest run --config config/vitest.config.ts src/shared/ephemeral-vm-runtime-store.test.ts src/shared/ephemeral-vm-runtime-store-rollback.test.ts src/shared/ephemeral-vm-recipe-process.test.ts src/main/ephemeral-vm/runtime-service.test.ts src/main/ephemeral-vm/resume-integrity.test.ts src/main/ephemeral-vm/recipe-runner.test.ts src/main/ephemeral-vm/runtime-ssh-cleanup.test.ts src/main/ipc/ephemeral-vm-runtime-handler-cleanup.test.ts src/main/ipc/ephemeral-vm-provision-cancel.test.ts src/main/ipc/ephemeral-vm-provisioned-root-ref.test.ts src/main/ipc/ephemeral-vm.test.ts src/main/provisioned-root-ssh-adoption.test.ts src/renderer/src/components/settings/EphemeralVmRuntimesSection.test.tsx src/renderer/src/lib/ephemeral-vm-failed-create-cleanup.test.ts src/renderer/src/lib/ephemeral-vm-runtime-cleanup.test.ts src/renderer/src/lib/ephemeral-vm-workspace-target.test.ts src/renderer/src/lib/ephemeral-vm-worktree-creation.test.ts src/renderer/src/lib/provisioned-root-create-options.test.ts src/renderer/src/store/slices/repos-ephemeral-vm-cleanup-retention.test.ts"
}
],
"runtimeBudget": {
@@ -135,8 +135,11 @@ test.skipIf(!targetRoot || !operation)(`STA-4274 ${operation ?? 'disabled'}`, as
'})'
].join('\n')
)
const servicePath = resolve(targetRoot, 'src/main/ephemeral-vm/runtime-service.ts')
const serviceUrl = pathToFileURL(
resolve(targetRoot, 'src/main/ephemeral-vm-runtime-service.ts')
existsSync(servicePath)
? servicePath
: resolve(targetRoot, 'src/main/ephemeral-vm-runtime-service.ts')
).href
const service = await import(/* @vite-ignore */ serviceUrl)
const result = await service.cleanupEphemeralVmRuntime({
-1
View File
@@ -1 +0,0 @@
export * from '../shared/ephemeral-vm-recipe-runner'
@@ -1,17 +1,17 @@
import {
getEphemeralVmRecipeResultConnection,
type EphemeralVmRecipeResult
} from '../shared/ephemeral-vm-recipes'
import type { EphemeralVmRuntimeRecord } from '../shared/ephemeral-vm-runtimes'
} from '../../shared/ephemeral-vm-recipes'
import type { EphemeralVmRuntimeRecord } from '../../shared/ephemeral-vm-runtimes'
import {
upsertEphemeralVmRuntime,
upsertEphemeralVmRuntimeRollbackRecovery
} from '../shared/ephemeral-vm-runtime-store'
import type { ProvisionEphemeralVmRuntimeArgs } from './ephemeral-vm-runtime-service'
} from '../../shared/ephemeral-vm-runtime-store'
import type { ProvisionEphemeralVmRuntimeArgs } from './runtime-service'
import {
runEphemeralVmRecipeCleanup,
type EphemeralVmRecipeContext
} from './ephemeral-vm-recipe-runner'
} from '../../shared/ephemeral-vm-recipe-runner'
type FailedStart = {
context: EphemeralVmRecipeContext
@@ -1,10 +1,10 @@
import type { Store } from './persistence'
import type { Repo } from '../shared/repo-types'
import { gitExecFileAsync } from './git/runner'
import { resolveDefaultBaseRefWithLocalGit } from './git/repo'
import { getLocalProjectGitExecOptions } from './project-runtime-git-options'
import { resolveWorktreeCreateBase } from './worktree-create-base'
import { resolveWorktreeAddBaseRef } from '../shared/worktree/base-ref'
import type { Store } from '../persistence/loading-store/store'
import type { Repo } from '../../shared/repo-types'
import { gitExecFileAsync } from '../git/command-runner/git-exec-file'
import { resolveDefaultBaseRefWithLocalGit } from '../git/repo-default-base-ref'
import { getLocalProjectGitExecOptions } from '../project-runtime-git-options'
import { resolveWorktreeCreateBase } from '../worktree-create-base'
import { resolveWorktreeAddBaseRef } from '../../shared/worktree/base-ref'
const PROVISIONED_ROOT_SOURCE_REF_TIMEOUT_MS = 15_000
@@ -2,17 +2,19 @@ import { mkdtempSync, realpathSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { encodePairingOffer, PAIRING_OFFER_VERSION } from '../shared/pairing'
import { getEphemeralVmRecipeResultProjectRoot } from '../shared/ephemeral-vm-recipes'
import { encodePairingOffer, PAIRING_OFFER_VERSION } from '../../shared/pairing'
import { getEphemeralVmRecipeResultProjectRoot } from '../../shared/ephemeral-vm-recipes'
import {
buildEphemeralVmRecipeCleanupCommand,
buildEphemeralVmRecipeCleanupPayload,
buildEphemeralVmRecipeCleanupPayload
} from '../../shared/ephemeral-vm-recipe-lifecycle-payload'
import {
runEphemeralVmRecipeCleanup,
runEphemeralVmRecipeResume,
runEphemeralVmRecipeStart,
runEphemeralVmRecipeSuspend
} from './ephemeral-vm-recipe-runner'
import type { OrcaVmRecipe } from '../shared/orca-yaml-hook-types'
} from '../../shared/ephemeral-vm-recipe-runner'
import type { OrcaVmRecipe } from '../../shared/orca-yaml-hook-types'
const tmpRoots: string[] = []
@@ -2,8 +2,8 @@ import { describe, expect, it } from 'vitest'
import type {
EphemeralVmRecipeConnection,
EphemeralVmRecipeResult
} from '../shared/ephemeral-vm-recipes'
import { getProvisionedRootResumeIntegrityError } from './ephemeral-vm-resume-integrity'
} from '../../shared/ephemeral-vm-recipes'
import { getProvisionedRootResumeIntegrityError } from './resume-integrity'
type RecipeSshTarget = Extract<EphemeralVmRecipeConnection, { type: 'ssh' }>['target']
@@ -1,10 +1,10 @@
import { normalizeRuntimePathForComparison } from '../shared/cross-platform-path'
import { normalizeRuntimePathForComparison } from '../../shared/cross-platform-path'
import {
getEphemeralVmRecipeResultCheckoutMode,
getEphemeralVmRecipeResultConnection,
getEphemeralVmRecipeResultProjectRoot,
type EphemeralVmRecipeResult
} from '../shared/ephemeral-vm-recipes'
} from '../../shared/ephemeral-vm-recipes'
export function getProvisionedRootResumeIntegrityError(
previous: EphemeralVmRecipeResult,
@@ -1,8 +1,8 @@
import {
listEphemeralVmRuntimes,
updateEphemeralVmRuntimeStatus
} from '../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../shared/ephemeral-vm-runtimes'
} from '../../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../../shared/ephemeral-vm-runtimes'
export function attachEphemeralVmRuntimeToWorkspace(args: {
userDataPath: string
@@ -1,4 +1,4 @@
import type { CleanupEphemeralVmRuntimeResult } from './ephemeral-vm-runtime-service'
import type { CleanupEphemeralVmRuntimeResult } from './runtime-service'
type CleanupInFlight = {
controller: AbortController
@@ -7,18 +7,18 @@ const mocks = vi.hoisted(() => ({
closeTunnel: vi.fn(async () => {})
}))
vi.mock('../shared/runtime-environment-store', () => ({
vi.mock('../../shared/runtime-environment-store', () => ({
listEnvironments: mocks.list,
removeEnvironment: mocks.remove
}))
vi.mock('../shared/runtime-environment-managed-orcad-store', () => ({
vi.mock('../../shared/runtime-environment-managed-orcad-store', () => ({
removeManagedOrcadEnvironment: mocks.removeManaged
}))
vi.mock('./managed-server/lifecycle/orcad-managed-tunnel', () => ({
vi.mock('../managed-server/lifecycle/orcad-managed-tunnel', () => ({
closeOrcadManagedTunnel: mocks.closeTunnel
}))
import { releaseEphemeralVmRuntimeEnvironments } from './ephemeral-vm-runtime-environment-release'
import { releaseEphemeralVmRuntimeEnvironments } from './runtime-environment-release'
describe('releaseEphemeralVmRuntimeEnvironments', () => {
beforeEach(() => {
@@ -1,7 +1,7 @@
import type { EphemeralVmRuntimeRecord } from '../shared/ephemeral-vm-runtimes'
import { removeManagedOrcadEnvironment } from '../shared/runtime-environment-managed-orcad-store'
import { listEnvironments, removeEnvironment } from '../shared/runtime-environment-store'
import { getOrcadSshDeployment } from '../shared/runtime-environments'
import type { EphemeralVmRuntimeRecord } from '../../shared/ephemeral-vm-runtimes'
import { removeManagedOrcadEnvironment } from '../../shared/runtime-environment-managed-orcad-store'
import { listEnvironments, removeEnvironment } from '../../shared/runtime-environment-store'
import { getOrcadSshDeployment } from '../../shared/runtime-environments'
/** Forgets the servers a destroyed VM ran; a managed one's tunnel would otherwise keep redialing. */
export async function releaseEphemeralVmRuntimeEnvironments(
@@ -21,7 +21,7 @@ export async function releaseEphemeralVmRuntimeEnvironments(
continue
}
const { closeOrcadManagedTunnel } =
await import('./managed-server/lifecycle/orcad-managed-tunnel')
await import('../managed-server/lifecycle/orcad-managed-tunnel')
await closeOrcadManagedTunnel(environment.id).catch(() => undefined)
removeManagedOrcadEnvironment(userDataPath, environment.id)
}
@@ -1,17 +1,17 @@
import { randomUUID } from 'node:crypto'
import { assertEphemeralVmRuntimeCheckoutModeCanPersist } from '../shared/ephemeral-vm-runtime-feature-store'
import { getEphemeralVmRecipeResultConnection } from '../shared/ephemeral-vm-recipes'
import { assertEphemeralVmRuntimeCheckoutModeCanPersist } from '../../shared/ephemeral-vm-runtime-feature-store'
import { getEphemeralVmRecipeResultConnection } from '../../shared/ephemeral-vm-recipes'
import {
listEphemeralVmRuntimes,
removeEphemeralVmRuntime,
upsertEphemeralVmRuntime
} from '../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../shared/ephemeral-vm-runtimes'
} from '../../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../../shared/ephemeral-vm-runtimes'
import type {
ProvisionEphemeralVmRuntimeArgs,
ProvisionEphemeralVmRuntimeResult
} from './ephemeral-vm-runtime-service'
import { cleanupFailedEphemeralVmStart } from './ephemeral-vm-failed-start-cleanup'
} from './runtime-service'
import { cleanupFailedEphemeralVmStart } from './failed-start-cleanup'
export type EphemeralVmCompatibilityPersistence = {
instanceId: string
@@ -2,23 +2,23 @@ import { existsSync, mkdtempSync, readFileSync, rmSync, truncateSync, writeFileS
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { encodePairingOffer, PAIRING_OFFER_VERSION } from '../shared/pairing'
import { encodePairingOffer, PAIRING_OFFER_VERSION } from '../../shared/pairing'
import {
getEphemeralVmRuntimeStorePath,
listEphemeralVmRuntimes,
upsertEphemeralVmRuntime
} from '../shared/ephemeral-vm-runtime-store'
} from '../../shared/ephemeral-vm-runtime-store'
import {
getEphemeralVmRuntimeFeatureStorePath,
MAX_EPHEMERAL_VM_RUNTIME_FEATURE_STORE_FILE_BYTES
} from '../shared/ephemeral-vm-runtime-feature-store'
} from '../../shared/ephemeral-vm-runtime-feature-store'
import {
cleanupEphemeralVmRuntime,
provisionEphemeralVmRuntime,
resumeEphemeralVmRuntime,
stopEphemeralVmRuntimeCleanup
} from './ephemeral-vm-runtime-service'
import type { OrcaVmRecipe } from '../shared/orca-yaml-hook-types'
resumeEphemeralVmRuntime
} from './runtime-service'
import { stopEphemeralVmRuntimeCleanup } from './runtime-cleanup-control'
import type { OrcaVmRecipe } from '../../shared/orca-yaml-hook-types'
const tempDirs: string[] = []
@@ -1,9 +1,9 @@
import type { OrcaVmRecipe } from '../shared/orca-yaml-hook-types'
import type { OrcaVmRecipe } from '../../shared/orca-yaml-hook-types'
import {
listEphemeralVmRuntimes,
updateEphemeralVmRuntimeStatus
} from '../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../shared/ephemeral-vm-runtimes'
} from '../../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../../shared/ephemeral-vm-runtimes'
import {
runEphemeralVmRecipeCleanup,
runEphemeralVmRecipeResume,
@@ -12,16 +12,14 @@ import {
type EphemeralVmRecipeContext,
type EphemeralVmRecipeStartFailure,
type EphemeralVmRecipeStartSuccess
} from './ephemeral-vm-recipe-runner'
import { cleanupFailedEphemeralVmStart } from './ephemeral-vm-failed-start-cleanup'
} from '../../shared/ephemeral-vm-recipe-runner'
import { cleanupFailedEphemeralVmStart } from './failed-start-cleanup'
import {
persistProvisionedEphemeralVmRuntime,
prepareEphemeralVmCompatibilityPersistence
} from './ephemeral-vm-runtime-provisioning-persistence'
import { getProvisionedRootResumeIntegrityError } from './ephemeral-vm-resume-integrity'
import { runControlledEphemeralVmRuntimeCleanup } from './ephemeral-vm-runtime-cleanup-control'
export { stopEphemeralVmRuntimeCleanup } from './ephemeral-vm-runtime-cleanup-control'
} from './runtime-provisioning-persistence'
import { getProvisionedRootResumeIntegrityError } from './resume-integrity'
import { runControlledEphemeralVmRuntimeCleanup } from './runtime-cleanup-control'
export type ProvisionEphemeralVmRuntimeArgs = {
userDataPath: string
@@ -2,9 +2,9 @@ import { mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, expect, it, vi } from 'vitest'
import { upsertEphemeralVmRuntime } from '../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../shared/ephemeral-vm-runtimes'
import { removeEphemeralVmRuntimeSshTarget } from './ephemeral-vm-runtime-ssh-cleanup'
import { upsertEphemeralVmRuntime } from '../../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../../shared/ephemeral-vm-runtimes'
import { removeEphemeralVmRuntimeSshTarget } from './runtime-ssh-cleanup'
const tempDirs: string[] = []
@@ -1,8 +1,8 @@
import {
listEphemeralVmRuntimes,
updateEphemeralVmRuntimeStatus
} from '../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../shared/ephemeral-vm-runtimes'
} from '../../shared/ephemeral-vm-runtime-store'
import type { EphemeralVmRuntimeRecord } from '../../shared/ephemeral-vm-runtimes'
export async function removeEphemeralVmRuntimeSshTarget(args: {
userDataPath: string
@@ -5,10 +5,10 @@ const mocks = vi.hoisted(() => ({
remove: vi.fn(async () => {})
}))
vi.mock('./ssh/targets/ssh-target-registry', () => ({
vi.mock('../ssh/targets/ssh-target-registry', () => ({
connectRegisteredSshTarget: mocks.connect
}))
vi.mock('./ipc/ssh/ssh', () => ({
vi.mock('../ipc/ssh/ssh', () => ({
getSshConnectionStore: () => ({
upsertRuntimeOwnedTarget: (runtimeId: string) => ({
id: `runtime-ssh-${runtimeId}`,
@@ -19,13 +19,13 @@ vi.mock('./ipc/ssh/ssh', () => ({
})
})
}))
vi.mock('./ipc/ssh/ssh-session-teardown', () => ({
vi.mock('../ipc/ssh/ssh-session-teardown', () => ({
disconnectRegisteredSshTarget: vi.fn(),
removeRegisteredSshTarget: mocks.remove
}))
import { connectRuntimeOwnedSshTarget } from './ephemeral-vm-runtime-ssh'
import { SSH_HOST_NOT_SERVED_MESSAGE } from './providers/ssh-host-not-served-error'
import { connectRuntimeOwnedSshTarget } from './runtime-ssh'
import { SSH_HOST_NOT_SERVED_MESSAGE } from '../providers/ssh-host-not-served-error'
const connection = {
type: 'ssh' as const,
@@ -1,12 +1,12 @@
import { getSshConnectionStore } from './ipc/ssh/ssh'
import { connectRegisteredSshTarget } from './ssh/targets/ssh-target-registry'
import { getSshConnectionStore } from '../ipc/ssh/ssh'
import { connectRegisteredSshTarget } from '../ssh/targets/ssh-target-registry'
import {
disconnectRegisteredSshTarget,
removeRegisteredSshTarget
} from './ipc/ssh/ssh-session-teardown'
import type { EphemeralVmRecipeConnection } from '../shared/ephemeral-vm-recipes'
import type { SshTarget } from '../shared/ssh-types'
import { SshHostNotServedError } from './providers/ssh-host-not-served-error'
} from '../ipc/ssh/ssh-session-teardown'
import type { EphemeralVmRecipeConnection } from '../../shared/ephemeral-vm-recipes'
import type { SshTarget } from '../../shared/ssh-types'
import { SshHostNotServedError } from '../providers/ssh-host-not-served-error'
export type RuntimeOwnedSshConnectionResult = {
targetId: string
@@ -17,7 +17,7 @@ vi.mock('electron', () => ({
removeHandler: vi.fn()
}
}))
vi.mock('../ephemeral-vm-runtime-ssh', () => ({
vi.mock('../ephemeral-vm/runtime-ssh', () => ({
connectRuntimeOwnedSshTarget: connect,
disconnectRuntimeOwnedSshTarget: vi.fn(async () => {}),
removeRuntimeOwnedSshTarget: vi.fn(async () => {})
@@ -26,7 +26,7 @@ vi.mock('./runtime-environments/runtime-environments', () => ({
invalidateRuntimeEnvironmentTransport: vi.fn()
}))
import type { Store } from '../persistence'
import type { Store } from '../persistence/loading-store/store'
import { listEphemeralVmRuntimes } from '../../shared/ephemeral-vm-runtime-store'
import { registerEphemeralVmHandlers } from './ephemeral-vm'
@@ -15,7 +15,7 @@ vi.mock('electron', () => ({
ipcMain: { handle: handleMock, removeHandler: vi.fn() }
}))
vi.mock('../ephemeral-vm-provisioned-root-source', () => ({
vi.mock('../ephemeral-vm/provisioned-root-source', () => ({
resolveProvisionedRootSource: resolveProvisionedRootSourceMock
}))
@@ -19,7 +19,7 @@ vi.mock('electron', () => ({
ipcMain: { handle: handleMock, removeHandler: removeHandlerMock }
}))
vi.mock('../ephemeral-vm-runtime-ssh', () => ({
vi.mock('../ephemeral-vm/runtime-ssh', () => ({
connectRuntimeOwnedSshTarget: connectRuntimeOwnedSshTargetMock,
disconnectRuntimeOwnedSshTarget: vi.fn(),
removeRuntimeOwnedSshTarget: vi.fn()
@@ -19,7 +19,7 @@ vi.mock('electron', () => ({
ipcMain: { handle: handleMock, removeHandler: removeHandlerMock }
}))
vi.mock('../ephemeral-vm-runtime-ssh', () => ({
vi.mock('../ephemeral-vm/runtime-ssh', () => ({
connectRuntimeOwnedSshTarget: vi.fn(),
disconnectRuntimeOwnedSshTarget: vi.fn(),
removeRuntimeOwnedSshTarget: removeRuntimeOwnedSshTargetMock
@@ -1,5 +1,5 @@
import { app, ipcMain } from 'electron'
import type { Store } from '../persistence'
import type { Store } from '../persistence/loading-store/store'
import {
listEphemeralVmRuntimes,
updateEphemeralVmRuntimeStatus
@@ -10,26 +10,26 @@ import {
getEphemeralVmRecipeResultPairingCode
} from '../../shared/ephemeral-vm-recipes'
import { updateEnvironmentFromPairingCode } from '../../shared/runtime-environment-store'
import { releaseEphemeralVmRuntimeEnvironments } from '../ephemeral-vm-runtime-environment-release'
import { releaseEphemeralVmRuntimeEnvironments } from '../ephemeral-vm/runtime-environment-release'
import {
cleanupEphemeralVmRuntime,
resumeEphemeralVmRuntime,
stopEphemeralVmRuntimeCleanup,
suspendEphemeralVmRuntime
} from '../ephemeral-vm-runtime-service'
import { removeEphemeralVmRuntimeSshTarget } from '../ephemeral-vm-runtime-ssh-cleanup'
} from '../ephemeral-vm/runtime-service'
import { stopEphemeralVmRuntimeCleanup } from '../ephemeral-vm/runtime-cleanup-control'
import { removeEphemeralVmRuntimeSshTarget } from '../ephemeral-vm/runtime-ssh-cleanup'
import {
buildEphemeralVmRecipeCleanupCommand,
buildEphemeralVmRecipeCleanupPayload
} from '../ephemeral-vm-recipe-runner'
} from '../../shared/ephemeral-vm-recipe-lifecycle-payload'
import {
connectRuntimeOwnedSshTarget,
disconnectRuntimeOwnedSshTarget,
removeRuntimeOwnedSshTarget
} from '../ephemeral-vm-runtime-ssh'
} from '../ephemeral-vm/runtime-ssh'
import { getRuntimeRecipeContext } from './ephemeral-vm-recipe-context'
import { invalidateRuntimeEnvironmentTransport } from './runtime-environments/runtime-environments'
import { attachEphemeralVmRuntimeToWorkspace } from '../ephemeral-vm-runtime-attachment'
import { attachEphemeralVmRuntimeToWorkspace } from '../ephemeral-vm/runtime-attachment'
export type EphemeralVmCleanupCommandResult = {
runtimeId: string
+1 -1
View File
@@ -35,7 +35,7 @@ vi.mock('electron', () => ({
}
}))
vi.mock('../ephemeral-vm-runtime-ssh', () => ({
vi.mock('../ephemeral-vm/runtime-ssh', () => ({
connectRuntimeOwnedSshTarget: connectRuntimeOwnedSshTargetMock,
disconnectRuntimeOwnedSshTarget: disconnectRuntimeOwnedSshTargetMock,
removeRuntimeOwnedSshTarget: removeRuntimeOwnedSshTargetMock
+4 -4
View File
@@ -1,5 +1,5 @@
import { app, ipcMain } from 'electron'
import type { Store } from '../persistence'
import type { Store } from '../persistence/loading-store/store'
import {
getEphemeralVmRecipeResultConnection,
type EphemeralVmRecipeDoctorResult
@@ -23,8 +23,8 @@ import {
import {
cleanupEphemeralVmRuntime,
provisionEphemeralVmRuntime
} from '../ephemeral-vm-runtime-service'
import { connectRuntimeOwnedSshTarget } from '../ephemeral-vm-runtime-ssh'
} from '../ephemeral-vm/runtime-service'
import { connectRuntimeOwnedSshTarget } from '../ephemeral-vm/runtime-ssh'
import {
getRecipeRepo,
listRecipeCatalog,
@@ -35,7 +35,7 @@ import {
import { registerEphemeralVmRuntimeHandlers } from './ephemeral-vm-runtime-handlers'
import type { PluginService } from '../plugins/plugin-service'
import { getApprovedPluginVmRecipes } from '../plugins/plugin-approved-vm-recipes'
import { resolveProvisionedRootSource } from '../ephemeral-vm-provisioned-root-source'
import { resolveProvisionedRootSource } from '../ephemeral-vm/provisioned-root-source'
const activeProvisionControllers = new Map<string, AbortController>()