microsandbox-rb 0.5.12 → 0.7.0

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.
@@ -1,12 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Microsandbox
4
- # Metadata for a snapshot artifact, returned by {Snapshot.create}/{Snapshot.get}/
5
- # {Snapshot.list}/{Snapshot.import}.
4
+ # Metadata for a snapshot artifact, returned by {Snapshot.create}/{Snapshot.open}/
5
+ # {Snapshot.get}/{Snapshot.list}/{Snapshot.list_dir}/{Snapshot.import}.
6
6
  #
7
- # `digest` and `path` are always present. `create` additionally populates
8
- # `size_bytes`; `get`/`list`/`import` additionally populate `name`,
9
- # `parent_digest`, `image_ref`, `format`, and `created_at`.
7
+ # `digest` and `path` are always present. The artifact-opening paths
8
+ # (`create`/`open`/`list_dir`, and {SandboxHandle#snapshot}) carry the full
9
+ # manifest — `size_bytes`, `image_ref`, `image_manifest_digest`, `format`,
10
+ # `fstype`, `parent_digest`, `created_at`, `source_sandbox`, and `labels`. The
11
+ # index paths (`get`/`list`/`import`) populate `name`, `parent_digest`,
12
+ # `image_ref`, `format`, `size_bytes`, and `created_at` (manifest-only fields
13
+ # such as `fstype`/`source_sandbox`/`labels` are nil/empty there).
10
14
  class SnapshotInfo
11
15
  # @return [String] manifest digest ("sha256:…") — the canonical identity
12
16
  attr_reader :digest
@@ -18,6 +22,14 @@ module Microsandbox
18
22
  attr_reader :parent_digest
19
23
  # @return [String, nil] source OCI image reference
20
24
  attr_reader :image_ref
25
+ # @return [String, nil] OCI manifest digest of the pinned image (manifest paths)
26
+ attr_reader :image_manifest_digest
27
+ # @return [String, nil] upper-layer filesystem type, e.g. "ext4" (manifest paths)
28
+ attr_reader :fstype
29
+ # @return [String, nil] best-effort source-sandbox name, if recorded
30
+ attr_reader :source_sandbox
31
+ # @return [Hash{String=>String}] user labels ({} for index-only entries)
32
+ attr_reader :labels
21
33
  # @return [Integer, nil] artifact size in bytes
22
34
  attr_reader :size_bytes
23
35
 
@@ -27,6 +39,10 @@ module Microsandbox
27
39
  @name = data["name"]
28
40
  @parent_digest = data["parent_digest"]
29
41
  @image_ref = data["image_ref"]
42
+ @image_manifest_digest = data["image_manifest_digest"]
43
+ @fstype = data["fstype"]
44
+ @source_sandbox = data["source_sandbox"]
45
+ @labels = data["labels"] || {}
30
46
  @format = data["format"]
31
47
  @size_bytes = data["size_bytes"]
32
48
  @created_at_ms = data["created_at_ms"]
@@ -42,6 +58,21 @@ module Microsandbox
42
58
  @created_at_ms && Time.at(@created_at_ms / 1000.0)
43
59
  end
44
60
 
61
+ # Re-open this snapshot's artifact (cheap metadata validation), returning a
62
+ # fully-populated {SnapshotInfo}. Addresses by path, so it works even for
63
+ # artifacts that were never added to the local index.
64
+ # @return [SnapshotInfo]
65
+ def open
66
+ Snapshot.open(@path || @digest)
67
+ end
68
+
69
+ # Remove this snapshot's artifact and its index row.
70
+ # @param force [Boolean] remove even if it has indexed children
71
+ # @return [nil]
72
+ def remove(force: false)
73
+ Snapshot.remove(@path || @digest, force: force)
74
+ end
75
+
45
76
  def inspect
46
77
  "#<Microsandbox::SnapshotInfo digest=#{@digest.inspect}#{" name=#{@name.inspect}" if @name}>"
47
78
  end
@@ -98,18 +129,44 @@ module Microsandbox
98
129
  SnapshotInfo.new(Native::Snapshot.create(source_sandbox.to_s, opts))
99
130
  end
100
131
 
