microsandbox-rb 0.5.7
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +94 -0
- data/Cargo.lock +7455 -0
- data/Cargo.toml +16 -0
- data/DESIGN.md +159 -0
- data/LICENSE +201 -0
- data/README.md +328 -0
- data/ext/microsandbox/Cargo.toml +45 -0
- data/ext/microsandbox/extconf.rb +14 -0
- data/ext/microsandbox/src/conv.rs +74 -0
- data/ext/microsandbox/src/error.rs +72 -0
- data/ext/microsandbox/src/exec.rs +158 -0
- data/ext/microsandbox/src/image.rs +114 -0
- data/ext/microsandbox/src/lib.rs +84 -0
- data/ext/microsandbox/src/runtime.rs +92 -0
- data/ext/microsandbox/src/sandbox.rs +812 -0
- data/ext/microsandbox/src/snapshot.rs +158 -0
- data/ext/microsandbox/src/stream.rs +86 -0
- data/ext/microsandbox/src/volume.rs +97 -0
- data/lib/microsandbox/errors.rb +68 -0
- data/lib/microsandbox/exec_handle.rb +154 -0
- data/lib/microsandbox/exec_output.rb +55 -0
- data/lib/microsandbox/fs.rb +172 -0
- data/lib/microsandbox/image.rb +111 -0
- data/lib/microsandbox/log_entry.rb +38 -0
- data/lib/microsandbox/metrics.rb +55 -0
- data/lib/microsandbox/sandbox.rb +461 -0
- data/lib/microsandbox/snapshot.rb +155 -0
- data/lib/microsandbox/streams.rb +54 -0
- data/lib/microsandbox/version.rb +7 -0
- data/lib/microsandbox/volume.rb +79 -0
- data/lib/microsandbox.rb +78 -0
- data/rust-toolchain.toml +5 -0
- data/sig/microsandbox.rbs +321 -0
- metadata +101 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Microsandbox
|
|
4
|
+
# A named persistent volume, from {Volume.create} / {Volume.get} / {Volume.list}.
|
|
5
|
+
#
|
|
6
|
+
# `path` is populated when returned from {Volume.create}; the storage stats
|
|
7
|
+
# (`kind`, `used_bytes`, …) are populated when returned from {Volume.get}/{Volume.list}.
|
|
8
|
+
class VolumeInfo
|
|
9
|
+
attr_reader :name, :path, :quota_mib, :used_bytes, :capacity_bytes,
|
|
10
|
+
:disk_format, :disk_fstype, :labels
|
|
11
|
+
|
|
12
|
+
def initialize(data)
|
|
13
|
+
@name = data["name"]
|
|
14
|
+
@path = data["path"]
|
|
15
|
+
@kind = data["kind"]
|
|
16
|
+
@quota_mib = data["quota_mib"]
|
|
17
|
+
@used_bytes = data["used_bytes"]
|
|
18
|
+
@capacity_bytes = data["capacity_bytes"]
|
|
19
|
+
@disk_format = data["disk_format"]
|
|
20
|
+
@disk_fstype = data["disk_fstype"]
|
|
21
|
+
@labels = data["labels"] || {}
|
|
22
|
+
@created_at_ms = data["created_at_ms"]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @return [Symbol, nil] :directory or :disk
|
|
26
|
+
def kind
|
|
27
|
+
@kind&.to_sym
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [Time, nil]
|
|
31
|
+
def created_at
|
|
32
|
+
@created_at_ms && Time.at(@created_at_ms / 1000.0)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def inspect
|
|
36
|
+
"#<Microsandbox::VolumeInfo name=#{@name.inspect}#{@kind ? " kind=#{@kind}" : ""}>"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Management of named persistent volumes. Mount them into a sandbox via
|
|
41
|
+
# `Sandbox.create(..., volumes: { "/data" => { named: "my-vol" } })`.
|
|
42
|
+
class Volume
|
|
43
|
+
class << self
|
|
44
|
+
# Create a named volume.
|
|
45
|
+
# @param name [String]
|
|
46
|
+
# @param kind ["dir", "disk"] storage kind (default "dir")
|
|
47
|
+
# @param size_mib [Integer, nil] required for kind "disk"
|
|
48
|
+
# @param quota_mib [Integer, nil] optional quota
|
|
49
|
+
# @param labels [Hash, nil]
|
|
50
|
+
# @return [VolumeInfo]
|
|
51
|
+
def create(name, kind: "dir", size_mib: nil, quota_mib: nil, labels: nil)
|
|
52
|
+
opts = { "kind" => kind.to_s }
|
|
53
|
+
opts["size_mib"] = Integer(size_mib) if size_mib
|
|
54
|
+
opts["quota_mib"] = Integer(quota_mib) if quota_mib
|
|
55
|
+
opts["labels"] = labels.each_with_object({}) { |(k, v), a| a[k.to_s] = v.to_s } if labels
|
|
56
|
+
VolumeInfo.new(Native::Volume.create(name.to_s, opts))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Metadata for a volume.
|
|
60
|
+
# @return [VolumeInfo]
|
|
61
|
+
def get(name)
|
|
62
|
+
VolumeInfo.new(Native::Volume.get(name.to_s))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# All volumes.
|
|
66
|
+
# @return [Array<VolumeInfo>]
|
|
67
|
+
def list
|
|
68
|
+
Native::Volume.list.map { |info| VolumeInfo.new(info) }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Remove a volume.
|
|
72
|
+
# @return [nil]
|
|
73
|
+
def remove(name)
|
|
74
|
+
Native::Volume.remove(name.to_s)
|
|
75
|
+
nil
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
data/lib/microsandbox.rb
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "microsandbox/version"
|
|
4
|
+
|
|
5
|
+
# Load the compiled native extension. Precompiled platform gems ship a
|
|
6
|
+
# version-specific subdirectory (e.g. lib/microsandbox/3.4/microsandbox_rb.bundle);
|
|
7
|
+
# fall back to the flat path used by source builds.
|
|
8
|
+
begin
|
|
9
|
+
ruby_version = RbConfig::CONFIG["ruby_version"].to_s
|
|
10
|
+
require_relative "microsandbox/#{ruby_version}/microsandbox_rb"
|
|
11
|
+
rescue LoadError
|
|
12
|
+
require_relative "microsandbox/microsandbox_rb"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
require_relative "microsandbox/errors"
|
|
16
|
+
require_relative "microsandbox/exec_output"
|
|
17
|
+
require_relative "microsandbox/exec_handle"
|
|
18
|
+
require_relative "microsandbox/fs"
|
|
19
|
+
require_relative "microsandbox/metrics"
|
|
20
|
+
require_relative "microsandbox/log_entry"
|
|
21
|
+
require_relative "microsandbox/streams"
|
|
22
|
+
require_relative "microsandbox/image"
|
|
23
|
+
require_relative "microsandbox/volume"
|
|
24
|
+
require_relative "microsandbox/snapshot"
|
|
25
|
+
require_relative "microsandbox/sandbox"
|
|
26
|
+
|
|
27
|
+
# Microsandbox — lightweight microVM sandboxes for Ruby.
|
|
28
|
+
#
|
|
29
|
+
# The runtime is embedded directly in the process via a Rust native extension;
|
|
30
|
+
# there is no daemon to install and no server to connect to. Creating a sandbox
|
|
31
|
+
# spawns a real microVM as a child process.
|
|
32
|
+
#
|
|
33
|
+
# @example
|
|
34
|
+
# Microsandbox::Sandbox.create("hello", image: "python") do |sb|
|
|
35
|
+
# puts sb.exec("python", ["-c", "print('Hello, World!')"]).stdout
|
|
36
|
+
# end
|
|
37
|
+
module Microsandbox
|
|
38
|
+
class << self
|
|
39
|
+
# @return [String] the gem version
|
|
40
|
+
def version
|
|
41
|
+
VERSION
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Download and install the `msb` runtime + `libkrunfw` into
|
|
45
|
+
# `~/.microsandbox` (idempotent). Usually unnecessary: the native
|
|
46
|
+
# extension provisions the runtime at build time.
|
|
47
|
+
# @return [nil]
|
|
48
|
+
def install
|
|
49
|
+
Native.install
|
|
50
|
+
nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [Boolean] whether the runtime is installed and resolvable
|
|
54
|
+
def installed?
|
|
55
|
+
Native.installed?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @return [String] the resolved path to the `msb` runtime binary
|
|
59
|
+
def runtime_path
|
|
60
|
+
Native.resolved_msb_path
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Override the `msb` runtime path (highest-priority SDK tier of the
|
|
64
|
+
# resolver, below only the `MSB_PATH` environment variable).
|
|
65
|
+
# @param path [String]
|
|
66
|
+
# @return [void]
|
|
67
|
+
def runtime_path=(path)
|
|
68
|
+
Native.set_runtime_msb_path(path.to_s)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Latest resource-usage snapshot for every running sandbox, keyed by name.
|
|
72
|
+
# Mirrors the official `all_sandbox_metrics`/`allSandboxMetrics` helpers.
|
|
73
|
+
# @return [Hash{String => Metrics}]
|
|
74
|
+
def all_sandbox_metrics
|
|
75
|
+
Native.all_sandbox_metrics.transform_values { |m| Metrics.new(m) }
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
data/rust-toolchain.toml
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Type signatures for the public microsandbox Ruby API.
|
|
2
|
+
|
|
3
|
+
module Microsandbox
|
|
4
|
+
VERSION: String
|
|
5
|
+
|
|
6
|
+
def self.version: () -> String
|
|
7
|
+
def self.install: () -> nil
|
|
8
|
+
def self.installed?: () -> bool
|
|
9
|
+
def self.runtime_path: () -> String
|
|
10
|
+
def self.runtime_path=: (String path) -> void
|
|
11
|
+
def self.all_sandbox_metrics: () -> Hash[String, Metrics]
|
|
12
|
+
|
|
13
|
+
class Error < StandardError
|
|
14
|
+
def self.code: () -> String
|
|
15
|
+
def code: () -> String
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class InvalidConfigError < Error end
|
|
19
|
+
class SandboxNotFoundError < Error end
|
|
20
|
+
class SandboxNotRunningError < Error end
|
|
21
|
+
class SandboxAlreadyExistsError < Error end
|
|
22
|
+
class SandboxStillRunningError < Error end
|
|
23
|
+
class ExecTimeoutError < Error end
|
|
24
|
+
class ExecFailedError < Error end
|
|
25
|
+
class FilesystemError < Error end
|
|
26
|
+
class PathNotFoundError < Error end
|
|
27
|
+
class VolumeNotFoundError < Error end
|
|
28
|
+
class VolumeAlreadyExistsError < Error end
|
|
29
|
+
class ImageNotFoundError < Error end
|
|
30
|
+
class ImageInUseError < Error end
|
|
31
|
+
class ImagePullFailedError < Error end
|
|
32
|
+
class NetworkPolicyError < Error end
|
|
33
|
+
class SecretViolationError < Error end
|
|
34
|
+
class TlsError < Error end
|
|
35
|
+
class IoError < Error end
|
|
36
|
+
class MetricsDisabledError < Error end
|
|
37
|
+
class MetricsUnavailableError < Error end
|
|
38
|
+
class UnsupportedOperationError < Error end
|
|
39
|
+
|
|
40
|
+
class ExecOutput
|
|
41
|
+
def initialize: (Hash[String, untyped] data) -> void
|
|
42
|
+
def exit_code: () -> Integer
|
|
43
|
+
def success?: () -> bool
|
|
44
|
+
def failure?: () -> bool
|
|
45
|
+
def stdout: () -> String
|
|
46
|
+
def stderr: () -> String
|
|
47
|
+
def stdout_bytes: () -> String
|
|
48
|
+
def stderr_bytes: () -> String
|
|
49
|
+
def to_s: () -> String
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class FsEntry
|
|
53
|
+
def path: () -> String
|
|
54
|
+
def name: () -> String
|
|
55
|
+
def type: () -> Symbol
|
|
56
|
+
def size: () -> Integer
|
|
57
|
+
def mode: () -> Integer
|
|
58
|
+
def modified: () -> Time?
|
|
59
|
+
def file?: () -> bool
|
|
60
|
+
def directory?: () -> bool
|
|
61
|
+
def symlink?: () -> bool
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class FsMetadata
|
|
65
|
+
def type: () -> Symbol
|
|
66
|
+
def size: () -> Integer
|
|
67
|
+
def mode: () -> Integer
|
|
68
|
+
def readonly?: () -> bool
|
|
69
|
+
def file?: () -> bool
|
|
70
|
+
def directory?: () -> bool
|
|
71
|
+
def symlink?: () -> bool
|
|
72
|
+
def modified: () -> Time?
|
|
73
|
+
def created: () -> Time?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
class FS
|
|
77
|
+
def read: (String path) -> String
|
|
78
|
+
def read_text: (String path) -> String
|
|
79
|
+
def write: (String path, String data) -> nil
|
|
80
|
+
def list: (String path) -> Array[FsEntry]
|
|
81
|
+
def mkdir: (String path) -> nil
|
|
82
|
+
def remove: (String path) -> nil
|
|
83
|
+
def remove_dir: (String path) -> nil
|
|
84
|
+
def copy: (String src, String dst) -> nil
|
|
85
|
+
def rename: (String src, String dst) -> nil
|
|
86
|
+
def exists?: (String path) -> bool
|
|
87
|
+
def stat: (String path) -> FsMetadata
|
|
88
|
+
def copy_from_host: (String host_path, String guest_path) -> nil
|
|
89
|
+
def copy_to_host: (String guest_path, String host_path) -> nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class Metrics
|
|
93
|
+
def cpu_percent: () -> Float
|
|
94
|
+
def vcpu_time_ns: () -> Integer
|
|
95
|
+
def memory_bytes: () -> Integer
|
|
96
|
+
def memory_available_bytes: () -> Integer?
|
|
97
|
+
def memory_host_resident_bytes: () -> Integer?
|
|
98
|
+
def memory_limit_bytes: () -> Integer
|
|
99
|
+
def disk_read_bytes: () -> Integer
|
|
100
|
+
def disk_write_bytes: () -> Integer
|
|
101
|
+
def net_rx_bytes: () -> Integer
|
|
102
|
+
def net_tx_bytes: () -> Integer
|
|
103
|
+
def uptime_secs: () -> Float
|
|
104
|
+
def timestamp: () -> Time
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
class LogEntry
|
|
108
|
+
def source: () -> Symbol
|
|
109
|
+
def session_id: () -> Integer?
|
|
110
|
+
def cursor: () -> String
|
|
111
|
+
def data: () -> String
|
|
112
|
+
def text: () -> String
|
|
113
|
+
def timestamp: () -> Time
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
class SandboxInfo
|
|
117
|
+
def name: () -> String
|
|
118
|
+
def status: () -> Symbol
|
|
119
|
+
def running?: () -> bool
|
|
120
|
+
def stopped?: () -> bool
|
|
121
|
+
def created_at: () -> Time?
|
|
122
|
+
def updated_at: () -> Time?
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
class SandboxStopResult
|
|
126
|
+
def name: () -> String
|
|
127
|
+
def status: () -> Symbol
|
|
128
|
+
def exit_code: () -> Integer?
|
|
129
|
+
def signal: () -> Integer?
|
|
130
|
+
def source: () -> String?
|
|
131
|
+
def stopped?: () -> bool
|
|
132
|
+
def crashed?: () -> bool
|
|
133
|
+
def observed_at: () -> Time
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
class Sandbox
|
|
137
|
+
def self.create: (String name, ?image: String?, ?cpus: Integer?, ?memory: Integer?,
|
|
138
|
+
?env: Hash[untyped, untyped]?, ?workdir: String?, ?shell: String?,
|
|
139
|
+
?user: String?, ?hostname: String?, ?labels: Hash[untyped, untyped]?,
|
|
140
|
+
?scripts: Hash[untyped, untyped]?, ?entrypoint: Array[String]?,
|
|
141
|
+
?ports: Hash[untyped, untyped]?, ?ports_udp: Hash[untyped, untyped]?,
|
|
142
|
+
?volumes: Hash[untyped, untyped]?, ?network: untyped?, ?from_snapshot: String?,
|
|
143
|
+
?log_level: (String | Symbol)?, ?quiet_logs: bool, ?security: (String | Symbol)?,
|
|
144
|
+
?oci_upper_size: Integer?, ?max_duration: Integer?, ?idle_timeout: Integer?,
|
|
145
|
+
?rlimits: Hash[untyped, untyped]?, ?pull_policy: (String | Symbol)?,
|
|
146
|
+
?secrets: Array[Hash[untyped, untyped]]?, ?detached: bool,
|
|
147
|
+
?replace: bool, ?replace_with_timeout: Numeric?)
|
|
148
|
+
?{ (Sandbox) -> untyped } -> untyped
|
|
149
|
+
def self.start: (String name, ?detached: bool) -> Sandbox
|
|
150
|
+
def self.get: (String name) -> SandboxInfo
|
|
151
|
+
def self.list: () -> Array[SandboxInfo]
|
|
152
|
+
def self.list_with: (?labels: Hash[untyped, untyped]) -> Array[SandboxInfo]
|
|
153
|
+
def self.remove: (String name) -> nil
|
|
154
|
+
|
|
155
|
+
def name: () -> String
|
|
156
|
+
def exec: (String command, ?Array[String] args, ?cwd: String?, ?user: String?,
|
|
157
|
+
?env: Hash[untyped, untyped]?, ?timeout: Numeric?, ?tty: bool, ?stdin: String?,
|
|
158
|
+
?rlimits: Hash[untyped, untyped]?) -> ExecOutput
|
|
159
|
+
def shell: (String script, ?cwd: String?, ?user: String?, ?env: Hash[untyped, untyped]?,
|
|
160
|
+
?timeout: Numeric?, ?tty: bool, ?stdin: String?, ?rlimits: Hash[untyped, untyped]?) -> ExecOutput
|
|
161
|
+
def exec_stream: (String command, ?Array[String] args, ?cwd: String?, ?user: String?,
|
|
162
|
+
?env: Hash[untyped, untyped]?, ?timeout: Numeric?, ?tty: bool, ?stdin: String?,
|
|
163
|
+
?rlimits: Hash[untyped, untyped]?) -> ExecHandle
|
|
164
|
+
def shell_stream: (String script, ?cwd: String?, ?user: String?, ?env: Hash[untyped, untyped]?,
|
|
165
|
+
?timeout: Numeric?, ?tty: bool, ?stdin: String?, ?rlimits: Hash[untyped, untyped]?) -> ExecHandle
|
|
166
|
+
def fs: () -> FS
|
|
167
|
+
def metrics: () -> Metrics
|
|
168
|
+
def logs: (?tail: Integer?, ?since_ms: Numeric?, ?until_ms: Numeric?,
|
|
169
|
+
?sources: Array[String | Symbol]?) -> Array[LogEntry]
|
|
170
|
+
def metrics_stream: (?interval: Numeric) -> MetricsStream
|
|
171
|
+
def log_stream: (?sources: Array[String | Symbol]?, ?since_ms: Numeric?,
|
|
172
|
+
?from_cursor: String?, ?until_ms: Numeric?, ?follow: bool) -> LogStream
|
|
173
|
+
def stop: (?timeout: Numeric?) -> nil
|
|
174
|
+
def kill: (?timeout: Numeric?) -> nil
|
|
175
|
+
def request_stop: () -> nil
|
|
176
|
+
def request_kill: () -> nil
|
|
177
|
+
def request_drain: () -> nil
|
|
178
|
+
def wait_until_stopped: () -> SandboxStopResult
|
|
179
|
+
def owns_lifecycle?: () -> bool
|
|
180
|
+
def detach: () -> nil
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
class LogStream
|
|
184
|
+
include Enumerable[LogEntry]
|
|
185
|
+
def each: () { (LogEntry) -> void } -> self
|
|
186
|
+
| () -> Enumerator[LogEntry, self]
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
class MetricsStream
|
|
190
|
+
include Enumerable[Metrics]
|
|
191
|
+
def each: () { (Metrics) -> void } -> self
|
|
192
|
+
| () -> Enumerator[Metrics, self]
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
class ExecEvent
|
|
196
|
+
def type: () -> Symbol
|
|
197
|
+
def pid: () -> Integer?
|
|
198
|
+
def code: () -> Integer?
|
|
199
|
+
def data: () -> String?
|
|
200
|
+
def text: () -> String?
|
|
201
|
+
def started?: () -> bool
|
|
202
|
+
def stdout?: () -> bool
|
|
203
|
+
def stderr?: () -> bool
|
|
204
|
+
def exited?: () -> bool
|
|
205
|
+
def failed?: () -> bool
|
|
206
|
+
def stdin_error?: () -> bool
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
class ExitStatus
|
|
210
|
+
def exit_code: () -> Integer
|
|
211
|
+
def success?: () -> bool
|
|
212
|
+
def failure?: () -> bool
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
class ExecStdin
|
|
216
|
+
def write: (untyped data) -> self
|
|
217
|
+
def close: () -> nil
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
class ExecHandle
|
|
221
|
+
include Enumerable[ExecEvent]
|
|
222
|
+
def id: () -> String
|
|
223
|
+
def each: () { (ExecEvent) -> void } -> self
|
|
224
|
+
| () -> Enumerator[ExecEvent, self]
|
|
225
|
+
def wait: () -> ExitStatus
|
|
226
|
+
def collect: () -> ExecOutput
|
|
227
|
+
def signal: (Integer sig) -> nil
|
|
228
|
+
def kill: () -> nil
|
|
229
|
+
def resize: (Integer rows, Integer cols) -> nil
|
|
230
|
+
def stdin: () -> ExecStdin?
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
class ImageInfo
|
|
234
|
+
def reference: () -> String
|
|
235
|
+
def size_bytes: () -> Integer?
|
|
236
|
+
def manifest_digest: () -> String?
|
|
237
|
+
def architecture: () -> String?
|
|
238
|
+
def os: () -> String?
|
|
239
|
+
def layer_count: () -> Integer
|
|
240
|
+
def created_at: () -> Time?
|
|
241
|
+
def last_used_at: () -> Time?
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
class ImageDetail
|
|
245
|
+
def handle: () -> ImageInfo
|
|
246
|
+
def config: () -> Hash[String, untyped]?
|
|
247
|
+
def layers: () -> Array[Hash[String, untyped]]
|
|
248
|
+
def reference: () -> String
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
class ImagePruneReport
|
|
252
|
+
def image_refs_removed: () -> Integer
|
|
253
|
+
def manifests_removed: () -> Integer
|
|
254
|
+
def layers_removed: () -> Integer
|
|
255
|
+
def fsmeta_removed: () -> Integer
|
|
256
|
+
def vmdk_removed: () -> Integer
|
|
257
|
+
def bytes_reclaimed: () -> Integer?
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
class Image
|
|
261
|
+
def self.list: () -> Array[ImageInfo]
|
|
262
|
+
def self.get: (String reference) -> ImageInfo
|
|
263
|
+
def self.inspect: (?String? reference) -> (ImageDetail | String)
|
|
264
|
+
def self.remove: (String reference, ?force: bool) -> nil
|
|
265
|
+
def self.prune: () -> ImagePruneReport
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
class VolumeInfo
|
|
269
|
+
def name: () -> String
|
|
270
|
+
def path: () -> String?
|
|
271
|
+
def kind: () -> Symbol?
|
|
272
|
+
def quota_mib: () -> Integer?
|
|
273
|
+
def used_bytes: () -> Integer?
|
|
274
|
+
def capacity_bytes: () -> Integer?
|
|
275
|
+
def disk_format: () -> String?
|
|
276
|
+
def disk_fstype: () -> String?
|
|
277
|
+
def labels: () -> Hash[String, String]
|
|
278
|
+
def created_at: () -> Time?
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
class Volume
|
|
282
|
+
def self.create: (String name, ?kind: String, ?size_mib: Integer?, ?quota_mib: Integer?,
|
|
283
|
+
?labels: Hash[untyped, untyped]?) -> VolumeInfo
|
|
284
|
+
def self.get: (String name) -> VolumeInfo
|
|
285
|
+
def self.list: () -> Array[VolumeInfo]
|
|
286
|
+
def self.remove: (String name) -> nil
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
class SnapshotInfo
|
|
290
|
+
def digest: () -> String
|
|
291
|
+
def path: () -> String
|
|
292
|
+
def name: () -> String?
|
|
293
|
+
def parent_digest: () -> String?
|
|
294
|
+
def image_ref: () -> String?
|
|
295
|
+
def size_bytes: () -> Integer?
|
|
296
|
+
def format: () -> Symbol?
|
|
297
|
+
def created_at: () -> Time?
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
class SnapshotVerifyReport
|
|
301
|
+
def digest: () -> String
|
|
302
|
+
def path: () -> String
|
|
303
|
+
def status: () -> Symbol
|
|
304
|
+
def algorithm: () -> String?
|
|
305
|
+
def content_digest: () -> String?
|
|
306
|
+
def verified?: () -> bool
|
|
307
|
+
def not_recorded?: () -> bool
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
class Snapshot
|
|
311
|
+
def self.create: (String source_sandbox, ?name: String?, ?path: String?,
|
|
312
|
+
?labels: Hash[untyped, untyped]?, ?force: bool, ?record_integrity: bool) -> SnapshotInfo
|
|
313
|
+
def self.get: (String name_or_digest) -> SnapshotInfo
|
|
314
|
+
def self.list: () -> Array[SnapshotInfo]
|
|
315
|
+
def self.remove: (String name_or_path, ?force: bool) -> nil
|
|
316
|
+
def self.verify: (String name_or_path) -> SnapshotVerifyReport
|
|
317
|
+
def self.export: (String name_or_path, String out_path, ?with_parents: bool,
|
|
318
|
+
?with_image: bool, ?plain_tar: bool) -> nil
|
|
319
|
+
def self.import: (String archive_path, ?dest: String?) -> SnapshotInfo
|
|
320
|
+
end
|
|
321
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: microsandbox-rb
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.5.7
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- ya-luotao
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rb_sys
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.9.91
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.9.91
|
|
26
|
+
description: |
|
|
27
|
+
The microsandbox-rb gem provides native bindings to the microsandbox runtime via
|
|
28
|
+
a Rust extension (magnus). It spins up real microVMs (not containers) in under
|
|
29
|
+
100ms, runs standard OCI (Docker) images, and gives you full control over
|
|
30
|
+
command execution, the guest filesystem, networking, volumes, snapshots, SSH,
|
|
31
|
+
and secrets — all from an idiomatic, synchronous Ruby API. No daemon, no server
|
|
32
|
+
to connect to: the runtime is embedded directly in your process.
|
|
33
|
+
email:
|
|
34
|
+
- luotao@hey.com
|
|
35
|
+
executables: []
|
|
36
|
+
extensions:
|
|
37
|
+
- ext/microsandbox/extconf.rb
|
|
38
|
+
extra_rdoc_files: []
|
|
39
|
+
files:
|
|
40
|
+
- CHANGELOG.md
|
|
41
|
+
- Cargo.lock
|
|
42
|
+
- Cargo.toml
|
|
43
|
+
- DESIGN.md
|
|
44
|
+
- LICENSE
|
|
45
|
+
- README.md
|
|
46
|
+
- ext/microsandbox/Cargo.toml
|
|
47
|
+
- ext/microsandbox/extconf.rb
|
|
48
|
+
- ext/microsandbox/src/conv.rs
|
|
49
|
+
- ext/microsandbox/src/error.rs
|
|
50
|
+
- ext/microsandbox/src/exec.rs
|
|
51
|
+
- ext/microsandbox/src/image.rs
|
|
52
|
+
- ext/microsandbox/src/lib.rs
|
|
53
|
+
- ext/microsandbox/src/runtime.rs
|
|
54
|
+
- ext/microsandbox/src/sandbox.rs
|
|
55
|
+
- ext/microsandbox/src/snapshot.rs
|
|
56
|
+
- ext/microsandbox/src/stream.rs
|
|
57
|
+
- ext/microsandbox/src/volume.rs
|
|
58
|
+
- lib/microsandbox.rb
|
|
59
|
+
- lib/microsandbox/errors.rb
|
|
60
|
+
- lib/microsandbox/exec_handle.rb
|
|
61
|
+
- lib/microsandbox/exec_output.rb
|
|
62
|
+
- lib/microsandbox/fs.rb
|
|
63
|
+
- lib/microsandbox/image.rb
|
|
64
|
+
- lib/microsandbox/log_entry.rb
|
|
65
|
+
- lib/microsandbox/metrics.rb
|
|
66
|
+
- lib/microsandbox/sandbox.rb
|
|
67
|
+
- lib/microsandbox/snapshot.rb
|
|
68
|
+
- lib/microsandbox/streams.rb
|
|
69
|
+
- lib/microsandbox/version.rb
|
|
70
|
+
- lib/microsandbox/volume.rb
|
|
71
|
+
- rust-toolchain.toml
|
|
72
|
+
- sig/microsandbox.rbs
|
|
73
|
+
homepage: https://github.com/ya-luotao/microsandbox-rb
|
|
74
|
+
licenses:
|
|
75
|
+
- Apache-2.0
|
|
76
|
+
metadata:
|
|
77
|
+
homepage_uri: https://github.com/ya-luotao/microsandbox-rb
|
|
78
|
+
source_code_uri: https://github.com/ya-luotao/microsandbox-rb
|
|
79
|
+
documentation_uri: https://github.com/ya-luotao/microsandbox-rb#readme
|
|
80
|
+
changelog_uri: https://github.com/ya-luotao/microsandbox-rb/blob/main/CHANGELOG.md
|
|
81
|
+
rubygems_mfa_required: 'true'
|
|
82
|
+
cargo_crate_name: microsandbox_rb
|
|
83
|
+
rdoc_options: []
|
|
84
|
+
require_paths:
|
|
85
|
+
- lib
|
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: 3.1.0
|
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: 3.3.11
|
|
96
|
+
requirements: []
|
|
97
|
+
rubygems_version: 3.6.9
|
|
98
|
+
specification_version: 4
|
|
99
|
+
summary: Lightweight microVM sandboxes for Ruby — run AI agents and untrusted code
|
|
100
|
+
with hardware-level isolation.
|
|
101
|
+
test_files: []
|