microsandbox-rb 0.17.1 → 0.17.2

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.
@@ -52,7 +52,7 @@ impl SshClient {
52
52
  let guard = inner.lock().await;
53
53
  let client = guard.as_ref().ok_or_else(consumed)?;
54
54
  client.exec_with(command, |b| b.tty(tty)).await
55
- });
55
+ })?;
56
56
  Ok(ssh_output_to_hash(result.map_err(error::to_ruby)?))
57
57
  }
58
58
 
@@ -74,7 +74,7 @@ impl SshClient {
74
74
  b
75
75
  })
76
76
  .await
77
- });
77
+ })?;
78
78
  result.map_err(error::to_ruby)
79
79
  }
80
80
 
@@ -85,7 +85,7 @@ impl SshClient {
85
85
  let guard = inner.lock().await;
86
86
  let client = guard.as_ref().ok_or_else(consumed)?;
87
87
  client.sftp().await
88
- });
88
+ })?;
89
89
  Ok(SftpClient::from_core(result.map_err(error::to_ruby)?))
90
90
  }
91
91
 
@@ -101,7 +101,7 @@ impl SshClient {
101
101
  Some(c) => c.close().await,
102
102
  None => Ok(()),
103
103
  }
104
- });
104
+ })?;
105
105
  result.map_err(error::to_ruby)
106
106
  }
107
107
  }
@@ -144,7 +144,7 @@ impl SftpClient {
144
144
  let guard = inner.lock().await;
145
145
  let sftp = guard.as_ref().ok_or_else(|| sftp_str("session closed"))?;
146
146
  sftp.read(path).await.map_err(sftp_str)
147
- });
147
+ })?;
148
148
  Ok(ruby().str_from_slice(&result.map_err(error::base_error)?))
149
149
  }
150
150
 
@@ -158,7 +158,7 @@ impl SftpClient {
158
158
  file.write_all(&bytes).await.map_err(sftp_str)?;
159
159
  file.shutdown().await.map_err(sftp_str)?;
160
160
  Ok(())
161
- });
161
+ })?;
162
162
  result.map_err(error::base_error)
163
163
  }
164
164
 
@@ -168,7 +168,7 @@ impl SftpClient {
168
168
  let guard = inner.lock().await;
169
169
  let sftp = guard.as_ref().ok_or_else(|| sftp_str("session closed"))?;
170
170
  sftp.create_dir(path).await.map_err(sftp_str)
171
- });
171
+ })?;
172
172
  result.map_err(error::base_error)
173
173
  }
174
174
 
@@ -178,7 +178,7 @@ impl SftpClient {
178
178
  let guard = inner.lock().await;
179
179
  let sftp = guard.as_ref().ok_or_else(|| sftp_str("session closed"))?;
180
180
  sftp.remove_file(path).await.map_err(sftp_str)
181
- });
181
+ })?;
182
182
  result.map_err(error::base_error)
183
183
  }
184
184
 
@@ -188,7 +188,7 @@ impl SftpClient {
188
188
  let guard = inner.lock().await;
189
189
  let sftp = guard.as_ref().ok_or_else(|| sftp_str("session closed"))?;
190
190
  sftp.remove_dir(path).await.map_err(sftp_str)
191
- });
191
+ })?;
192
192
  result.map_err(error::base_error)
193
193
  }
194
194
 
@@ -198,7 +198,7 @@ impl SftpClient {
198
198
  let guard = inner.lock().await;
199
199
  let sftp = guard.as_ref().ok_or_else(|| sftp_str("session closed"))?;
200
200
  sftp.rename(old_path, new_path).await.map_err(sftp_str)
201
- });
201
+ })?;
202
202
  result.map_err(error::base_error)
203
203
  }
204
204
 
@@ -208,7 +208,7 @@ impl SftpClient {
208
208
  let guard = inner.lock().await;
209
209
  let sftp = guard.as_ref().ok_or_else(|| sftp_str("session closed"))?;
210
210
  sftp.symlink(target, link_path).await.map_err(sftp_str)
211
- });
211
+ })?;
212
212
  result.map_err(error::base_error)