132
+ # Open a snapshot artifact by bare name or path (cheap metadata
133
+ # validation; does not read the upper layer). Unlike {get}, this also
134
+ # works for artifacts addressed by path that were never indexed, and it
135
+ # returns the full manifest.
136
+ # @return [SnapshotInfo]
137
+ def open(name_or_path)
138
+ SnapshotInfo.new(Native::Snapshot.open(name_or_path.to_s))
139
+ end
140
+
101
141
  # Metadata for a snapshot by name or digest.
102
142
  # @return [SnapshotInfo]
103
143
  def get(name_or_digest)
104
144
  SnapshotInfo.new(Native::Snapshot.get(name_or_digest.to_s))
105
145
  end
106
146
 
107
- # All snapshots.
147
+ # All snapshots indexed in the local cache.
108
148
  # @return [Array<SnapshotInfo>]
109
149
  def list
110
150
  Native::Snapshot.list.map { |info| SnapshotInfo.new(info) }
111
151
  end
112
152
 
153
+ # Enumerate snapshot artifacts under a directory by parsing each
154
+ # subdirectory's `manifest.json`, without touching the local index — for
155
+ # inspecting external/un-imported collections (e.g. a mounted volume).
156
+ # @return [Array<SnapshotInfo>]
157
+ def list_dir(dir)
158
+ Native::Snapshot.list_dir(dir.to_s).map { |info| SnapshotInfo.new(info) }
159
+ end
160
+
161
+ # Rebuild the local snapshot index from a directory (defaults to the
162
+ # configured snapshots dir). The repair for index drift or out-of-band
163
+ # imports that {list}/{get} can't otherwise see.
164
+ # @param dir [String, nil]
165
+ # @return [Integer] number of indexed snapshots
166
+ def reindex(dir = nil)
167
+ Native::Snapshot.reindex(dir&.to_s)
168
+ end
169
+
113
170
  # Remove a snapshot artifact by name or path.
114
171
  # @param force [Boolean] remove even if referenced
115
172
  # @return [nil]
@@ -2,8 +2,9 @@
2
2
 
3
3
  module Microsandbox
4
4
  # The result of an {SshClient#exec} call. Like {ExecOutput}, `stdout`/`stderr`
5
- # are the captured bytes decoded as UTF-8 (lenient); use `stdout_bytes`/
6
- # `stderr_bytes` for the raw ASCII-8BIT bytes.
5
+ # are the captured bytes decoded as UTF-8 (lossy invalid byte sequences are
6
+ # replaced with U+FFFD); use `stdout_bytes`/`stderr_bytes` for the raw
7
+ # ASCII-8BIT bytes.
7
8
  class SshOutput
8
9
  # @return [Integer] the remote command's exit status
9
10
  attr_reader :status
@@ -25,14 +26,14 @@ module Microsandbox
25
26
  # @return [Boolean] whether the command exited non-zero
26
27
  def failure? = !@success
27
28
 
28
- # @return [String] stdout decoded as UTF-8
29
+ # @return [String] stdout decoded as UTF-8 (lossy)
29
30
  def stdout
30
- @stdout ||= @stdout_bytes.dup.force_encoding(Encoding::UTF_8)
31
+ @stdout ||= @stdout_bytes.dup.force_encoding(Encoding::UTF_8).scrub
31
32
  end
32
33
 
33
- # @return [String] stderr decoded as UTF-8
34
+ # @return [String] stderr decoded as UTF-8 (lossy)
34
35
  def stderr
35
- @stderr ||= @stderr_bytes.dup.force_encoding(Encoding::UTF_8)
36
+ @stderr ||= @stderr_bytes.dup.force_encoding(Encoding::UTF_8).scrub
36
37
  end
37
38
 
38
39
  def to_s = stdout
@@ -56,16 +57,20 @@ module Microsandbox
56
57
  @native.read(path.to_s)
57
58
  end
58
59
 
59
- # Read a file and decode it as UTF-8 (lenient).
60
+ # Read a file and decode it as UTF-8 (lossy — invalid byte sequences are
61
+ # replaced with U+FFFD).
60
62
  # @return [String]
61
63
  def read_text(path)
62
- read(path).force_encoding(Encoding::UTF_8)
64
+ read(path).force_encoding(Encoding::UTF_8).scrub
63
65
  end
64
66
 
65
67
  # Write a file, creating or truncating it.
