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.
Class Method Summary collapse
-
.create(name, image: nil, cpus: nil, memory: nil, env: nil, workdir: nil, shell: nil, user: nil, hostname: nil, labels: nil, scripts: nil, entrypoint: nil, ports: nil, ports_udp: nil, volumes: nil, network: nil, patches: nil, from_snapshot: nil, log_level: nil, quiet_logs: false, security: 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, detached: false, replace: false, replace_with_timeout: nil) {|sandbox| ... } ⇒ Sandbox, Object
Create and boot a sandbox.
-
.get(name) ⇒ SandboxInfo
Fetch metadata for a sandbox by name.
-
.list ⇒ Array<SandboxInfo>
List all sandboxes.
-
.list_with(labels: {}) ⇒ Array<SandboxInfo>
List sandboxes carrying all of the given labels (AND-matched).
-
.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_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).
-
#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_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(timeout: nil) ⇒ 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.
-
#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).
-
#request_drain ⇒ nil
Request a graceful drain and return immediately, without waiting.
-
#request_kill ⇒ nil
Send the force-kill request and return immediately, without waiting.
-
#request_stop ⇒ nil
Send the graceful-shutdown request and return immediately, without waiting for the sandbox to terminate.
-
#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.
-
#stop(timeout: nil) ⇒ nil
Gracefully stop the sandbox (and wait for it to terminate).
-
#wait_until_stopped ⇒ SandboxStopResult
Block until the sandbox is observed in a terminal (non-running) state.
Constructor Details
#initialize(native) ⇒ Sandbox
Returns a new instance of Sandbox.
343 344 345 |
# File 'lib/microsandbox/sandbox.rb', line 343 def initialize(native) @native = native end |
Class Method Details
.create(name, image: nil, cpus: nil, memory: nil, env: nil, workdir: nil, shell: nil, user: nil, hostname: nil, labels: nil, scripts: nil, entrypoint: nil, ports: nil, ports_udp: nil, volumes: nil, network: nil, patches: nil, from_snapshot: nil, log_level: nil, quiet_logs: false, security: 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, detached: false, replace: false, replace_with_timeout: nil) {|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.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/microsandbox/sandbox.rb', line 145 def create(name, image: nil, cpus: nil, memory: nil, env: nil, workdir: nil, shell: nil, user: nil, hostname: nil, labels: nil, scripts: nil, entrypoint: nil, ports: nil, ports_udp: nil, volumes: nil, network: nil, patches: nil, from_snapshot: nil, log_level: nil, quiet_logs: false, security: 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, detached: false, replace: false, replace_with_timeout: nil) Microsandbox.ensure_runtime! opts = {} opts["image"] = image.to_s if image opts["from_snapshot"] = from_snapshot.to_s if from_snapshot opts["cpus"] = Integer(cpus) if cpus opts["memory"] = Integer(memory) if 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 opts["entrypoint"] = Array(entrypoint).map(&:to_s) if entrypoint 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["log_level"] = log_level.to_s if log_level opts["quiet_logs"] = true if quiet_logs opts["security"] = security.to_s if security opts["oci_upper_size"] = Integer(oci_upper_size) if oci_upper_size 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["detached"] = true if detached if replace_with_timeout opts["replace_with_timeout"] = Float(replace_with_timeout) elsif replace opts["replace"] = true end 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 |
.get(name) ⇒ SandboxInfo
Fetch metadata for a sandbox by name.
214 215 216 |
# File 'lib/microsandbox/sandbox.rb', line 214 def get(name) SandboxInfo.new(Native::Sandbox.get(name.to_s)) end |
.list ⇒ Array<SandboxInfo>
List all sandboxes.
220 221 222 |
# File 'lib/microsandbox/sandbox.rb', line 220 def list Native::Sandbox.list.map { |info| SandboxInfo.new(info) } end |
.list_with(labels: {}) ⇒ Array<SandboxInfo>
List sandboxes carrying all of the given labels (AND-matched).
227 228 229 230 |
# File 'lib/microsandbox/sandbox.rb', line 227 def list_with(labels: {}) opts = { "labels" => stringify(labels) } Native::Sandbox.list_with(opts).map { |info| SandboxInfo.new(info) } end |
.remove(name) ⇒ nil
Remove a (stopped) sandbox by name.
234 235 236 237 |
# File 'lib/microsandbox/sandbox.rb', line 234 def remove(name) Native::Sandbox.remove(name.to_s) nil end |
.start(name, detached: false) ⇒ Sandbox
Restart a previously-defined sandbox by name.
207 208 209 210 |
# File 'lib/microsandbox/sandbox.rb', line 207 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`.
407 408 409 410 411 412 413 414 415 416 417 418 419 420 |
# File 'lib/microsandbox/sandbox.rb', line 407 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_shell ⇒ Integer
Attach an interactive terminal running the sandbox’s default shell. See #attach for the host-TTY requirements.
425 426 427 |
# File 'lib/microsandbox/sandbox.rb', line 425 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).
548 549 550 551 |
# File 'lib/microsandbox/sandbox.rb', line 548 def detach @native.detach 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.
363 364 365 366 |
# File 'lib/microsandbox/sandbox.rb', line 363 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_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.
378 379 380 381 |
# File 'lib/microsandbox/sandbox.rb', line 378 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:))) end |
#fs ⇒ FS
Guest filesystem operations.
431 432 433 |
# File 'lib/microsandbox/sandbox.rb', line 431 def fs @fs ||= FS.new(@native) end |
#inspect ⇒ Object
553 554 555 |
# File 'lib/microsandbox/sandbox.rb', line 553 def inspect "#<Microsandbox::Sandbox name=#{name.inspect}>" end |
#kill(timeout: nil) ⇒ nil
Force-kill the sandbox (SIGKILL).
506 507 508 509 |
# File 'lib/microsandbox/sandbox.rb', line 506 def kill(timeout: nil) @native.kill(timeout && Float(timeout)) nil end |
#log_stream(sources: nil, since_ms: nil, from_cursor: nil, until_ms: nil, follow: false) ⇒ LogStream
Stream captured logs as they appear.
485 486 487 488 489 490 491 492 493 |
# File 'lib/microsandbox/sandbox.rb', line 485 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.
458 459 460 461 462 463 464 465 |
# File 'lib/microsandbox/sandbox.rb', line 458 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.
446 447 448 |
# File 'lib/microsandbox/sandbox.rb', line 446 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.
471 472 473 |
# File 'lib/microsandbox/sandbox.rb', line 471 def metrics_stream(interval: 1.0) MetricsStream.new(@native.metrics_stream(Float(interval))) end |
#name ⇒ String
Returns the sandbox name.
348 349 350 |
# File 'lib/microsandbox/sandbox.rb', line 348 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).
541 542 543 |
# File 'lib/microsandbox/sandbox.rb', line 541 def owns_lifecycle? @native.owns_lifecycle end |
#request_drain ⇒ nil
Request a graceful drain and return immediately, without waiting.
528 529 530 531 |
# File 'lib/microsandbox/sandbox.rb', line 528 def request_drain @native.request_drain nil end |
#request_kill ⇒ nil
Send the force-kill request and return immediately, without waiting.
521 522 523 524 |
# File 'lib/microsandbox/sandbox.rb', line 521 def request_kill @native.request_kill nil end |
#request_stop ⇒ nil
Send the graceful-shutdown request and return immediately, without waiting for the sandbox to terminate. Pair with #wait_until_stopped.
514 515 516 517 |
# File 'lib/microsandbox/sandbox.rb', line 514 def request_stop @native.request_stop nil 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.
370 371 372 373 |
# File 'lib/microsandbox/sandbox.rb', line 370 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
Run a shell script and stream its output as it arrives.
385 386 387 388 |
# File 'lib/microsandbox/sandbox.rb', line 385 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:))) end |
#ssh ⇒ SshOps
SSH access to the sandbox — open a native in-process SSH client or prepare a reusable server endpoint.
440 441 442 |
# File 'lib/microsandbox/sandbox.rb', line 440 def ssh SshOps.new(@native) end |
#stop(timeout: nil) ⇒ nil
Gracefully stop the sandbox (and wait for it to terminate).
498 499 500 501 |
# File 'lib/microsandbox/sandbox.rb', line 498 def stop(timeout: nil) @native.stop(timeout && Float(timeout)) nil end |
#wait_until_stopped ⇒ SandboxStopResult
Block until the sandbox is observed in a terminal (non-running) state.
535 536 537 |
# File 'lib/microsandbox/sandbox.rb', line 535 def wait_until_stopped SandboxStopResult.new(@native.wait_until_stopped) end |