213
213
  }
214
214
 
@@ -218,7 +218,7 @@ impl SftpClient {
218
218
  let guard = inner.lock().await;
219
219
  let sftp = guard.as_ref().ok_or_else(|| sftp_str("session closed"))?;
220
220
  sftp.canonicalize(path).await.map_err(sftp_str)
221
- });
221
+ })?;
222
222
  result.map_err(error::base_error)
223
223
  }
224
224
 
@@ -228,7 +228,7 @@ impl SftpClient {
228
228
  let guard = inner.lock().await;
229
229
  let sftp = guard.as_ref().ok_or_else(|| sftp_str("session closed"))?;
230
230
  sftp.read_link(path).await.map_err(sftp_str)
231
- });
231
+ })?;
232
232
  result.map_err(error::base_error)
233
233
  }
234
234
 
@@ -243,7 +243,7 @@ impl SftpClient {
243
243
  Some(s) => s.close().await.map_err(sftp_str),
244
244
  None => Ok(()),
245
245
  }
246
- });
246
+ })?;
247
247
  result.map_err(error::base_error)
248
248
  }
249
249
  }
@@ -276,7 +276,7 @@ impl SshServer {
276
276
  Some(s) => s.serve_connection(SshStdioStream::new()).await,
277
277
  None => Err(consumed()),
278
278
  }
279
- });
279
+ })?;
280
280
  result.map_err(error::to_ruby)
281
281
  }
282
282
 
@@ -285,19 +285,23 @@ impl SshServer {
285
285
  let inner = Arc::clone(&self.inner);
286
286
  block_on(async move {
287
287
  inner.lock().await.take();
288
- });
288
+ })?;
289
289
  Ok(())
290
290
  }
291
291
  }
292
292
 