68
+ # @param data [String] raw bytes to write (binary-safe)
69
+ # @raise [TypeError] if +data+ is not a String
66
70
  # @return [nil]
67
71
  def write(path, data)
68
- @native.write(path.to_s, data.to_s)
72
+ bytes = Microsandbox.coerce_write_bytes(data)
73
+ @native.write(path.to_s, bytes)
69
74
  nil
70
75
  end
71
76
 
@@ -1,9 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Microsandbox
4
- # Gem version. Tracks the upstream microsandbox runtime (currently `v0.5.8`,
5
- # the pinned core-crate tag); the patch segment advances for gem-only revisions
6
- # that add bindings atop the same core. Must equal the native ext's Cargo crate
7
- # version (`Native.version`), enforced by spec/unit/version_spec.rb.
8
- VERSION = "0.5.12"
4
+ # Gem version. Versioned independently of the upstream microsandbox runtime it
5
+ # embeds: the gem follows its own semver (while 0.x, breaking changes bump the
6
+ # minor and fixes bump the patch), so the number does NOT track the upstream tag
7
+ # one-to-one. Consult {RUNTIME_VERSION} for the wrapped runtime, and the
8
+ # Versioning section of the README for the full gem-to-runtime map. Must equal
9
+ # the native ext's Cargo crate version (`Native.version`), enforced by
10
+ # spec/unit/version_spec.rb.
11
+ VERSION = "0.7.0"
12
+
13
+ # The upstream microsandbox runtime release this gem build embeds — the `tag`
14
+ # pinned on the `microsandbox`/`microsandbox-network` git deps in
15
+ # ext/microsandbox/Cargo.toml. Exposed at runtime as
16
+ # {Microsandbox.runtime_version}. spec/unit/version_spec.rb asserts it stays in
17
+ # sync with the Cargo tag so it can't silently drift out of date.
18
+ RUNTIME_VERSION = "v0.5.8"
9
19
  end
@@ -22,7 +22,8 @@ module Microsandbox
22
22
  @created_at_ms = data["created_at_ms"]
23
23
  end
24
24
 
25
- # @return [Symbol, nil] :directory or :disk
25
+ # @return [Symbol, nil] :dir or :disk (matches the {Volume.create} `kind:`
26
+ # input and the core's canonical names)
26
27
  def kind
27
28
  @kind&.to_sym
28
29
  end
@@ -32,11 +33,102 @@ module Microsandbox
32
33
  @created_at_ms && Time.at(@created_at_ms / 1000.0)
33
34
  end
34
35
 
36
+ # A host-side filesystem view over this volume (read/write its contents
37
+ # without a running sandbox).
38
+ # @return [VolumeFs]
39
+ def fs
40
+ @fs ||= VolumeFs.new(Native::Volume.fs(@name.to_s))
41
+ end
42
+
35
43
  def inspect
36
44
  "#<Microsandbox::VolumeInfo name=#{@name.inspect}#{" kind=#{@kind}" if @kind}>"
37
45
  end
38
46
  end
39
47
 
