Class: Microsandbox::Sandbox
- Inherits:
-
Object
- Object
- Microsandbox::Sandbox
- Defined in:
- lib/microsandbox/sandbox.rb
Overview
A running sandbox (microVM) — the primary entry point of the SDK.
Constant Summary collapse
- DISK_IMAGE_EXTENSIONS =
Recognized disk-image rootfs extensions, mirroring the upstream
DiskImageFormat::from_extension/FromStrset. Used by disk_image_rootfs? to gate thefstype:-vs-OCI check; keep in sync on a runtime-tag bump. %w[raw qcow2 vmdk].freeze
Class Method Summary collapse
-
.build_create_opts(image: nil, cpus: nil, max_cpus: nil, memory: nil, max_memory: nil, env: nil, workdir: nil, shell: nil, user: nil, hostname: nil, labels: nil, scripts: nil, entrypoint: nil, cmd: nil, ports: nil, ports_udp: nil, volumes: nil, network: nil, dns: nil, tls: nil, ipv4_pool: nil, ipv6_pool: nil, max_connections: nil, trust_host_cas: nil, rate_limiter: nil, vsock: nil, patches: nil, from_snapshot: nil, fstype: nil, init: nil, ephemeral: false, log_level: nil, quiet_logs: false, security: nil, root_disk: nil, oci_upper_size: nil, max_duration: nil, idle_timeout: nil, rlimits: nil, pull_policy: nil, registry_auth: nil, registry_insecure: false, registry_ca_certs: nil, secrets: nil, on_secret_violation: nil, detached: false, replace: false, replace_with_timeout: nil) ⇒ Object
private
Shared keyword-option builder for Sandbox.create/Sandbox.create_with_progress.
-
.create(name, **kwargs) {|sandbox| ... } ⇒ Sandbox, Object
Create and boot a sandbox.
-
.create_with_progress(name, **kwargs) ⇒ PullSession
Create a sandbox while streaming image-pull progress.
-
.get(name) ⇒ SandboxHandle
Fetch a controllable handle for a sandbox by name (running or not).
-
.list ⇒ SandboxPage
List the first page of sandboxes (default page size 20) as controllable handles.
-
.list_with(labels: {}, limit: nil, cursor: nil) ⇒ SandboxPage
List one configured page of sandboxes.
-
.remove(name) ⇒ nil
Remove a (stopped) sandbox by name.
-
.start(name, detached: false) ⇒ Sandbox
Restart a previously-defined sandbox by name.
Instance Method Summary collapse
-
#attach(command, args = [], cwd: nil, user: nil, env: nil, detach_keys: nil, rlimits: nil) ⇒ Integer
Attach an interactive terminal to a command in the sandbox.
-
#attach_default(cwd: nil, user: nil, env: nil, detach_keys: nil, rlimits: nil) ⇒ Integer
Attach an interactive terminal to the image's resolved OCI
ENTRYPOINTandCMD— the default workload (runtime v0.6.9). -
#attach_shell ⇒ Integer
Attach an interactive terminal running the sandbox's default shell.
-
#detach ⇒ nil
Detach this handle: disarm the stop-on-drop safety net so the sandbox keeps running after this handle is gone (and after this process exits).
-
#drain ⇒ nil
Trigger a graceful drain (SIGUSR1).
-
#exec(command, args = [], cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecOutput
Run a command (no shell interpretation) and collect its output.
-
#exec_default(cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecOutput
Run the image's resolved OCI
ENTRYPOINTandCMD— the default workload (runtime v0.6.9) — and collect output. -
#exec_default_stream(cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecHandle
Run the default workload (see #exec_default) and stream its output.
-
#exec_stream(command, args = [], cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecHandle
Run a command and stream its output as it arrives.
-
#fs ⇒ FS
Guest filesystem operations.
-
#initialize(native) ⇒ Sandbox
constructor
A new instance of Sandbox.
- #inspect ⇒ Object
-
#kill ⇒ nil
Force-kill the sandbox (SIGKILL).
-
#log_stream(sources: nil, since_ms: nil, from_cursor: nil, until_ms: nil, follow: false) ⇒ LogStream
Stream captured logs as they appear.
-
#logs(tail: nil, since_ms: nil, until_ms: nil, sources: nil) ⇒ Array<LogEntry>
Read captured logs.
-
#metrics ⇒ Metrics
Latest resource-usage snapshot.
-
#metrics_stream(interval: 1.0) ⇒ MetricsStream
Stream resource-usage snapshots, one per interval tick, until the sandbox stops.
-
#modify(**kwargs) ⇒ ModificationPlan
Plan or apply a live modification of this sandbox: resize CPU/memory, adjust env/labels/workdir, and rotate/remove secrets, without recreating the sandbox.
-
#name ⇒ String
The sandbox name.
-
#owns_lifecycle? ⇒ Boolean
Whether this handle owns the sandbox process lifecycle (i.e. stopping it or dropping the handle terminates the sandbox).
-
#ping ⇒ PingResult
Health-check the guest agent without refreshing the idle timer.
-
#shell(script, cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecOutput
Run a shell script (pipes, redirects, etc. allowed) and collect output.
-
#shell_stream(script, cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecHandle
Run a shell script and stream its output as it arrives.
-
#ssh ⇒ SshOps
SSH access to the sandbox — open a native in-process SSH client or prepare a reusable server endpoint.
-
#status ⇒ Symbol
The live status, fetched from the backend (a round-trip per call).
-
#stop ⇒ nil
Gracefully stop the sandbox (SIGTERM→SIGKILL escalation, 10s default) and wait for it to terminate.
-
#stop_and_wait ⇒ ExitStatus
Gracefully stop, then wait for the process to exit.
-
#touch ⇒ TouchResult
Explicitly refresh this sandbox's idle-activity timer (resetting any
idle_timeout:countdown). -
#wait ⇒ ExitStatus
Wait for the sandbox process to exit.
Constructor Details
#initialize(native) ⇒ Sandbox
Returns a new instance of Sandbox.
1195 1196 1197 |
# File 'lib/microsandbox/sandbox.rb', line 1195 def initialize(native) @native = native end |
Class Method Details
.build_create_opts(image: nil, cpus: nil, max_cpus: nil, memory: nil, max_memory: nil, env: nil, workdir: nil, shell: nil, user: nil, hostname: nil, labels: nil, scripts: nil, entrypoint: nil, cmd: nil, ports: nil, ports_udp: nil, volumes: nil, network: nil, dns: nil, tls: nil, ipv4_pool: nil, ipv6_pool: nil, max_connections: nil, trust_host_cas: nil, rate_limiter: nil, vsock: nil, patches: nil, from_snapshot: nil, fstype: nil, init: nil, ephemeral: false, log_level: nil, quiet_logs: false, security: nil, root_disk: nil, oci_upper_size: nil, max_duration: nil, idle_timeout: nil, rlimits: nil, pull_policy: nil, registry_auth: nil, registry_insecure: false, registry_ca_certs: nil, secrets: nil, on_secret_violation: nil, detached: false, replace: false, replace_with_timeout: nil) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Shared keyword-option builder for create/create_with_progress.
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
# File 'lib/microsandbox/sandbox.rb', line 439 def build_create_opts(image: nil, cpus: nil, max_cpus: nil, memory: nil, max_memory: nil, env: nil, workdir: nil, shell: nil, user: nil, hostname: nil, labels: nil, scripts: nil, entrypoint: nil, cmd: nil, ports: nil, ports_udp: nil, volumes: nil, network: nil, dns: nil, tls: nil, ipv4_pool: nil, ipv6_pool: nil, max_connections: nil, trust_host_cas: nil, rate_limiter: nil, vsock: nil, patches: nil, from_snapshot: nil, fstype: nil, init: nil, ephemeral: false, log_level: nil, quiet_logs: false, security: nil, root_disk: nil, oci_upper_size: nil, max_duration: nil, idle_timeout: nil, rlimits: nil, pull_policy: nil, registry_auth: nil, registry_insecure: false, registry_ca_certs: nil, secrets: nil, on_secret_violation: nil, detached: false, replace: false, replace_with_timeout: nil) # A sandbox boots from exactly one rootfs source. The core would reject a # contradictory pair, but only after a runtime round-trip; fail fast and # clearly here (the Python SDK validates this the same way). if image && from_snapshot raise ArgumentError, "provide either image: or from_snapshot:, not both" end if root_disk && oci_upper_size raise ArgumentError, "pass either root_disk: or oci_upper_size:, not both" end Microsandbox.ensure_runtime! # `fstype:` names the inner filesystem of a disk-image rootfs, so it only # applies when `image:` is a disk-image path (a local path ending in # .raw/.qcow2/.vmdk). Routing an OCI ref (e.g. "python") through the # disk-image builder would make the core treat it as a host disk path and # fail at boot, so reject the combination up front instead of forwarding a # value the native layer can't honour. if fstype && !disk_image_rootfs?(image) raise ArgumentError, "fstype: only applies to a disk-image rootfs; image: must be a local " \ "path ending in .raw, .qcow2, or .vmdk (got #{image.inspect}). " \ "OCI references auto-detect their filesystem — drop fstype:." end opts = {} opts["image"] = image.to_s if image opts["from_snapshot"] = from_snapshot.to_s if from_snapshot opts["fstype"] = fstype.to_s if fstype opts["cpus"] = Integer(cpus) if cpus opts["max_cpus"] = Integer(max_cpus) if max_cpus opts["memory"] = Integer(memory) if memory opts["max_memory"] = Integer(max_memory) if max_memory opts["workdir"] = workdir.to_s if workdir opts["shell"] = shell.to_s if shell opts["user"] = user.to_s if user opts["hostname"] = hostname.to_s if hostname opts["env"] = stringify(env) if env opts["labels"] = stringify(labels) if labels opts["scripts"] = stringify(scripts) if scripts # entrypoint/cmd: an explicit empty Array clears the image's value # (blocking the image-config merge), so presence is keyed on the kwarg # itself — nil (the default) inherits from the image. opts["entrypoint"] = Array(entrypoint).map(&:to_s) unless entrypoint.nil? opts["cmd"] = Array(cmd).map(&:to_s) unless cmd.nil? opts["ports"] = intify_ports(ports) if ports opts["ports_udp"] = intify_ports(ports_udp) if ports_udp opts["volumes"] = normalize_volumes(volumes) if volumes opts["patches"] = normalize_patches(patches) if patches apply_network_opts(opts, network) unless network.nil? opts["dns"] = normalize_dns(dns) if dns opts["tls"] = normalize_tls(tls) if tls opts["ipv4_pool"] = ipv4_pool.to_s if ipv4_pool opts["ipv6_pool"] = ipv6_pool.to_s if ipv6_pool opts["max_connections"] = Integer(max_connections) if max_connections set_bool(opts, "trust_host_cas", trust_host_cas) opts["rate_limiter"] = normalize_rate_limiter(rate_limiter) if rate_limiter opts["vsock"] = normalize_vsock(vsock) if vsock opts["log_level"] = log_level.to_s if log_level opts["quiet_logs"] = true if quiet_logs opts["security"] = security.to_s if security if oci_upper_size warn "Microsandbox: oci_upper_size: is deprecated; use root_disk: " \ "(an Integer size in MiB, or RootDisk.managed/tmpfs/disk)", uplevel: 2 opts["root_disk"] = coerce_root_disk_size(oci_upper_size, "oci_upper_size:") elsif root_disk opts["root_disk"] = normalize_root_disk(root_disk) end opts["max_duration"] = Integer(max_duration) if max_duration opts["idle_timeout"] = Integer(idle_timeout) if idle_timeout opts["rlimits"] = normalize_rlimits(rlimits) if rlimits opts["pull_policy"] = pull_policy.to_s if pull_policy apply_registry_opts(opts, registry_auth, registry_insecure, registry_ca_certs) opts["secrets"] = normalize_secrets(secrets) if secrets opts["on_secret_violation"] = normalize_violation(on_secret_violation) if on_secret_violation opts["init"] = normalize_init(init) unless init.nil? opts["ephemeral"] = true if ephemeral opts["detached"] = true if detached if replace_with_timeout opts["replace_with_timeout"] = coerce_duration(replace_with_timeout, "replace_with_timeout") elsif replace opts["replace"] = true end opts end |
.create(name, **kwargs) {|sandbox| ... } ⇒ Sandbox, Object
Create and boot a sandbox.
When a block is given the sandbox is yielded and stopped automatically when the block returns (the block's value is returned); otherwise the live Microsandbox::Sandbox is returned and you are responsible for calling #stop.
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 |
# File 'lib/microsandbox/sandbox.rb', line 401 def create(name, **kwargs, &block) opts = build_create_opts(**kwargs) sandbox = new(Native::Sandbox.create(name.to_s, opts)) return sandbox unless block_given? begin yield sandbox ensure begin sandbox.stop rescue Microsandbox::Error # best-effort cleanup; ignore stop failures during teardown end end end |
.create_with_progress(name, **kwargs) ⇒ PullSession
Create a sandbox while streaming image-pull progress. Accepts the same
options as create; returns a PullSession — iterate it (an
Enumerable of progress-event Hashes, each with a "kind"), then call
PullSession#sandbox for the booted Microsandbox::Sandbox. Mirrors the Python
create_with_progress / Node createWithPullProgress.
423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/microsandbox/sandbox.rb', line 423 def create_with_progress(name, **kwargs) # Unlike {create}, this has no block form: the booted sandbox is reached # via {PullSession#sandbox} (after iterating progress) and stopped by the # caller. A block would be silently dropped — and the sandbox leaked — so # reject it loudly rather than let a `create`-style block call misfire. if block_given? raise ArgumentError, "create_with_progress takes no block; iterate the returned PullSession " \ "for progress, then call #sandbox and stop it when done" end opts = build_create_opts(**kwargs) PullSession.new(Native::Sandbox.create_with_progress(name.to_s, opts)) end |
.get(name) ⇒ SandboxHandle
Fetch a controllable handle for a sandbox by name (running or not).
546 547 548 |
# File 'lib/microsandbox/sandbox.rb', line 546 def get(name) SandboxHandle.new(Native::Sandbox.get(name.to_s)) end |
.list ⇒ SandboxPage
List the first page of sandboxes (default page size 20) as controllable handles. Cursor-paginated as of runtime v0.6.8 — follow Microsandbox::SandboxPage#next_cursor via list_with for subsequent pages.
554 555 556 |
# File 'lib/microsandbox/sandbox.rb', line 554 def list build_page(Native::Sandbox.list) end |
.list_with(labels: {}, limit: nil, cursor: nil) ⇒ SandboxPage
List one configured page of sandboxes.
564 565 566 567 568 569 |
# File 'lib/microsandbox/sandbox.rb', line 564 def list_with(labels: {}, limit: nil, cursor: nil) opts = {"labels" => stringify(labels)} opts["limit"] = Integer(limit) if limit opts["cursor"] = cursor.to_s if cursor build_page(Native::Sandbox.list_with(opts)) end |
.remove(name) ⇒ nil
Remove a (stopped) sandbox by name.
573 574 575 576 |
# File 'lib/microsandbox/sandbox.rb', line 573 def remove(name) Native::Sandbox.remove(name.to_s) nil end |
.start(name, detached: false) ⇒ Sandbox
Restart a previously-defined sandbox by name.
539 540 541 542 |
# File 'lib/microsandbox/sandbox.rb', line 539 def start(name, detached: false) Microsandbox.ensure_runtime! new(Native::Sandbox.start(name.to_s, {"detached" => detached})) end |
Instance Method Details
#attach(command, args = [], cwd: nil, user: nil, env: nil, detach_keys: nil, rlimits: nil) ⇒ Integer
Attach an interactive terminal to a command in the sandbox.
Puts the host terminal into raw mode and forwards keystrokes (and
SIGWINCH resizes) to the guest until the command exits or the detach
sequence is typed. Requires a real TTY on stdin/stdout, so it is for CLI
use, not library/automation code (use #exec/#exec_stream there). Blocks
until the session ends. Mirrors the official SDKs' attach.
1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 |
# File 'lib/microsandbox/sandbox.rb', line 1302 def attach(command, args = [], cwd: nil, user: nil, env: nil, detach_keys: nil, rlimits: nil) opts = {} opts["cwd"] = cwd.to_s if cwd opts["user"] = user.to_s if user opts["env"] = env.each_with_object({}) { |(k, v), a| a[k.to_s] = v.to_s } if env opts["detach_keys"] = detach_keys.to_s if detach_keys if rlimits opts["rlimits"] = rlimits.map do |resource, limit| soft, hard = limit.is_a?(Array) ? [limit[0], limit[1]] : [limit, limit] [resource.to_s, Integer(soft), Integer(hard)] end end @native.attach(command.to_s, Array(args).map(&:to_s), opts) end |
#attach_default(cwd: nil, user: nil, env: nil, detach_keys: nil, rlimits: nil) ⇒ Integer
Attach an interactive terminal to the image's resolved OCI ENTRYPOINT
and CMD — the default workload (runtime v0.6.9). See #attach for the
host-TTY requirements and #exec_default for default-workload semantics.
1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 |
# File 'lib/microsandbox/sandbox.rb', line 1335 def attach_default(cwd: nil, user: nil, env: nil, detach_keys: nil, rlimits: nil) opts = {} opts["cwd"] = cwd.to_s if cwd opts["user"] = user.to_s if user opts["env"] = env.each_with_object({}) { |(k, v), a| a[k.to_s] = v.to_s } if env opts["detach_keys"] = detach_keys.to_s if detach_keys if rlimits opts["rlimits"] = rlimits.map do |resource, limit| soft, hard = limit.is_a?(Array) ? [limit[0], limit[1]] : [limit, limit] [resource.to_s, Integer(soft), Integer(hard)] end end @native.attach_default(opts) end |
#attach_shell ⇒ Integer
Attach an interactive terminal running the sandbox's default shell. See #attach for the host-TTY requirements.
1320 1321 1322 |
# File 'lib/microsandbox/sandbox.rb', line 1320 def attach_shell @native.attach_shell end |
#detach ⇒ nil
Detach this handle: disarm the stop-on-drop safety net so the sandbox keeps running after this handle is gone (and after this process exits).
1539 1540 1541 1542 |
# File 'lib/microsandbox/sandbox.rb', line 1539 def detach @native.detach nil end |
#drain ⇒ nil
Trigger a graceful drain (SIGUSR1).
1512 1513 1514 1515 |
# File 'lib/microsandbox/sandbox.rb', line 1512 def drain @native.drain nil end |
#exec(command, args = [], cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecOutput
Run a command (no shell interpretation) and collect its output.
1221 1222 1223 1224 |
# File 'lib/microsandbox/sandbox.rb', line 1221 def exec(command, args = [], cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ExecOutput.new(@native.exec(command.to_s, Array(args).map(&:to_s), exec_opts(cwd:, user:, env:, timeout:, tty:, stdin:, rlimits:))) end |
#exec_default(cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecOutput
1242 1243 1244 1245 1246 |
# File 'lib/microsandbox/sandbox.rb', line 1242 def exec_default(cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ExecOutput.new(@native.exec_default( exec_opts(cwd:, user:, env:, timeout:, tty:, stdin:, rlimits:) )) end |
#exec_default_stream(cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecHandle
Like #exec_stream, timeout: is accepted but not applied on
the streaming path.
Run the default workload (see #exec_default) and stream its output.
1279 1280 1281 1282 1283 |
# File 'lib/microsandbox/sandbox.rb', line 1279 def exec_default_stream(cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ExecHandle.new(@native.exec_default_stream( exec_opts(cwd:, user:, env:, timeout:, tty:, stdin:, rlimits:, pipe_ok: true) )) end |
#exec_stream(command, args = [], cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecHandle
Run a command and stream its output as it arrives.
Pass stdin: :pipe to feed the process interactively: ExecHandle#stdin
then returns a writable sink; close it to send EOF (a process like cat
that reads until EOF will otherwise block forever).
1260 1261 1262 1263 |
# File 'lib/microsandbox/sandbox.rb', line 1260 def exec_stream(command, args = [], cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ExecHandle.new(@native.exec_stream(command.to_s, Array(args).map(&:to_s), exec_opts(cwd:, user:, env:, timeout:, tty:, stdin:, rlimits:, pipe_ok: true))) end |
#fs ⇒ FS
Guest filesystem operations.
1352 1353 1354 |
# File 'lib/microsandbox/sandbox.rb', line 1352 def fs @fs ||= FS.new(@native) end |
#inspect ⇒ Object
1544 1545 1546 |
# File 'lib/microsandbox/sandbox.rb', line 1544 def inspect "#<Microsandbox::Sandbox name=#{name.inspect}>" end |
#kill ⇒ nil
Force-kill the sandbox (SIGKILL).
1505 1506 1507 1508 |
# File 'lib/microsandbox/sandbox.rb', line 1505 def kill @native.kill nil end |
#log_stream(sources: nil, since_ms: nil, from_cursor: nil, until_ms: nil, follow: false) ⇒ LogStream
Stream captured logs as they appear.
1478 1479 1480 1481 1482 1483 1484 1485 1486 |
# File 'lib/microsandbox/sandbox.rb', line 1478 def log_stream(sources: nil, since_ms: nil, from_cursor: nil, until_ms: nil, follow: false) opts = {} opts["sources"] = Array(sources).map(&:to_s) if sources opts["since_ms"] = Float(since_ms) if since_ms opts["from_cursor"] = from_cursor.to_s if from_cursor opts["until_ms"] = Float(until_ms) if until_ms opts["follow"] = true if follow LogStream.new(@native.log_stream(opts)) end |
#logs(tail: nil, since_ms: nil, until_ms: nil, sources: nil) ⇒ Array<LogEntry>
Read captured logs.
1443 1444 1445 1446 1447 1448 1449 1450 |
# File 'lib/microsandbox/sandbox.rb', line 1443 def logs(tail: nil, since_ms: nil, until_ms: nil, sources: nil) opts = {} opts["tail"] = Integer(tail) if tail opts["since_ms"] = Float(since_ms) if since_ms opts["until_ms"] = Float(until_ms) if until_ms opts["sources"] = Array(sources).map(&:to_s) if sources @native.logs(opts).map { |entry| LogEntry.new(entry) } end |
#metrics ⇒ Metrics
Latest resource-usage snapshot.
Raises a Error ("sandbox N has no live metrics slot") when
called in the brief window right after create returns, before the
runtime has registered the sandbox's metrics slot. On v0.6.x runtimes
the spawn handshake no longer blocks create until the first sample is
written, so the slot goes live a beat after boot (within a few hundred
milliseconds); retry for that window rather than treating the first failure
as fatal.
1375 1376 1377 |
# File 'lib/microsandbox/sandbox.rb', line 1375 def metrics Metrics.new(@native.metrics) end |
#metrics_stream(interval: 1.0) ⇒ MetricsStream
Stream resource-usage snapshots, one per interval tick, until the sandbox stops. Requires metrics to be enabled for the sandbox.
The first tick fires immediately, so opening the stream right after create can hit the same metrics-slot startup window as #metrics and yield a transient "no live metrics slot" error on that first tick. Because the stream is single-pass (a drained or errored stream is spent), make sure the slot is live before opening it — e.g. retry #metrics until it succeeds (the slot goes live within a few hundred milliseconds of boot), then call #metrics_stream.
1464 1465 1466 |
# File 'lib/microsandbox/sandbox.rb', line 1464 def metrics_stream(interval: 1.0) MetricsStream.new(@native.metrics_stream(coerce_duration(interval, "interval"))) end |
#modify(**kwargs) ⇒ ModificationPlan
Plan or apply a live modification of this sandbox: resize CPU/memory,
adjust env/labels/workdir, and rotate/remove secrets, without recreating
the sandbox. The apply is all-or-nothing under the chosen policy:: the
default :no_restart applies only changes that are live-capable right
now and raises if any requested change needs a restart (on a running
sandbox that includes env/labels/workdir and adding a secret — rotating
or removing an existing one is live). Pass policy: :next_start to
persist restart-required changes for the next start, or :restart to
restart and apply them now; use dry_run: true to preview each change's
disposition without applying anything. Mirrors the official SDKs'
modify. Returns a ModificationPlan classifying each change.
1430 1431 1432 1433 |
# File 'lib/microsandbox/sandbox.rb', line 1430 def modify(**kwargs) opts = Sandbox.send(:build_modify_opts, **kwargs) ModificationPlan.new(JSON.parse(@native.modify(opts))) end |
#name ⇒ String
Returns the sandbox name.
1200 1201 1202 |
# File 'lib/microsandbox/sandbox.rb', line 1200 def name @native.name end |
#owns_lifecycle? ⇒ Boolean
Returns whether this handle owns the sandbox process lifecycle (i.e. stopping it or dropping the handle terminates the sandbox).
1532 1533 1534 |
# File 'lib/microsandbox/sandbox.rb', line 1532 def owns_lifecycle? @native.owns_lifecycle end |
#ping ⇒ PingResult
Health-check the guest agent without refreshing the idle timer. Sends
core.ping to the running sandbox and reports the round-trip latency.
Mirrors the official SDKs' ping.
1383 1384 1385 |
# File 'lib/microsandbox/sandbox.rb', line 1383 def ping PingResult.new(@native.ping) end |
#shell(script, cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecOutput
Run a shell script (pipes, redirects, etc. allowed) and collect output.
1228 1229 1230 1231 |
# File 'lib/microsandbox/sandbox.rb', line 1228 def shell(script, cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ExecOutput.new(@native.shell(script.to_s, exec_opts(cwd:, user:, env:, timeout:, tty:, stdin:, rlimits:))) end |
#shell_stream(script, cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ⇒ ExecHandle
Like #exec_stream, timeout: is accepted but not applied on
the streaming path.
Run a shell script and stream its output as it arrives.
1269 1270 1271 1272 |
# File 'lib/microsandbox/sandbox.rb', line 1269 def shell_stream(script, cwd: nil, user: nil, env: nil, timeout: nil, tty: false, stdin: nil, rlimits: nil) ExecHandle.new(@native.shell_stream(script.to_s, exec_opts(cwd:, user:, env:, timeout:, tty:, stdin:, rlimits:, pipe_ok: true))) end |
#ssh ⇒ SshOps
SSH access to the sandbox — open a native in-process SSH client or prepare a reusable server endpoint.
1361 1362 1363 |
# File 'lib/microsandbox/sandbox.rb', line 1361 def ssh SshOps.new(@native) end |
#status ⇒ Symbol
The live status, fetched from the backend (a round-trip per call).
1526 1527 1528 |
# File 'lib/microsandbox/sandbox.rb', line 1526 def status @native.status.to_sym end |
#stop ⇒ nil
Gracefully stop the sandbox (SIGTERM→SIGKILL escalation, 10s default) and
wait for it to terminate. For a custom timeout or fire-and-return
request_* control, fetch a Microsandbox::SandboxHandle via get.
1492 1493 1494 1495 |
# File 'lib/microsandbox/sandbox.rb', line 1492 def stop @native.stop nil end |
#stop_and_wait ⇒ ExitStatus
Gracefully stop, then wait for the process to exit.
1499 1500 1501 |
# File 'lib/microsandbox/sandbox.rb', line 1499 def stop_and_wait ExitStatus.new(@native.stop_and_wait) end |
#touch ⇒ TouchResult
Explicitly refresh this sandbox's idle-activity timer (resetting any
idle_timeout: countdown). Mirrors the official SDKs' touch.
1390 1391 1392 |
# File 'lib/microsandbox/sandbox.rb', line 1390 def touch TouchResult.new(@native.touch) end |
#wait ⇒ ExitStatus
Wait for the sandbox process to exit.
1519 1520 1521 |
# File 'lib/microsandbox/sandbox.rb', line 1519 def wait ExitStatus.new(@native.wait) end |