293
293
  pub fn define(ruby: &Ruby, native: &RModule) -> Result<(), Error> {
294
294
  let client = native.define_class("SshClient", ruby.class_object())?;
295
+ // Resolve the wrapper class now, not on first use (see `preload_class`).
296
+ crate::runtime::preload_class::<SshClient>(ruby);
295
297
  client.define_method("exec", method!(SshClient::exec, 2))?;
296
298
  client.define_method("attach", method!(SshClient::attach, 2))?;
297
299
  client.define_method("sftp", method!(SshClient::sftp, 0))?;
298
300
  client.define_method("close", method!(SshClient::close, 0))?;
299
301
 
300
302
  let sftp = native.define_class("SftpClient", ruby.class_object())?;
303
+ // Resolve the wrapper class now, not on first use (see `preload_class`).
304
+ crate::runtime::preload_class::<SftpClient>(ruby);
301
305
  sftp.define_method("read", method!(SftpClient::read, 1))?;
302
306
  sftp.define_method("write", method!(SftpClient::write, 2))?;
303
307
  sftp.define_method("mkdir", method!(SftpClient::mkdir, 1))?;
@@ -310,6 +314,8 @@ pub fn define(ruby: &Ruby, native: &RModule) -> Result<(), Error> {
310
314
  sftp.define_method("close", method!(SftpClient::close, 0))?;
311
315
 
312
316
  let server = native.define_class("SshServer", ruby.class_object())?;
317
+ // Resolve the wrapper class now, not on first use (see `preload_class`).
318
+ crate::runtime::preload_class::<SshServer>(ruby);
313
319
  server.define_method("serve_connection", method!(SshServer::serve_connection, 0))?;
314
320
  server.define_method("close", method!(SshServer::close, 0))?;
315
321
 
@@ -41,7 +41,7 @@ impl LogStream {
41
41
  fn recv(&self) -> Result<Option<RHash>, Error> {
42
42
  use futures::StreamExt;
43
43
  let inner = Arc::clone(&self.inner);
44
- match block_on(async move { inner.lock().await.next().await }) {
44
+ match block_on(async move { inner.lock().await.next().await })? {
45
45
  Some(Ok(entry)) => Ok(Some(log_entry_to_hash(&entry))),
46
46
  Some(Err(e)) => Err(error::to_ruby(e)),
47
47
  None => Ok(None),
@@ -67,7 +67,7 @@ impl MetricsStream {
67
67
  fn recv(&self) -> Result<Option<RHash>, Error> {
68
68
  use futures::StreamExt;
69
69
  let inner = Arc::clone(&self.inner);
70
- match block_on(async move { inner.lock().await.next().await }) {
70
+ match block_on(async move { inner.lock().await.next().await })? {
71
71
  Some(Ok(metrics)) => Ok(Some(metrics_to_hash(&metrics))),
72
72
  Some(Err(e)) => Err(error::to_ruby(e)),
73
73
  None => Ok(None),
@@ -77,9 +77,13 @@ impl MetricsStream {
77
77
 
78
78
  pub fn define(ruby: &Ruby, native: &RModule) -> Result<(), Error> {
79
79
  let logs = native.define_class("LogStream", ruby.class_object())?;
80
+ // Resolve the wrapper class now, not on first use (see `preload_class`).
81
+ crate::runtime::preload_class::<LogStream>(ruby);
80
82
  logs.define_method("recv", method!(LogStream::recv, 0))?;
81
83
 
82
84
  let metrics = native.define_class("MetricsStream", ruby.class_object())?;
85
+ // Resolve the wrapper class now, not on first use (see `preload_class`).
86
+ crate::runtime::preload_class::<MetricsStream>(ruby);
83
87
  metrics.define_method("recv", method!(MetricsStream::recv, 0))?;
84
88
 
85
89
  Ok(())
@@ -68,7 +68,7 @@ fn create(name: String, opts: RHash) -> Result<RHash, Error> {
68
68
  builder = builder.label(k, v);
69
69
  }
70
70
 
71
- let vol = block_on(builder.create()).map_err(error::to_ruby)?;
71
+ let vol = block_on(builder.create())?.map_err(error::to_ruby)?;
72
72
  let hash = ruby().hash_new();
73
73
  hash.aset("name", vol.name().to_string())?;
74
74
  // `path()` is fallible as of v0.5.8 (returns `Unsupported` for cloud
@@ -81,19 +81,19 @@ fn create(name: String, opts: RHash) -> Result<RHash, Error> {
81
81
  }
82
82
 
83
83
  fn get(name: String) -> Result<RHash, Error> {
84
- let handle = block_on(microsandbox::Volume::get(&name)).map_err(error::to_ruby)?;
84
+ let handle = block_on(microsandbox::Volume::get(&name))?.map_err(error::to_ruby)?;
85
85
  Ok(handle_to_hash(&handle))
86
86
  }
87
87
 
88
88
  /// The backend's default volume (v0.6.9). Cloud-backend only — the local
89
89
  /// backend rejects it (Unsupported) to avoid accidental host access.
90
90
  fn get_default() -> Result<RHash, Error> {
91
- let handle = block_on(microsandbox::Volume::get_default()).map_err(error::to_ruby)?;
91
+ let handle = block_on(microsandbox::Volume::get_default())?.map_err(error::to_ruby)?;
92
92
  Ok(handle_to_hash(&handle))
93
93
  }
94
94
 
95
95
  fn list() -> Result<RArray, Error> {
96
- let handles = block_on(microsandbox::Volume::list()).map_err(error::to_ruby)?;
96
+ let handles = block_on(microsandbox::Volume::list())?.map_err(error::to_ruby)?;
97
97
  let arr = ruby().ary_new();
98
98
  for h in handles.iter() {
99
99
  arr.push(handle_to_hash(h))?;
@@ -102,7 +102,7 @@ fn list() -> Result<RArray, Error> {
102
102
  }
103
103
 
104
104
  fn remove(name: String) -> Result<(), Error> {
105
- block_on(microsandbox::Volume::remove(&name)).map_err(error::to_ruby)
105
+ block_on(microsandbox::Volume::remove(&name))?.map_err(error::to_ruby)
106
106
  }
107
107
 
108
108
  /// Volume paths are relative to the volume root and never need a `..` segment,
@@ -151,14 +151,14 @@ impl VolumeFs {
151
151
  fn read(&self, path: String) -> Result<RString, Error> {
152
152
  let path = contained(&path)?;
153
153
  let fs = self.fs();
154
- let bytes = block_on(fs.read(path)).map_err(error::to_ruby)?;
154
+ let bytes = block_on(fs.read(path))?.map_err(error::to_ruby)?;
155
155
  Ok(ruby().str_from_slice(bytes.as_ref()))
156
156
  }
157
157
 
158
158
  fn read_text(&self, path: String) -> Result<String, Error> {
159
159
  let path = contained(&path)?;
160
160
  let fs = self.fs();
161
- block_on(fs.read_to_string(path)).map_err(error::to_ruby)
161
+ block_on(fs.read_to_string(path))?.map_err(error::to_ruby)
162
162
  }
163
163
 
164
164
  fn write(&self, path: String, data: RString) -> Result<(), Error> {
@@ -166,13 +166,13 @@ impl VolumeFs {
166
166
  let bytes = unsafe { data.as_slice() }.to_vec();
167
167
  let path = contained(&path)?;
168
168
  let fs = self.fs();
169
- block_on(fs.write(path, &bytes)).map_err(error::to_ruby)
169
+ block_on(fs.write(path, &bytes))?.map_err(error::to_ruby)
170
170
  }
171
171
 
172
172
  fn list(&self, path: String) -> Result<RArray, Error> {
173
173
  let path = contained(&path)?;
174
174
  let fs = self.fs();
175
- let entries = block_on(fs.list(path)).map_err(error::to_ruby)?;
175
+ let entries = block_on(fs.list(path))?.map_err(error::to_ruby)?;
176
176
  let arr = ruby().ary_new();
177
177
  for entry in &entries {
178
178
  arr.push(fs_entry_to_hash(entry))?;
@@ -183,45 +183,45 @@ impl VolumeFs {
183
183
  fn mkdir(&self, path: String) -> Result<(), Error> {
184
184
  let path = contained(&path)?;
185
185
  let fs = self.fs();
186
- block_on(fs.mkdir(path)).map_err(error::to_ruby)
186
+ block_on(fs.mkdir(path))?.map_err(error::to_ruby)
187
187
  }
188
188
 
189
189
  fn remove_file(&self, path: String) -> Result<(), Error> {
190
190
  let path = contained(&path)?;
191
191
  let fs = self.fs();
192
- block_on(fs.remove(path)).map_err(error::to_ruby)
192
+ block_on(fs.remove(path))?.map_err(error::to_ruby)
193
193
  }
194
194
 
195
195
  fn remove_dir(&self, path: String) -> Result<(), Error> {
196
196
  let path = contained(&path)?;
197
197
  let fs = self.fs();
198
- block_on(fs.remove_dir(path)).map_err(error::to_ruby)
198
+ block_on(fs.remove_dir(path))?.map_err(error::to_ruby)
199
199
  }
200
200
 
201
201
  fn exists(&self, path: String) -> Result<bool, Error> {
202
202
  let path = contained(&path)?;
203
203
  let fs = self.fs();
204
- block_on(fs.exists(path)).map_err(error::to_ruby)
204
+ block_on(fs.exists(path))?.map_err(error::to_ruby)
205
205
  }
206
206
 
207
207
  fn copy(&self, from: String, to: String) -> Result<(), Error> {
208
208
  let from = contained(&from)?;
209
209
  let to = contained(&to)?;
210
210
  let fs = self.fs();
211
- block_on(fs.copy(from, to)).map_err(error::to_ruby)
211
+ block_on(fs.copy(from, to))?.map_err(error::to_ruby)
212
212
  }
213
213
 
214
214
  fn rename(&self, from: String, to: String) -> Result<(), Error> {
215
215
  let from = contained(&from)?;
216
216
  let to = contained(&to)?;
217
217
  let fs = self.fs();
218
- block_on(fs.rename(from, to)).map_err(error::to_ruby)
218
+ block_on(fs.rename(from, to))?.map_err(error::to_ruby)
219
219
  }
220
220
 
221
221
  fn stat(&self, path: String) -> Result<RHash, Error> {
222
222
  let path = contained(&path)?;
223
223
  let fs = self.fs();
224
- let meta = block_on(fs.stat(path)).map_err(error::to_ruby)?;
224
+ let meta = block_on(fs.stat(path))?.map_err(error::to_ruby)?;
225
225
  Ok(fs_metadata_to_hash(&meta))
226
226
  }
227
227
  }
@@ -241,6 +241,8 @@ pub fn define(ruby: &Ruby, native: &RModule) -> Result<(), Error> {
241
241
  class.define_singleton_method("fs", function!(fs, 1))?;
242
242
 
243
243
  let vfs = native.define_class("VolumeFs", ruby.class_object())?;
244
+ // Resolve the wrapper class now, not on first use (see `preload_class`).
245
+ crate::runtime::preload_class::<VolumeFs>(ruby);
244
246
  vfs.define_method("read", method!(VolumeFs::read, 1))?;
245
247
  vfs.define_method("read_text", method!(VolumeFs::read_text, 1))?;
246
248
  vfs.define_method("write", method!(VolumeFs::write, 2))?;
@@ -496,7 +496,10 @@ module Microsandbox
496
496
  def create(name, **kwargs, &block)
497
497
  opts = build_create_opts(**kwargs)
498
498
  Microsandbox.ensure_runtime!
499
- sandbox = new(Native::Sandbox.create(name.to_s, opts))
499
+ # Everything Ruby-level happens BEFORE `acquire`: its interrupt mask must
500
+ # cover only the native call plus the wrap, never caller-supplied code.
501
+ sandbox_name = name.to_s
502
+ sandbox = acquire { Native::Sandbox.create(sandbox_name, opts) }
500
503
  return sandbox unless block_given?
501
504
 
502
505
  begin
@@ -553,7 +556,8 @@ module Microsandbox
553
556
  def connect_or_create(name, **kwargs, &block)
554
557
  opts = build_create_opts(**kwargs)
555
558
  Microsandbox.ensure_runtime!
556
- sandbox = new(Native::Sandbox.connect_or_create(name.to_s, opts))
559
+ sandbox_name = name.to_s # outside the interrupt mask, like in {create}
560
+ sandbox = acquire { Native::Sandbox.connect_or_create(sandbox_name, opts) }
557
561
  return sandbox unless block_given?
558
562
 
559
563
  begin
@@ -588,6 +592,65 @@ module Microsandbox
588
592
  PullSession.new(Native::Sandbox.create_with_progress(name.to_s, opts))
589
593
  end
590
594
 
595
+ # @api private
596
+ # Wrap the native sandbox the block acquires, and stop it again if an
597
+ # interrupt cuts in before the caller has it.
598
+ #
599
+ # A native call cannot be interrupted while it runs, so a `Thread#raise`
600
+ # (what `Timeout.timeout` uses) or a `Thread#kill` that arrives during the
601
+ # block is delivered after it — at the next interrupt checkpoint, which is
602
+ # still in here, before the caller ever sees the object. Left alone the
603
+ # sandbox would be garbage and only GC would stop it, "eventually"; for
604
+ # `Timeout.timeout { Sandbox.create(...) }` that is not good enough. So:
605
+ #
606
+ # - the acquisition runs under `Thread.handle_interrupt(Object => :never)`,
607
+ # which holds a queued exception (or kill) back until the wrapper is
608
+ # assigned. The mask covers only the uninterruptible native call plus
609
+ # the wrap, so it changes no observable timing; runtime provisioning
610
+ # ({Microsandbox.ensure_runtime!}) and the block forms' `yield` stay
611
+ # outside it, with normal interrupt handling. For the same reason the
612
+ # block passed here must contain NOTHING but the native call: argument
613
+ # conversion (`name.to_s`, option Hashes) is the caller's own code and
614
+ # has to run before `acquire`, where it stays interruptible;
615
+ # - the `ensure` plus the `acquired` flag — not `rescue Exception; raise` —
616
+ # is what also covers `Thread#kill`, which no `rescue` can catch.
617
+ #
618
+ # A SIGINT (Ctrl-C on the main thread) is the exception: it is not queued
619
+ # like those two and cannot be masked. One that lands during the native
620
+ # call is raised the moment the call returns — the VM checks interrupts
621
+ # as it pops the native method's frame, before any Ruby code here can
622
+ # hold the result — so no assignment order would catch it; the sandbox
623
+ # is then torn down when the unreferenced object is garbage-collected.
624
+ #
625
+ # Ownership: {connect_or_create} can hand back a sandbox that was already
626
+ # running for someone else, and {start} restarts a persisted one. The
627
+ # cleanup therefore applies EXACTLY the predicate the block form of
628
+ # {connect_or_create} uses — {Sandbox#owns_lifecycle?} — in all three
629
+ # callers, {create} included: a sandbox this call does not own is never
630
+ # stopped here. Its reference is just let go (GC closes the handle, the
631
+ # sandbox keeps running).
632
+ # @yieldreturn [Native::Sandbox]
633
+ # @return [Sandbox]
634
+ def acquire
635
+ sandbox = nil
636
+ acquired = false
637
+ begin
638
+ Thread.handle_interrupt(Object => :never) do
639
+ sandbox = new(yield)
640
+ end
641
+ acquired = true
642
+ ensure
643
+ if sandbox && !acquired && sandbox.owns_lifecycle?
644
+ begin
645
+ sandbox.stop
646
+ rescue Microsandbox::Error
647
+ # best-effort cleanup; the interrupt is what the caller must see
648
+ end
649
+ end
650
+ end
651
+ sandbox
652
+ end
653
+
591
654
  # @api private
592
655
  # Shared keyword-option builder for {create}/{connect_or_create}/
593
656
  # {create_with_progress}. Pure validation and normalization: the callers
@@ -705,7 +768,9 @@ module Microsandbox
705
768
  # @return [Sandbox]
706
769
  def start(name, detached: false)
707
770
  Microsandbox.ensure_runtime!
708
- new(Native::Sandbox.start(name.to_s, {"detached" => detached}))
771
+ sandbox_name = name.to_s # outside the interrupt mask, like in {create}
772
+ opts = {"detached" => detached}
773
+ acquire { Native::Sandbox.start(sandbox_name, opts) }
709
774
  end
710
775
 
711
776
  # Fetch a controllable handle for a sandbox by name (running or not).
@@ -1998,10 +2063,16 @@ module Microsandbox
1998
2063
  # {Sandbox} is live — stop it when done. Memoized: the native result can be
1999
2064
  # taken only once, so a later call returns the same {Sandbox}, or re-raises
2000
2065
  # the same error if the create failed.
2066
+ #
2067
+ # Interrupt-safe like {Sandbox.create}: if a `Timeout.timeout` (or another
2068
+ # `Thread#raise`/`Thread#kill`) arrives while this is waiting, the sandbox
2069
+ # the session produced is stopped before the exception propagates rather
2070
+ # than left running with nothing referring to it. The result is consumed
2071
+ # by then, so a later call raises instead of returning a sandbox.
2001
2072
  # @return [Sandbox]
2002
2073
  def sandbox
2003
2074
  raise @failure if @failure
2004
- @sandbox ||= Sandbox.new(@native.result)
2075
+ @sandbox ||= Sandbox.acquire { @native.result }
2005
2076
  rescue Microsandbox::Error => e
2006
2077
  @failure ||= e
2007
2078
  raise
@@ -8,7 +8,7 @@ module Microsandbox
8
8
  # Versioning section of the README for the full gem-to-runtime map. Must equal
9
9
  # the native ext's Cargo crate version (`Native.version`), enforced by
10
10
  # spec/unit/version_spec.rb.
11
- VERSION = "0.17.1"
11
+ VERSION = "0.17.2"
12
12
 
13
13
  # The upstream microsandbox runtime release this gem build embeds — the `tag`
14
14
  # pinned on the `microsandbox`/`microsandbox-network` git deps in
data/sig/microsandbox.rbs CHANGED
@@ -82,6 +82,7 @@ module Microsandbox
82
82
  end
83
83
 
84
84
  class FsEntry
85
+ def initialize: (Hash[String, untyped] data) -> void
85
86
  def path: () -> String
86
87
  def name: () -> String
87
88
  def type: () -> Symbol
@@ -94,6 +95,7 @@ module Microsandbox
94
95
  end
95
96
 
96
97
  class FsMetadata
98
+ def initialize: (Hash[String, untyped] data) -> void
97
99
  def type: () -> Symbol
98
100
  def size: () -> Integer
99
101
  def mode: () -> Integer
@@ -106,6 +108,7 @@ module Microsandbox
106
108
  end
107
109
 
108
110
  class FS
111
+ def initialize: (untyped native) -> void
109
112
  def read: (String path) -> String
110
113
  def read_text: (String path) -> String
111
114
  def write: (String path, String data) -> nil
@@ -125,17 +128,20 @@ module Microsandbox
125
128
 
126
129
  class FsReadStream
127
130
  include Enumerable[String]
131
+ def initialize: (untyped native) -> void
128
132
  def each: () { (String) -> void } -> self
129
133
  | () -> Enumerator[String, self]
130
134
  def read: () -> String
131
135
  end
132
136
 
133
137
  class FsWriteSink
138
+ def initialize: (untyped native) -> void
134
139
  def write: (String data) -> self
135
140
  def close: () -> nil
136
141
  end
137
142
 
138
143
  class Metrics
144
+ def initialize: (Hash[String, untyped] data) -> void
139
145
  def cpu_percent: () -> Float
140
146
  def vcpu_time_ns: () -> Integer
141
147
  def memory_bytes: () -> Integer
@@ -154,6 +160,7 @@ module Microsandbox
154
160
  end
155
161
 
156
162
  class LogEntry
163
+ def initialize: (Hash[String, untyped] entry) -> void
157
164
  def source: () -> Symbol
158
165
  def session_id: () -> Integer?
159
166
  def cursor: () -> String
@@ -163,6 +170,7 @@ module Microsandbox
163
170
  end
164
171
 
165
172
  class SandboxHandle
173
+ def initialize: (untyped native) -> void
166
174
  def name: () -> String
167
175
  def id: () -> String
168
176
  def status: () -> Symbol
@@ -200,6 +208,7 @@ module Microsandbox
200
208
  SandboxInfo: singleton(SandboxHandle)
201
209
 
202
210
  class SandboxStopResult
211
+ def initialize: (Hash[String, untyped] data) -> void
203
212
  def name: () -> String
204
213
  def status: () -> Symbol
205
214
  def exit_code: () -> Integer?
@@ -290,6 +299,7 @@ module Microsandbox
290
299
  def self.list_with: (?labels: Hash[untyped, untyped], ?limit: Integer?, ?cursor: String?) -> SandboxPage
291
300
  def self.remove: (String name) -> nil
292
301
 
302
+ def initialize: (untyped native) -> void
293
303
  def name: () -> String
294
304
  def id: () -> String
295
305
  def exec: (String command, ?Array[String] args, ?cwd: String?, ?user: String?,
@@ -354,17 +364,20 @@ module Microsandbox
354
364
 
355
365
  class LogStream
356
366
  include Enumerable[LogEntry]
367
+ def initialize: (untyped native) -> void
357
368
  def each: () { (LogEntry) -> void } -> self
358
369
  | () -> Enumerator[LogEntry, self]
359
370
  end
360
371
 
361
372
  class MetricsStream
362
373
  include Enumerable[Metrics]
374
+ def initialize: (untyped native) -> void
363
375
  def each: () { (Metrics) -> void } -> self
364
376
  | () -> Enumerator[Metrics, self]
365
377
  end
366
378
 
367
379
  class ExecEvent
380
+ def initialize: (Hash[String, untyped] event) -> void
368
381
  def type: () -> Symbol
369
382
  def pid: () -> Integer?
370
383
  def code: () -> Integer?
@@ -379,18 +392,21 @@ module Microsandbox
379
392
  end
380
393
 
381
394
  class ExitStatus
395
+ def initialize: (Hash[String, untyped] data) -> void
382
396
  def exit_code: () -> Integer?
383
397
  def success?: () -> bool
384
398
  def failure?: () -> bool
385
399
  end
386
400
 
387
401
  class ExecStdin
402
+ def initialize: (untyped native) -> void
388
403
  def write: (String data) -> self
389
404
  def close: () -> nil
390
405
  end
391
406
 
392
407
  class ExecHandle
393
408
  include Enumerable[ExecEvent]
409
+ def initialize: (untyped native) -> void
394
410
  def id: () -> String
395
411
  def each: () { (ExecEvent) -> void } -> self
396
412
  | () -> Enumerator[ExecEvent, self]
@@ -403,6 +419,7 @@ module Microsandbox
403
419
  end
404
420
 
405
421
  class ImageInfo
422
+ def initialize: (Hash[String, untyped] data) -> void
406
423
  def reference: () -> String
407
424
  def size_bytes: () -> Integer?
408
425
  def manifest_digest: () -> String?
@@ -414,6 +431,7 @@ module Microsandbox
414
431
  end
415
432
 
416
433
  class ImageDetail
434
+ def initialize: (Hash[String, untyped] data) -> void
417
435
  def handle: () -> ImageInfo
418
436
  def config: () -> Hash[String, untyped]?
419
437
  def layers: () -> Array[Hash[String, untyped]]
@@ -421,6 +439,7 @@ module Microsandbox
421
439
  end
422
440
 
423
441
  class ImagePruneReport
442
+ def initialize: (Hash[String, untyped] data) -> void
424
443
  def image_refs_removed: () -> Integer
425
444
  def manifests_removed: () -> Integer
426
445
  def layers_removed: () -> Integer
@@ -441,6 +460,7 @@ module Microsandbox
441
460
  end
442
461
 
443
462
  class VolumeInfo
463
+ def initialize: (Hash[String, untyped] data) -> void
444
464
  def name: () -> String
445
465
  def path: () -> String?
446
466
  def kind: () -> Symbol?
@@ -481,6 +501,7 @@ module Microsandbox
481
501
  end
482
502
 
483
503
  class SnapshotInfo
504
+ def initialize: (Hash[String, untyped] data) -> void
484
505
  def digest: () -> String
485
506
  def path: () -> String
486
507
  def name: () -> String?
@@ -506,6 +527,7 @@ module Microsandbox
506
527
  end
507
528
 
508
529
  class SnapshotVerifyReport
530
+ def initialize: (Hash[String, untyped] data) -> void
509
531
  def digest: () -> String
510
532
  def path: () -> String
511
533
  def status: () -> Symbol
@@ -569,6 +591,7 @@ module Microsandbox
569
591
  end
570
592
 
571
593
  class BackendInfo
594
+ def initialize: (Hash[String, untyped] data) -> void
572
595
  def kind: () -> Symbol
573
596
  def api_url: () -> String?
574
597
  def source: () -> Symbol
@@ -643,6 +666,7 @@ module Microsandbox
643
666
 
644
667
  class AgentStream
645
668
  include Enumerable[AgentFrame]
669
+ def initialize: (untyped native, Integer id, Integer handle) -> void
646
670
  def id: () -> Integer
647
671
  def recv: () -> AgentFrame?
648
672
  def each: () { (AgentFrame) -> void } -> self
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.17.1
4
+ version: 0.17.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ya-luotao