48
+ # A host-side filesystem view over a named volume, from {Volume.fs} or
49
+ # {VolumeInfo#fs}. Reads and writes the volume's contents directly on the host,
50
+ # without booting a sandbox. All paths are relative to the volume root. Mirrors
51
+ # the `VolumeFs` of the official Python/Node SDKs.
52
+ class VolumeFs
53
+ def initialize(native)
54
+ @native = native
55
+ end
56
+
57
+ # Read a file as raw bytes (ASCII-8BIT).
58
+ # @return [String]
59
+ def read(path)
60
+ @native.read(path.to_s)
61
+ end
62
+
63
+ # Read a file as a UTF-8 string.
64
+ # @return [String]
65
+ def read_text(path)
66
+ @native.read_text(path.to_s)
67
+ end
68
+
69
+ # Write data to a file, creating parent directories as needed.
70
+ # @param data [String] raw bytes (binary-safe)
71
+ # @raise [TypeError] if +data+ is not a String
72
+ # @return [nil]
73
+ def write(path, data)
74
+ bytes = Microsandbox.coerce_write_bytes(data)
75
+ @native.write(path.to_s, bytes)
76
+ nil
77
+ end
78
+
79
+ # List the entries of a directory.
80
+ # @return [Array<FsEntry>]
81
+ def list(path)
82
+ @native.list(path.to_s).map { |entry| FsEntry.new(entry) }
83
+ end
84
+
85
+ # Create a directory (and any missing parents).
86
+ # @return [nil]
87
+ def mkdir(path)
88
+ @native.mkdir(path.to_s)
89
+ nil
90
+ end
91
+
92
+ # Remove a single file.
93
+ # @return [nil]
94
+ def remove_file(path)
95
+ @native.remove_file(path.to_s)
96
+ nil
97
+ end
98
+
99
+ # Remove a directory recursively.
100
+ # @return [nil]
101
+ def remove_dir(path)
102
+ @native.remove_dir(path.to_s)
103
+ nil
104
+ end
105
+
106
+ # @return [Boolean] whether the path exists in the volume
107
+ def exists?(path)
108
+ @native.exists(path.to_s)
109
+ end
110
+
111
+ # Copy a file within the volume.
112
+ # @return [nil]
113
+ def copy(src, dst)
114
+ @native.copy(src.to_s, dst.to_s)
115
+ nil
116
+ end
117
+
118
+ # Rename/move a file or directory within the volume.
119
+ # @return [nil]
120
+ def rename(src, dst)
121
+ @native.rename(src.to_s, dst.to_s)
122
+ nil
123
+ end
124
+
125
+ # Stat a path.
126
+ # @return [FsMetadata]
127
+ def stat(path)
128
+ FsMetadata.new(@native.stat(path.to_s))
129
+ end
130
+ end
131
+
40
132
  # Management of named persistent volumes. Mount them into a sandbox via
41
133
  # `Sandbox.create(..., volumes: { "/data" => { named: "my-vol" } })`.
42
134
  class Volume
@@ -74,6 +166,13 @@ module Microsandbox
74
166
  Native::Volume.remove(name.to_s)
75
167
  nil
76
168
  end
169
+
170
+ # A host-side filesystem view over a named volume (read/write its contents
171
+ # without a running sandbox). The volume need not be mounted.
172
+ # @return [VolumeFs]
173
+ def fs(name)
174
+ VolumeFs.new(Native::Volume.fs(name.to_s))
175
+ end
77
176
  end
78
177
  end
79
178
  end
data/lib/microsandbox.rb CHANGED
@@ -45,6 +45,15 @@ module Microsandbox
45
45
  VERSION
46
46
  end
47
47
 
48
+ # The upstream microsandbox runtime release this gem build embeds (the git
49
+ # `tag` pinned in ext/microsandbox/Cargo.toml). The gem's own {version} is
50
+ # versioned independently of this, so consult this to learn which runtime is
51
+ # wrapped. See the Versioning section of the README for the full map.
52
+ # @return [String] e.g. "v0.5.8"
53
+ def runtime_version
54
+ RUNTIME_VERSION
55
+ end
56
+
48
57
  # Download and install the `msb` runtime + `libkrunfw` into
49
58
  # `~/.microsandbox` (idempotent).
50
59
  #
@@ -60,6 +69,25 @@ module Microsandbox
60
69
  nil
61
70
  end
62
71
 
72
+ # Customizable install via the core `Setup` builder. Like {install} but with
73
+ # control over where and what to install — mirrors the Node `Setup` builder.
74
+ #
75
+ # @param base_dir [String, nil] install root (default `~/.microsandbox`)
76
+ # @param version [String, nil] pin the runtime version to download
77
+ # @param force [Boolean] re-download even if binaries already exist — the way
78
+ # to repair a corrupt/incomplete `~/.microsandbox`
79
+ # @param skip_verify [Boolean] skip the post-install verification step
80
+ # @return [nil]
81
+ def setup(base_dir: nil, version: nil, force: false, skip_verify: false)
82
+ opts = {}
83
+ opts["base_dir"] = base_dir.to_s if base_dir
84
+ opts["version"] = version.to_s if version
85
+ opts["force"] = true if force
86
+ opts["skip_verify"] = true if skip_verify
87
+ Native.setup(opts)
88
+ nil
89
+ end
90
+
63
91
  # @return [Boolean] whether the runtime is installed and resolvable
64
92
  def installed?
65
93
  Native.installed?
