microsandbox-rb 0.16.0 → 0.17.1
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 +4 -4
- data/CHANGELOG.md +234 -1
- data/Cargo.lock +236 -201
- data/DESIGN.md +7 -38
- data/README.md +178 -626
- data/SECURITY.md +65 -0
- data/docs/configuration.md +154 -0
- data/docs/errors.md +74 -0
- data/docs/execution.md +101 -0
- data/docs/filesystem.md +45 -0
- data/docs/images.md +65 -0
- data/docs/lifecycle.md +108 -0
- data/docs/observability.md +99 -0
- data/docs/releasing.md +66 -0
- data/docs/runtime.md +152 -0
- data/docs/surface.md +70 -0
- data/ext/microsandbox/Cargo.toml +4 -4
- data/ext/microsandbox/src/error.rs +7 -0
- data/ext/microsandbox/src/host_path.rs +108 -0
- data/ext/microsandbox/src/lib.rs +1 -0
- data/ext/microsandbox/src/sandbox.rs +143 -31
- data/ext/microsandbox/src/volume.rs +43 -12
- data/lib/microsandbox/fs.rb +4 -8
- data/lib/microsandbox/image.rb +2 -2
- data/lib/microsandbox/log_entry.rb +1 -1
- data/lib/microsandbox/metrics.rb +1 -1
- data/lib/microsandbox/outbound_proxy.rb +340 -0
- data/lib/microsandbox/sandbox.rb +73 -10
- data/lib/microsandbox/snapshot.rb +1 -1
- data/lib/microsandbox/ssh.rb +2 -10
- data/lib/microsandbox/streams.rb +8 -5
- data/lib/microsandbox/version.rb +2 -2
- data/lib/microsandbox/volume.rb +31 -14
- data/lib/microsandbox-rb.rb +7 -0
- data/lib/microsandbox.rb +89 -31
- data/sig/microsandbox.rbs +40 -1
- metadata +15 -1
data/lib/microsandbox/volume.rb
CHANGED
|
@@ -38,7 +38,7 @@ module Microsandbox
|
|
|
38
38
|
|
|
39
39
|
# @return [Time, nil]
|
|
40
40
|
def created_at
|
|
41
|
-
|
|
41
|
+
Microsandbox.time_from_ms(@created_at_ms)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# A host-side filesystem view over this volume (read/write its contents
|
|
@@ -55,8 +55,10 @@ module Microsandbox
|
|
|
55
55
|
|
|
56
56
|
# A host-side filesystem view over a named volume, from {Volume.fs} or
|
|
57
57
|
# {VolumeInfo#fs}. Reads and writes the volume's contents directly on the host,
|
|
58
|
-
# without booting a sandbox. All paths are relative to the volume root
|
|
59
|
-
#
|
|
58
|
+
# without booting a sandbox. All paths are relative to the volume root (a
|
|
59
|
+
# leading `/` is the volume root) and may not contain a `..` segment — every
|
|
60
|
+
# operation raises {FilesystemError} for one. Mirrors the `VolumeFs` of the
|
|
61
|
+
# official Python/Node SDKs.
|
|
60
62
|
class VolumeFs
|
|
61
63
|
def initialize(native)
|
|
62
64
|
@native = native
|
|
@@ -65,13 +67,13 @@ module Microsandbox
|
|
|
65
67
|
# Read a file as raw bytes (ASCII-8BIT).
|
|
66
68
|
# @return [String]
|
|
67
69
|
def read(path)
|
|
68
|
-
@native.read(path
|
|
70
|
+
@native.read(contained(path))
|
|
69
71
|
end
|
|
70
72
|
|
|
71
73
|
# Read a file as a UTF-8 string.
|
|
72
74
|
# @return [String]
|
|
73
75
|
def read_text(path)
|
|
74
|
-
@native.read_text(path
|
|
76
|
+
@native.read_text(contained(path))
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
# Write data to a file, creating parent directories as needed.
|
|
@@ -80,60 +82,75 @@ module Microsandbox
|
|
|
80
82
|
# @return [nil]
|
|
81
83
|
def write(path, data)
|
|
82
84
|
bytes = Microsandbox.coerce_write_bytes(data)
|
|
83
|
-
@native.write(path
|
|
85
|
+
@native.write(contained(path), bytes)
|
|
84
86
|
nil
|
|
85
87
|
end
|
|
86
88
|
|
|
87
89
|
# List the entries of a directory.
|
|
88
90
|
# @return [Array<FsEntry>]
|
|
89
91
|
def list(path)
|
|
90
|
-
@native.list(path
|
|
92
|
+
@native.list(contained(path)).map { |entry| FsEntry.new(entry) }
|
|
91
93
|
end
|
|
92
94
|
|
|
93
95
|
# Create a directory (and any missing parents).
|
|
94
96
|
# @return [nil]
|
|
95
97
|
def mkdir(path)
|
|
96
|
-
@native.mkdir(path
|
|
98
|
+
@native.mkdir(contained(path))
|
|
97
99
|
nil
|
|
98
100
|
end
|
|
99
101
|
|
|
100
102
|
# Remove a single file.
|
|
101
103
|
# @return [nil]
|
|
102
104
|
def remove_file(path)
|
|
103
|
-
@native.remove_file(path
|
|
105
|
+
@native.remove_file(contained(path))
|
|
104
106
|
nil
|
|
105
107
|
end
|
|
106
108
|
|
|
107
109
|
# Remove a directory recursively.
|
|
108
110
|
# @return [nil]
|
|
109
111
|
def remove_dir(path)
|
|
110
|
-
@native.remove_dir(path
|
|
112
|
+
@native.remove_dir(contained(path))
|
|
111
113
|
nil
|
|
112
114
|
end
|
|
113
115
|
|
|
114
116
|
# @return [Boolean] whether the path exists in the volume
|
|
115
117
|
def exists?(path)
|
|
116
|
-
@native.exists(path
|
|
118
|
+
@native.exists(contained(path))
|
|
117
119
|
end
|
|
118
120
|
|
|
119
121
|
# Copy a file within the volume.
|
|
120
122
|
# @return [nil]
|
|
121
123
|
def copy(src, dst)
|
|
122
|
-
@native.copy(src
|
|
124
|
+
@native.copy(contained(src), contained(dst))
|
|
123
125
|
nil
|
|
124
126
|
end
|
|
125
127
|
|
|
126
128
|
# Rename/move a file or directory within the volume.
|
|
127
129
|
# @return [nil]
|
|
128
130
|
def rename(src, dst)
|
|
129
|
-
@native.rename(src
|
|
131
|
+
@native.rename(contained(src), contained(dst))
|
|
130
132
|
nil
|
|
131
133
|
end
|
|
132
134
|
|
|
133
135
|
# Stat a path.
|
|
134
136
|
# @return [FsMetadata]
|
|
135
137
|
def stat(path)
|
|
136
|
-
FsMetadata.new(@native.stat(path
|
|
138
|
+
FsMetadata.new(@native.stat(contained(path)))
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
private
|
|
142
|
+
|
|
143
|
+
# Volume paths are relative to the volume root and never need a `..`
|
|
144
|
+
# segment, so one is refused here with a clear message instead of being
|
|
145
|
+
# handed to the resolver. The native layer enforces the same rule; this
|
|
146
|
+
# check only exists so the error names the cause.
|
|
147
|
+
def contained(path)
|
|
148
|
+
s = path.to_s
|
|
149
|
+
if s.split("/").include?("..")
|
|
150
|
+
raise Microsandbox::FilesystemError,
|
|
151
|
+
"path traversal outside volume root (`..` segments are not allowed in volume paths)"
|
|
152
|
+
end
|
|
153
|
+
s
|
|
137
154
|
end
|
|
138
155
|
end
|
|
139
156
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Entry point named after the gem. `require "microsandbox"` resolves to
|
|
4
|
+
# whichever installed gem ships that file first, and the separate
|
|
5
|
+
# `microsandbox` gem on RubyGems ships one too; outside Bundler,
|
|
6
|
+
# `require "microsandbox-rb"` always loads this gem.
|
|
7
|
+
require_relative "microsandbox"
|
data/lib/microsandbox.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "monitor"
|
|
4
|
+
|
|
3
5
|
require_relative "microsandbox/version"
|
|
4
6
|
|
|
5
7
|
# Load the compiled native extension. Precompiled platform gems stage the
|
|
@@ -30,6 +32,7 @@ require_relative "microsandbox/snapshot"
|
|
|
30
32
|
require_relative "microsandbox/patch"
|
|
31
33
|
require_relative "microsandbox/root_disk"
|
|
32
34
|
require_relative "microsandbox/network"
|
|
35
|
+
require_relative "microsandbox/outbound_proxy"
|
|
33
36
|
require_relative "microsandbox/agent"
|
|
34
37
|
require_relative "microsandbox/ssh"
|
|
35
38
|
require_relative "microsandbox/modification"
|
|
@@ -46,6 +49,13 @@ require_relative "microsandbox/sandbox"
|
|
|
46
49
|
# puts sb.exec("python", ["-c", "print('Hello, World!')"]).stdout
|
|
47
50
|
# end
|
|
48
51
|
module Microsandbox
|
|
52
|
+
# Serializes runtime provisioning within this process: {install}, {setup} and
|
|
53
|
+
# the first-use check in {ensure_runtime!}. The installer replaces files in
|
|
54
|
+
# place, so two threads racing through a first `Sandbox.create` must not both
|
|
55
|
+
# run it. A Monitor (re-entrant) because ensure_runtime! calls install.
|
|
56
|
+
RUNTIME_SETUP_LOCK = Monitor.new
|
|
57
|
+
private_constant :RUNTIME_SETUP_LOCK
|
|
58
|
+
|
|
49
59
|
class << self
|
|
50
60
|
# @return [String] the gem version
|
|
51
61
|
def version
|
|
@@ -73,7 +83,7 @@ module Microsandbox
|
|
|
73
83
|
# gem supplies the runtime.
|
|
74
84
|
# @return [nil]
|
|
75
85
|
def install
|
|
76
|
-
Native.install
|
|
86
|
+
RUNTIME_SETUP_LOCK.synchronize { Native.install }
|
|
77
87
|
nil
|
|
78
88
|
end
|
|
79
89
|
|
|
@@ -92,7 +102,7 @@ module Microsandbox
|
|
|
92
102
|
opts["version"] = version.to_s if version
|
|
93
103
|
opts["force"] = true if force
|
|
94
104
|
opts["skip_verify"] = true if skip_verify
|
|
95
|
-
Native.setup(opts)
|
|
105
|
+
RUNTIME_SETUP_LOCK.synchronize { Native.setup(opts) }
|
|
96
106
|
nil
|
|
97
107
|
end
|
|
98
108
|
|
|
@@ -129,34 +139,38 @@ module Microsandbox
|
|
|
129
139
|
# @return [nil]
|
|
130
140
|
def ensure_runtime!
|
|
131
141
|
return if @runtime_ready
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
142
|
+
RUNTIME_SETUP_LOCK.synchronize do
|
|
143
|
+
# Re-check under the lock: another thread may have finished meanwhile.
|
|
144
|
+
return if @runtime_ready
|
|
145
|
+
# A cloud backend has no local msb/libkrunfw runtime to provision: skip the
|
|
146
|
+
# presence check and the first-use download entirely. Resolving the kind
|
|
147
|
+
# uses the same lazy env/profile/config ladder every operation already
|
|
148
|
+
# consults, so this adds no work for local hosts (the common case).
|
|
149
|
+
return if default_backend_kind == :cloud
|
|
150
|
+
# The binaries gem won the resolver: its vendored msb (and the libkrunfw
|
|
151
|
+
# beside it) are exactly the version this gem was built for, so there is
|
|
152
|
+
# nothing to verify or download. (If `MSB_PATH` overrides it, the user owns
|
|
153
|
+
# the runtime and we fall through to the existing behaviour.)
|
|
154
|
+
if bundled_runtime_active?
|
|
155
|
+
@runtime_ready = true
|
|
156
|
+
return
|
|
157
|
+
end
|
|
158
|
+
# Opted out: the caller manages the runtime out of band, so don't fetch,
|
|
159
|
+
# verify, or repair it here. Memoize the decision (the env var is stable for
|
|
160
|
+
# the process); the operation resolves `msb` itself and surfaces any problem.
|
|
161
|
+
if auto_install_disabled?
|
|
162
|
+
@runtime_ready = true
|
|
163
|
+
return
|
|
164
|
+
end
|
|
152
165
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
166
|
+
unless installed?
|
|
167
|
+
warn "[microsandbox] runtime (msb + libkrunfw) not found; " \
|
|
168
|
+
"downloading to ~/.microsandbox (set MICROSANDBOX_NO_AUTO_INSTALL to skip, " \
|
|
169
|
+
"or install the microsandbox-rb-binaries gem to ship it with your bundle)..."
|
|
170
|
+
end
|
|
171
|
+
install
|
|
172
|
+
@runtime_ready = true
|
|
157
173
|
end
|
|
158
|
-
install
|
|
159
|
-
@runtime_ready = true
|
|
160
174
|
nil
|
|
161
175
|
end
|
|
162
176
|
|
|
@@ -175,7 +189,9 @@ module Microsandbox
|
|
|
175
189
|
# setter is a no-op — use `MSB_PATH` to override a bundled runtime.
|
|
176
190
|
# @param path [String]
|
|
177
191
|
# @return [void]
|
|
192
|
+
# @raise [ArgumentError] for nil or an empty path (the slot cannot be cleared)
|
|
178
193
|
def runtime_path=(path)
|
|
194
|
+
require_runtime_path!(:runtime_path=, path)
|
|
179
195
|
if @bundled_msb_path && path.to_s != @bundled_msb_path
|
|
180
196
|
warn "[microsandbox] runtime_path= ignored: the microsandbox-rb-binaries gem already " \
|
|
181
197
|
"claimed the set-once SDK slot (#{@bundled_msb_path}); set MSB_PATH to override it"
|
|
@@ -189,7 +205,9 @@ module Microsandbox
|
|
|
189
205
|
# Mirrors {runtime_path=} for libkrunfw.
|
|
190
206
|
# @param path [String]
|
|
191
207
|
# @return [void]
|
|
208
|
+
# @raise [ArgumentError] for nil or an empty path (the slot cannot be cleared)
|
|
192
209
|
def libkrunfw_path=(path)
|
|
210
|
+
require_runtime_path!(:libkrunfw_path=, path)
|
|
193
211
|
Native.set_runtime_libkrunfw_path(path.to_s)
|
|
194
212
|
end
|
|
195
213
|
|
|
@@ -271,6 +289,36 @@ module Microsandbox
|
|
|
271
289
|
raise TypeError, "data must be a String (got #{data.class})"
|
|
272
290
|
end
|
|
273
291
|
|
|
292
|
+
# A Time for an epoch-milliseconds Integer from the native layer, or nil.
|
|
293
|
+
# Integer arithmetic on purpose: `Time.at(ms / 1000.0)` goes through a
|
|
294
|
+
# Float and lands one millisecond low for about half of all timestamps.
|
|
295
|
+
# @api private
|
|
296
|
+
# @param ms [Integer, nil]
|
|
297
|
+
# @return [Time, nil]
|
|
298
|
+
def time_from_ms(ms)
|
|
299
|
+
ms && Time.at(ms.div(1000), ms % 1000, :millisecond)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# Run the block, then close +resource+ — the shared tail of the block forms
|
|
303
|
+
# that own a resource whose close can fail (a write sink flushes on close).
|
|
304
|
+
# If the block raised, its exception is the one the caller needs: a failure
|
|
305
|
+
# from the close that follows is dropped instead of replacing it. If the
|
|
306
|
+
# block finished (or left via break/throw), a close failure propagates.
|
|
307
|
+
# @api private
|
|
308
|
+
def close_after(resource)
|
|
309
|
+
raised = false
|
|
310
|
+
yield
|
|
311
|
+
rescue Exception # standard:disable Lint/RescueException -- re-raised unchanged
|
|
312
|
+
raised = true
|
|
313
|
+
raise
|
|
314
|
+
ensure
|
|
315
|
+
begin
|
|
316
|
+
resource.close
|
|
317
|
+
rescue
|
|
318
|
+
raise unless raised
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
274
322
|
private
|
|
275
323
|
|
|
276
324
|
# Auto-provisioning is on by default; any non-empty, non-"0"/"false" value
|
|
@@ -357,12 +405,22 @@ module Microsandbox
|
|
|
357
405
|
private_constant :TRUSTED_BINARIES_OWNERS
|
|
358
406
|
|
|
359
407
|
# Name of the loaded gem whose files define Microsandbox::Binaries, or nil
|
|
360
|
-
# when it came from a bare load path.
|
|
408
|
+
# when it came from a bare load path. Gem roots can nest — a host project
|
|
409
|
+
# that is itself a gem, with its bundle installed under the project
|
|
410
|
+
# directory, is a prefix of every gem in that bundle — so the owner is the
|
|
411
|
+
# gem with the LONGEST matching root, not whichever one is listed first.
|
|
361
412
|
def bundled_runtime_owner
|
|
362
413
|
source = Binaries.method(:msb_path).source_location&.first
|
|
363
414
|
return nil unless source
|
|
364
|
-
|
|
365
|
-
|
|
415
|
+
roots = Gem.loaded_specs.values.select { |s| source.start_with?(File.join(s.full_gem_path, "")) }
|
|
416
|
+
roots.max_by { |s| s.full_gem_path.length }&.name
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
# The runtime path slots are set-once in the core and have no "unset": nil
|
|
420
|
+
# or "" would be stored as an empty path for the rest of the process.
|
|
421
|
+
def require_runtime_path!(setter, path)
|
|
422
|
+
return unless path.nil? || path.to_s.empty?
|
|
423
|
+
raise ArgumentError, "#{setter} needs a non-empty path (the slot is set-once and cannot be cleared)"
|
|
366
424
|
end
|
|
367
425
|
|
|
368
426
|
# Whether the binaries gem's msb is what the resolver actually returns — i.e.
|
data/sig/microsandbox.rbs
CHANGED
|
@@ -261,8 +261,9 @@ module Microsandbox
|
|
|
261
261
|
?volumes: Hash[untyped, untyped]?, ?network: untyped?,
|
|
262
262
|
?dns: Hash[untyped, untyped]?, ?tls: Hash[untyped, untyped]?,
|
|
263
263
|
?ipv4_pool: String?, ?ipv6_pool: String?,
|
|
264
|
-
?max_connections: Integer?, ?trust_host_cas: bool?,
|
|
264
|
+
?max_connections: Integer?, ?trust_host_cas: bool?, ?strict: bool?,
|
|
265
265
|
?rate_limiter: Hash[untyped, untyped]?,
|
|
266
|
+
?proxy: (OutboundProxy | Hash[untyped, untyped])?,
|
|
266
267
|
?vsock: (Hash[untyped, untyped] | Array[Hash[untyped, untyped]])?,
|
|
267
268
|
?patches: Array[Hash[untyped, untyped]]?, ?from_snapshot: String?,
|
|
268
269
|
?fstype: String?, ?init: (String | Symbol | Hash[untyped, untyped])?, ?ephemeral: bool,
|
|
@@ -576,6 +577,44 @@ module Microsandbox
|
|
|
576
577
|
def cloud?: () -> bool
|
|
577
578
|
end
|
|
578
579
|
|
|
580
|
+
# Host-side secret source (runtime v0.6.17): only `env` exists.
|
|
581
|
+
class SecretSource
|
|
582
|
+
KINDS: Array[String]
|
|
583
|
+
attr_reader kind: String
|
|
584
|
+
attr_reader var: String
|
|
585
|
+
def self.env: ((String | Symbol) variable) -> SecretSource
|
|
586
|
+
def self.coerce: (untyped value, ?String context) -> SecretSource
|
|
587
|
+
def initialize: ((String | Symbol) kind, (String | Symbol) var) -> void
|
|
588
|
+
def to_h: () -> Hash[String, String]
|
|
589
|
+
def ==: (untyped other) -> bool
|
|
590
|
+
def eql?: (untyped other) -> bool
|
|
591
|
+
def hash: () -> Integer
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
# Outbound SOCKS4/SOCKS5 proxy for the `proxy:` create option (runtime
|
|
595
|
+
# v0.6.17). Immutable: `credentials` returns a new proxy.
|
|
596
|
+
class OutboundProxy
|
|
597
|
+
PROTOCOLS: Array[String]
|
|
598
|
+
attr_reader protocol: String
|
|
599
|
+
attr_reader address: String
|
|
600
|
+
attr_reader user_id: String?
|
|
601
|
+
attr_reader username: String?
|
|
602
|
+
attr_reader password: SecretSource?
|
|
603
|
+
def self.socks4: (String address, ?user_id: String?) -> OutboundProxy
|
|
604
|
+
def self.socks5: (String address) -> OutboundProxy
|
|
605
|
+
def self.coerce: (untyped value) -> Hash[String, untyped]
|
|
606
|
+
def self.from_hash: (Hash[untyped, untyped] hash) -> OutboundProxy
|
|
607
|
+
def initialize: (protocol: (String | Symbol), address: String, ?user_id: String?,
|
|
608
|
+
?username: String?, ?password: SecretSource?) -> void
|
|
609
|
+
def credentials: (String username, (SecretSource | Hash[untyped, untyped]) password) -> OutboundProxy
|
|
610
|
+
def socks4?: () -> bool
|
|
611
|
+
def socks5?: () -> bool
|
|
612
|
+
def to_h: () -> Hash[String, untyped]
|
|
613
|
+
def ==: (untyped other) -> bool
|
|
614
|
+
def eql?: (untyped other) -> bool
|
|
615
|
+
def hash: () -> Integer
|
|
616
|
+
end
|
|
617
|
+
|
|
579
618
|
class NetworkPolicy
|
|
580
619
|
PROFILES: Array[String]
|
|
581
620
|
PRESET_ALIASES: Hash[String, String]
|
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.
|
|
4
|
+
version: 0.17.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ya-luotao
|
|
@@ -43,6 +43,17 @@ files:
|
|
|
43
43
|
- DESIGN.md
|
|
44
44
|
- LICENSE
|
|
45
45
|
- README.md
|
|
46
|
+
- SECURITY.md
|
|
47
|
+
- docs/configuration.md
|
|
48
|
+
- docs/errors.md
|
|
49
|
+
- docs/execution.md
|
|
50
|
+
- docs/filesystem.md
|
|
51
|
+
- docs/images.md
|
|
52
|
+
- docs/lifecycle.md
|
|
53
|
+
- docs/observability.md
|
|
54
|
+
- docs/releasing.md
|
|
55
|
+
- docs/runtime.md
|
|
56
|
+
- docs/surface.md
|
|
46
57
|
- ext/microsandbox/Cargo.toml
|
|
47
58
|
- ext/microsandbox/extconf.rb
|
|
48
59
|
- ext/microsandbox/src/agent.rs
|
|
@@ -51,6 +62,7 @@ files:
|
|
|
51
62
|
- ext/microsandbox/src/error.rs
|
|
52
63
|
- ext/microsandbox/src/exec.rs
|
|
53
64
|
- ext/microsandbox/src/fs_stream.rs
|
|
65
|
+
- ext/microsandbox/src/host_path.rs
|
|
54
66
|
- ext/microsandbox/src/image.rs
|
|
55
67
|
- ext/microsandbox/src/lib.rs
|
|
56
68
|
- ext/microsandbox/src/runtime.rs
|
|
@@ -59,6 +71,7 @@ files:
|
|
|
59
71
|
- ext/microsandbox/src/ssh.rs
|
|
60
72
|
- ext/microsandbox/src/stream.rs
|
|
61
73
|
- ext/microsandbox/src/volume.rs
|
|
74
|
+
- lib/microsandbox-rb.rb
|
|
62
75
|
- lib/microsandbox.rb
|
|
63
76
|
- lib/microsandbox/agent.rb
|
|
64
77
|
- lib/microsandbox/backend_info.rb
|
|
@@ -71,6 +84,7 @@ files:
|
|
|
71
84
|
- lib/microsandbox/metrics.rb
|
|
72
85
|
- lib/microsandbox/modification.rb
|
|
73
86
|
- lib/microsandbox/network.rb
|
|
87
|
+
- lib/microsandbox/outbound_proxy.rb
|
|
74
88
|
- lib/microsandbox/patch.rb
|
|
75
89
|
- lib/microsandbox/root_disk.rb
|
|
76
90
|
- lib/microsandbox/sandbox.rb
|