add vm create and vm start commands, refactor ensure to delegate to them
This commit is contained in:
parent
e23e84655d
commit
9aac8298c9
27
src/cli.ts
27
src/cli.ts
|
|
@ -602,6 +602,33 @@ program
|
|||
|
||||
const vmCmd = program.command("vm").description("Manage the sandlot VM")
|
||||
|
||||
vmCmd
|
||||
.command("create")
|
||||
.description("Create and provision the VM")
|
||||
.action(async () => {
|
||||
const spin = spinner("Creating VM")
|
||||
try {
|
||||
await vm.create((msg) => { spin.text = msg })
|
||||
spin.succeed("VM created")
|
||||
} catch (err) {
|
||||
spin.fail(String((err as Error).message ?? err))
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
|
||||
vmCmd
|
||||
.command("start")
|
||||
.description("Start the VM")
|
||||
.action(async () => {
|
||||
try {
|
||||
await vm.start()
|
||||
console.log("✔ VM started")
|
||||
} catch (err) {
|
||||
console.error(`✖ ${(err as Error).message ?? err}`)
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
|
||||
vmCmd
|
||||
.command("shell")
|
||||
.description("Open a shell in the VM")
|
||||
|
|
|
|||
42
src/vm.ts
42
src/vm.ts
|
|
@ -25,22 +25,15 @@ function requireContainer(): void {
|
|||
}
|
||||
}
|
||||
|
||||
/** Ensure the sandlot container exists and is running. Creates and provisions on first use. */
|
||||
export async function ensure(log?: (msg: string) => void): Promise<void> {
|
||||
/** Create and provision the container from scratch. Fails if it already exists. */
|
||||
export async function create(log?: (msg: string) => void): Promise<void> {
|
||||
requireContainer()
|
||||
|
||||
// Ensure the container daemon is running
|
||||
await $`container system start`.nothrow().quiet()
|
||||
|
||||
const s = await status()
|
||||
if (s === "running") return
|
||||
|
||||
if (s === "stopped") {
|
||||
await $`container start ${CONTAINER_NAME}`.quiet()
|
||||
return
|
||||
if (s !== "missing") {
|
||||
throw new Error("Container already exists. Use 'sandlot vm destroy' first to recreate it.")
|
||||
}
|
||||
|
||||
// Create from scratch
|
||||
const home = homedir()
|
||||
log?.("Pulling image & creating container")
|
||||
await $`container run -d --name ${CONTAINER_NAME} -m 4G --mount type=bind,source=${home}/dev,target=/host,readonly -v ${home}/.sandlot:/sandlot ubuntu:24.04 sleep infinity`.quiet()
|
||||
|
|
@ -112,6 +105,33 @@ echo '${claudeJson}' > ~/.claude.json
|
|||
`}`.quiet()
|
||||
}
|
||||
|
||||
/** Start a stopped container. */
|
||||
export async function start(): Promise<void> {
|
||||
requireContainer()
|
||||
const s = await status()
|
||||
if (s === "running") return
|
||||
if (s === "missing") throw new Error("Container does not exist. Use 'sandlot vm create' first.")
|
||||
await $`container start ${CONTAINER_NAME}`.quiet()
|
||||
}
|
||||
|
||||
/** Ensure the sandlot container exists and is running. Creates and provisions on first use. */
|
||||
export async function ensure(log?: (msg: string) => void): Promise<void> {
|
||||
requireContainer()
|
||||
|
||||
// Ensure the container daemon is running
|
||||
await $`container system start`.nothrow().quiet()
|
||||
|
||||
const s = await status()
|
||||
if (s === "running") return
|
||||
|
||||
if (s === "stopped") {
|
||||
await start()
|
||||
return
|
||||
}
|
||||
|
||||
await create(log)
|
||||
}
|
||||
|
||||
/** Check container status. */
|
||||
export async function status(): Promise<"running" | "stopped" | "missing"> {
|
||||
const result = await $`container list --format json --all`.nothrow().quiet().text()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user