@@ -102,7 +130,9 @@ module Microsandbox
102
130
  end
103
131
 
104
132
  # Override the `msb` runtime path (highest-priority SDK tier of the
105
- # resolver, below only the `MSB_PATH` environment variable).
133
+ # resolver, below only the `MSB_PATH` environment variable). Process-level
134
+ # and set-once: a second call is silently ignored, and the `MSB_PATH`
135
+ # environment variable still wins. Mirrors {libkrunfw_path=}.
106
136
  # @param path [String]
107
137
  # @return [void]
108
138
  def runtime_path=(path)
@@ -172,6 +202,19 @@ module Microsandbox
172
202
  Native.all_sandbox_metrics.transform_values { |m| Metrics.new(m) }
173
203
  end
174
204
 
205
+ # Coerce write data to a binary-safe String, or raise. Centralizes the
206
+ # contract every `#write` shares (FS/SftpClient/VolumeFs/ExecStdin/
207
+ # FsWriteSink): accept a String and reject anything else loudly, instead of
208
+ # silently writing its `to_s` form (e.g. a StringIO's inspect or "42").
209
+ # @api private
210
+ # @param data [Object]
211
+ # @return [String]
212
+ # @raise [TypeError] unless +data+ is a String
213
+ def coerce_write_bytes(data)
214
+ String.try_convert(data) or
215
+ raise TypeError, "data must be a String (got #{data.class})"
216
+ end
217
+
175
218
  private
176
219
 
177
220
  # Auto-provisioning is on by default; any non-empty, non-"0"/"false" value
data/sig/microsandbox.rbs CHANGED
@@ -2,9 +2,12 @@
2
2
 
3
3
  module Microsandbox
4
4
  VERSION: String
5
+ RUNTIME_VERSION: String
5
6
 
6
7
  def self.version: () -> String
8
+ def self.runtime_version: () -> String
7
9
  def self.install: () -> nil
10
+ def self.setup: (?base_dir: String?, ?version: String?, ?force: bool, ?skip_verify: bool) -> nil
8
11
  def self.installed?: () -> bool
9
12
  def self.ensure_runtime!: () -> nil
10
13
  def self.runtime_path: () -> String
@@ -95,6 +98,20 @@ module Microsandbox
95
98
  def stat: (String path) -> FsMetadata
96
99
  def copy_from_host: (String host_path, String guest_path) -> nil
97
100
  def copy_to_host: (String guest_path, String host_path) -> nil
101
+ def read_stream: (String path) -> FsReadStream
102
+ def write_stream: (String path) ?{ (FsWriteSink) -> untyped } -> untyped
103
+ end
104
+
105
+ class FsReadStream
106
+ include Enumerable[String]
107
+ def each: () { (String) -> void } -> self
108
+ | () -> Enumerator[String, self]
109
+ def read: () -> String
110
+ end
111
+
112
+ class FsWriteSink
113
+ def write: (String data) -> self
114
+ def close: () -> nil
98
115
  end
99
116
 
100
117
  class Metrics
@@ -108,6 +125,9 @@ module Microsandbox
108
125
  def disk_write_bytes: () -> Integer
109
126
  def net_rx_bytes: () -> Integer
110
127
  def net_tx_bytes: () -> Integer
128
+ def upper_used_bytes: () -> Integer?
129
+ def upper_free_bytes: () -> Integer?
130
+ def upper_host_allocated_bytes: () -> Integer?
111
131
  def uptime_secs: () -> Float
112
132
  def timestamp: () -> Time
113
133
  end
@@ -136,6 +156,10 @@ module Microsandbox
136
156
  def request_kill: () -> nil
137
157
  def request_drain: () -> nil
138
158
  def wait_until_stopped: () -> SandboxStopResult
159
+ def config_json: () -> String
160
+ def config: () -> Hash[String, untyped]
161
+ def snapshot: (String name) -> SnapshotInfo
162
+ def snapshot_to: (String path) -> SnapshotInfo
139
163
  end
140
164
 
141
165
  # Deprecated alias for SandboxHandle (was a read-only metadata type pre-v0.5.8).
@@ -159,15 +183,23 @@ module Microsandbox
159
183
  ?scripts: Hash[untyped, untyped]?, ?entrypoint: Array[String]?,
160
184
  ?ports: Hash[untyped, untyped]?, ?ports_udp: Hash[untyped, untyped]?,
161
185
  ?volumes: Hash[untyped, untyped]?, ?network: untyped?,
186
+ ?dns: Hash[untyped, untyped]?, ?tls: Hash[untyped, untyped]?,
187
+ ?ipv4_pool: String?, ?ipv6_pool: String?,
188
+ ?max_connections: Integer?, ?trust_host_cas: bool?,
162
189
  ?patches: Array[Hash[untyped, untyped]]?, ?from_snapshot: String?,
190
+ ?fstype: String?, ?init: (String | Symbol | Hash[untyped, untyped])?, ?ephemeral: bool,
163
191
  ?log_level: (String | Symbol)?, ?quiet_logs: bool, ?security: (String | Symbol)?,
164
192
  ?oci_upper_size: Integer?, ?max_duration: Integer?, ?idle_timeout: Integer?,
165
193
  ?rlimits: Hash[untyped, untyped]?, ?pull_policy: (String | Symbol)?,
166
194
  ?registry_auth: Hash[untyped, untyped]?, ?registry_insecure: bool,
167
195
  ?registry_ca_certs: (String | Array[String])?,
168
- ?secrets: Array[Hash[untyped, untyped]]?, ?detached: bool,
196
+ ?secrets: Array[Hash[untyped, untyped]]?,
197
+ ?on_secret_violation: (String | Symbol | Hash[untyped, untyped])?,
198
+ ?detached: bool,
169
199
  ?replace: bool, ?replace_with_timeout: Numeric?)
170
200
  ?{ (Sandbox) -> untyped } -> untyped
201
+ # Accepts the same keyword options as {create}.
202
+ def self.create_with_progress: (String name, **untyped) -> PullSession
171
203
  def self.start: (String name, ?detached: bool) -> Sandbox
172
204
  def self.get: (String name) -> SandboxHandle
173
205
  def self.list: () -> Array[SandboxHandle]
@@ -176,15 +208,15 @@ module Microsandbox
176
208
 
177
209
  def name: () -> String
178
210
  def exec: (String command, ?Array[String] args, ?cwd: String?, ?user: String?,
179
- ?env: Hash[untyped, untyped]?, ?timeout: Numeric?, ?tty: bool, ?stdin: String?,
211
+ ?env: Hash[untyped, untyped]?, ?timeout: Numeric?, ?tty: bool, ?stdin: (String | :null)?,
180
212
  ?rlimits: Hash[untyped, untyped]?) -> ExecOutput
181
213
  def shell: (String script, ?cwd: String?, ?user: String?, ?env: Hash[untyped, untyped]?,
182
- ?timeout: Numeric?, ?tty: bool, ?stdin: String?, ?rlimits: Hash[untyped, untyped]?) -> ExecOutput
214
+ ?timeout: Numeric?, ?tty: bool, ?stdin: (String | :null)?, ?rlimits: Hash[untyped, untyped]?) -> ExecOutput
183
215
  def exec_stream: (String command, ?Array[String] args, ?cwd: String?, ?user: String?,
184
- ?env: Hash[untyped, untyped]?, ?timeout: Numeric?, ?tty: bool, ?stdin: (String | :pipe)?,
216
+ ?env: Hash[untyped, untyped]?, ?timeout: Numeric?, ?tty: bool, ?stdin: (String | :pipe | :null)?,
185
217
  ?rlimits: Hash[untyped, untyped]?) -> ExecHandle
186
218
  def shell_stream: (String script, ?cwd: String?, ?user: String?, ?env: Hash[untyped, untyped]?,
187
- ?timeout: Numeric?, ?tty: bool, ?stdin: (String | :pipe)?, ?rlimits: Hash[untyped, untyped]?) -> ExecHandle
219
+ ?timeout: Numeric?, ?tty: bool, ?stdin: (String | :pipe | :null)?, ?rlimits: Hash[untyped, untyped]?) -> ExecHandle
188
220
  def attach: (String command, ?Array[String] args, ?cwd: String?, ?user: String?,
189
221
  ?env: Hash[untyped, untyped]?, ?detach_keys: String?,
190
222
  ?rlimits: Hash[untyped, untyped]?) -> Integer
@@ -207,6 +239,14 @@ module Microsandbox
207
239
  def detach: () -> nil
208
240
  end
209
241
 
242
+ class PullSession
243
+ include Enumerable[Hash[String, untyped]]
244
+ def initialize: (untyped native) -> void
245
+ def each: () { (Hash[String, untyped]) -> void } -> self
246
+ | () -> Enumerator[Hash[String, untyped], self]
247
+ def sandbox: () -> Sandbox
248
+ end
249
+
210
250
  class LogStream
211
251
  include Enumerable[LogEntry]
212
252
  def each: () { (LogEntry) -> void } -> self
@@ -240,7 +280,7 @@ module Microsandbox
240
280
  end
241
281
 
242
282
  class ExecStdin
243
- def write: (untyped data) -> self
283
+ def write: (String data) -> self
244
284
  def close: () -> nil
245
285
  end
246
286
 
@@ -303,6 +343,22 @@ module Microsandbox
303
343
  def disk_fstype: () -> String?
304
344
  def labels: () -> Hash[String, String]
305
345
  def created_at: () -> Time?
346
+ def fs: () -> VolumeFs
347
+ end
348
+
349
+ class VolumeFs
350
+ def initialize: (untyped native) -> void
351
+ def read: (String path) -> String
352
+ def read_text: (String path) -> String
353
+ def write: (String path, String data) -> nil
354
+ def list: (String path) -> Array[FsEntry]
355
+ def mkdir: (String path) -> nil
356
+ def remove_file: (String path) -> nil
357
+ def remove_dir: (String path) -> nil
358
+ def exists?: (String path) -> bool
359
+ def copy: (String src, String dst) -> nil
360
+ def rename: (String src, String dst) -> nil
361
+ def stat: (String path) -> FsMetadata
306
362
  end
307
363
 
308
364
  class Volume
@@ -311,6 +367,7 @@ module Microsandbox
311
367
  def self.get: (String name) -> VolumeInfo
312
368
  def self.list: () -> Array[VolumeInfo]
313
369
  def self.remove: (String name) -> nil
370
+ def self.fs: (String name) -> VolumeFs
314
371
  end
315
372
 
316
373
  class SnapshotInfo
@@ -319,9 +376,15 @@ module Microsandbox
319
376
  def name: () -> String?
320
377
  def parent_digest: () -> String?
321
378
  def image_ref: () -> String?
379
+ def image_manifest_digest: () -> String?
380
+ def fstype: () -> String?
381
+ def source_sandbox: () -> String?
382
+ def labels: () -> Hash[String, String]
322
383
  def size_bytes: () -> Integer?
323
384
  def format: () -> Symbol?
324
385
  def created_at: () -> Time?
386
+ def open: () -> SnapshotInfo
387
+ def remove: (?force: bool) -> nil
325
388
  end
326
389
 
327
390
  class SnapshotVerifyReport
@@ -337,8 +400,11 @@ module Microsandbox
337
400
  class Snapshot
338
401
  def self.create: (String source_sandbox, ?name: String?, ?path: String?,
339
402
  ?labels: Hash[untyped, untyped]?, ?force: bool, ?record_integrity: bool) -> SnapshotInfo
403
+ def self.open: (String name_or_path) -> SnapshotInfo
340
404
  def self.get: (String name_or_digest) -> SnapshotInfo
341
405
  def self.list: () -> Array[SnapshotInfo]
406
+ def self.list_dir: (String dir) -> Array[SnapshotInfo]
407
+ def self.reindex: (?String? dir) -> Integer
342
408
  def self.remove: (String name_or_path, ?force: bool) -> nil
343
409
  def self.verify: (String name_or_path) -> SnapshotVerifyReport
344
410
  def self.export: (String name_or_path, String out_path, ?with_parents: bool,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: microsandbox-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.12
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ya-luotao
@@ -50,6 +50,7 @@ files:
50
50
  - ext/microsandbox/src/conv.rs
51
51
  - ext/microsandbox/src/error.rs
52
52
  - ext/microsandbox/src/exec.rs
53
+ - ext/microsandbox/src/fs_stream.rs
53
54
  - ext/microsandbox/src/image.rs
54
55
  - ext/microsandbox/src/lib.rs
55
56
  - ext/microsandbox/src/runtime.rs