daytona-sdk 0.125.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.
- checksums.yaml +7 -0
- data/.rubocop.yml +16 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/README.md +39 -0
- data/Rakefile +12 -0
- data/lib/daytona/code_toolbox/sandbox_python_code_toolbox.rb +439 -0
- data/lib/daytona/code_toolbox/sandbox_ts_code_toolbox.rb +23 -0
- data/lib/daytona/common/charts.rb +298 -0
- data/lib/daytona/common/code_language.rb +11 -0
- data/lib/daytona/common/daytona.rb +206 -0
- data/lib/daytona/common/file_system.rb +23 -0
- data/lib/daytona/common/git.rb +16 -0
- data/lib/daytona/common/image.rb +493 -0
- data/lib/daytona/common/process.rb +141 -0
- data/lib/daytona/common/pty.rb +306 -0
- data/lib/daytona/common/resources.rb +31 -0
- data/lib/daytona/common/response.rb +28 -0
- data/lib/daytona/common/snapshot.rb +110 -0
- data/lib/daytona/computer_use.rb +549 -0
- data/lib/daytona/config.rb +53 -0
- data/lib/daytona/daytona.rb +278 -0
- data/lib/daytona/file_system.rb +359 -0
- data/lib/daytona/git.rb +287 -0
- data/lib/daytona/lsp_server.rb +130 -0
- data/lib/daytona/object_storage.rb +169 -0
- data/lib/daytona/process.rb +484 -0
- data/lib/daytona/sandbox.rb +376 -0
- data/lib/daytona/sdk/version.rb +7 -0
- data/lib/daytona/sdk.rb +45 -0
- data/lib/daytona/snapshot_service.rb +198 -0
- data/lib/daytona/util.rb +56 -0
- data/lib/daytona/volume.rb +43 -0
- data/lib/daytona/volume_service.rb +49 -0
- data/sig/daytona/sdk.rbs +6 -0
- metadata +149 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'observer'
|
|
5
|
+
|
|
6
|
+
module Daytona
|
|
7
|
+
class PtySize
|
|
8
|
+
# @return [Integer] Number of terminal rows (height)
|
|
9
|
+
attr_reader :rows
|
|
10
|
+
|
|
11
|
+
# @return [Integer] Number of terminal columns (width)
|
|
12
|
+
attr_reader :cols
|
|
13
|
+
|
|
14
|
+
# Initialize a new PtySize
|
|
15
|
+
#
|
|
16
|
+
# @param rows [Integer] Number of terminal rows (height)
|
|
17
|
+
# @param cols [Integer] Number of terminal columns (width)
|
|
18
|
+
def initialize(rows:, cols:)
|
|
19
|
+
@rows = rows
|
|
20
|
+
@cols = cols
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class PtyResult
|
|
25
|
+
# @return [Integer, nil] Exit code of the PTY process (0 for success, non-zero for errors).
|
|
26
|
+
# nil if the process hasn't exited yet or exit code couldn't be determined.
|
|
27
|
+
attr_reader :exit_code
|
|
28
|
+
|
|
29
|
+
# @return [String, nil] Error message if the PTY failed or was terminated abnormally.
|
|
30
|
+
# nil if no error occurred.
|
|
31
|
+
attr_reader :error
|
|
32
|
+
|
|
33
|
+
# Initialize a new PtyResult
|
|
34
|
+
#
|
|
35
|
+
# @param exit_code [Integer, nil] Exit code of the PTY process
|
|
36
|
+
# @param error [String, nil] Error message if the PTY failed
|
|
37
|
+
def initialize(exit_code: nil, error: nil)
|
|
38
|
+
@exit_code = exit_code
|
|
39
|
+
@error = error
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class PtyHandle # rubocop:disable Metrics/ClassLength
|
|
44
|
+
include Observable
|
|
45
|
+
|
|
46
|
+
# @return [String] Session ID of the PTY session
|
|
47
|
+
attr_reader :session_id
|
|
48
|
+
|
|
49
|
+
# @return [Integer, nil] Exit code of the PTY process (if terminated)
|
|
50
|
+
attr_reader :exit_code
|
|
51
|
+
|
|
52
|
+
# @return [String, nil] Error message if the PTY failed
|
|
53
|
+
attr_reader :error
|
|
54
|
+
|
|
55
|
+
# Initialize the PTY handle.
|
|
56
|
+
#
|
|
57
|
+
# @param websocket [WebSocket::Client::Simple::Client] Connected WebSocket client connection
|
|
58
|
+
# @param session_id [String] Session ID of the PTY session
|
|
59
|
+
# @param handle_resize [Proc, nil] Optional callback for resizing the PTY
|
|
60
|
+
# @param handle_kill [Proc, nil] Optional callback for killing the PTY
|
|
61
|
+
def initialize(websocket, session_id:, handle_resize: nil, handle_kill: nil)
|
|
62
|
+
@websocket = websocket
|
|
63
|
+
@session_id = session_id
|
|
64
|
+
@handle_resize = handle_resize
|
|
65
|
+
@handle_kill = handle_kill
|
|
66
|
+
@exit_code = nil
|
|
67
|
+
@error = nil
|
|
68
|
+
@logger = Sdk.logger
|
|
69
|
+
|
|
70
|
+
@status = Status::INIT
|
|
71
|
+
subscribe
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Check if connected to the PTY session
|
|
75
|
+
#
|
|
76
|
+
# @return [Boolean] true if connected, false otherwise
|
|
77
|
+
def connected? = websocket.open?
|
|
78
|
+
|
|
79
|
+
# Wait for the PTY connection to be established
|
|
80
|
+
#
|
|
81
|
+
# @param timeout [Float] Maximum time in seconds to wait for connection. Defaults to 10.0
|
|
82
|
+
# @return [void]
|
|
83
|
+
# @raise [Daytona::Sdk::Error] If connection timeout is exceeded
|
|
84
|
+
def wait_for_connection(timeout: DEFAULT_TIMEOUT)
|
|
85
|
+
return if status == Status::CONNECTED
|
|
86
|
+
|
|
87
|
+
start_time = Time.now
|
|
88
|
+
|
|
89
|
+
sleep(SLEEP_INTERVAL) until status == Status::CONNECTED || (Time.now - start_time) > timeout
|
|
90
|
+
|
|
91
|
+
raise Sdk::Error, 'PTY connection timeout' unless status == Status::CONNECTED
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Send input to the PTY session
|
|
95
|
+
#
|
|
96
|
+
# @param input [String] Input to send to the PTY
|
|
97
|
+
# @return [void]
|
|
98
|
+
def send_input(input)
|
|
99
|
+
raise Sdk::Error, 'PTY session not connected' unless websocket.open?
|
|
100
|
+
|
|
101
|
+
websocket.send(input)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Resize the PTY terminal
|
|
105
|
+
#
|
|
106
|
+
# @param pty_size [PtySize] New terminal size
|
|
107
|
+
# @return [DaytonaApiClient::PtySessionInfo] Updated PTY session information
|
|
108
|
+
def resize(pty_size)
|
|
109
|
+
raise Sdk::Error, 'No resize handler available' unless handle_resize
|
|
110
|
+
|
|
111
|
+
handle_resize.call(pty_size)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Delete the PTY session
|
|
115
|
+
#
|
|
116
|
+
# @return [void]
|
|
117
|
+
def kill
|
|
118
|
+
raise Sdk::Error, 'No kill handler available' unless handle_kill
|
|
119
|
+
|
|
120
|
+
handle_kill.call
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Wait for the PTY session to complete
|
|
124
|
+
#
|
|
125
|
+
# @param on_data [Proc, nil] Optional callback to handle output data
|
|
126
|
+
# @return [Daytona::PtyResult] Result containing exit code and error information
|
|
127
|
+
def wait(timeout: nil, &on_data)
|
|
128
|
+
timeout ||= Float::INFINITY
|
|
129
|
+
return unless status == Status::CONNECTED
|
|
130
|
+
|
|
131
|
+
start_time = Time.now
|
|
132
|
+
add_observer(on_data, :call) if on_data
|
|
133
|
+
|
|
134
|
+
sleep(SLEEP_INTERVAL) while status == Status::CONNECTED && (Time.now - start_time) <= timeout
|
|
135
|
+
|
|
136
|
+
PtyResult.new(exit_code:, error:)
|
|
137
|
+
ensure
|
|
138
|
+
delete_observer(on_data) if on_data
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# @yieldparam [WebSocket::Frame::Data]
|
|
142
|
+
# @return [void]
|
|
143
|
+
def each(&)
|
|
144
|
+
return unless block_given?
|
|
145
|
+
|
|
146
|
+
queue = Queue.new
|
|
147
|
+
add_observer(proc { queue << _1 }, :call)
|
|
148
|
+
|
|
149
|
+
while websocket.open?
|
|
150
|
+
drain(queue, &)
|
|
151
|
+
sleep(SLEEP_INTERVAL)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
drain(queue, &)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Disconnect from the PTY session
|
|
158
|
+
#
|
|
159
|
+
# @return [void]
|
|
160
|
+
def disconnect = websocket.close
|
|
161
|
+
|
|
162
|
+
private
|
|
163
|
+
|
|
164
|
+
# @return [Symbol]
|
|
165
|
+
attr_reader :status
|
|
166
|
+
|
|
167
|
+
# @return [WebSocket::Client::Simple::Client]
|
|
168
|
+
attr_reader :websocket
|
|
169
|
+
|
|
170
|
+
# @return [Proc, Nil]
|
|
171
|
+
attr_reader :handle_kill
|
|
172
|
+
|
|
173
|
+
# @return [Proc, Nil]
|
|
174
|
+
attr_reader :handle_resize
|
|
175
|
+
|
|
176
|
+
# @return [Logger]
|
|
177
|
+
attr_reader :logger
|
|
178
|
+
|
|
179
|
+
# @return [void]
|
|
180
|
+
def subscribe
|
|
181
|
+
websocket.on(:open, &method(:on_websocket_open))
|
|
182
|
+
websocket.on(:close, &method(:on_websocket_close))
|
|
183
|
+
websocket.on(:message, &method(:on_websocket_message))
|
|
184
|
+
websocket.on(:error, &method(:on_websocket_error))
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# @return [void]
|
|
188
|
+
def on_websocket_open
|
|
189
|
+
logger.debug('[Websocket] open')
|
|
190
|
+
@status = Status::OPEN
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# @param error [Object, Nil]
|
|
194
|
+
# @return [void]
|
|
195
|
+
def on_websocket_close(error)
|
|
196
|
+
logger.debug("[Websocket] close: #{error.inspect}")
|
|
197
|
+
@status = Status::CLOSED
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# @param error [WebSocket::Frame::Incoming::Client]
|
|
201
|
+
# @return [void]
|
|
202
|
+
def on_websocket_message(message)
|
|
203
|
+
logger.debug("[Websocket] message(#{message.type}): #{message.data}")
|
|
204
|
+
|
|
205
|
+
case message.type
|
|
206
|
+
when :binary, :text
|
|
207
|
+
process_websocket_text_message(message)
|
|
208
|
+
when :close
|
|
209
|
+
process_websocket_close_message(message)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# @param error [Object]
|
|
214
|
+
# @return [void]
|
|
215
|
+
def on_websocket_error(error)
|
|
216
|
+
logger.debug("[Websocket] error: #{error.inspect}")
|
|
217
|
+
logger.debug("[Websocket] error: #{error.class}")
|
|
218
|
+
@status = Status::ERROR
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# @param message [WebSocket::Frame::Incoming::Client]
|
|
222
|
+
# @return [void]
|
|
223
|
+
def process_websocket_text_message(message)
|
|
224
|
+
data = JSON.parse(message.data.to_s, symbolize_names: true)
|
|
225
|
+
process_websocket_control_message(data) if data[:type] == WebSocketMessageType::CONTROL
|
|
226
|
+
rescue JSON::ParserError, TypeError
|
|
227
|
+
process_websocket_data_message(message.data.to_s)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# @param data [WebSocket::Frame::Data]
|
|
231
|
+
# @return [void]
|
|
232
|
+
def process_websocket_data_message(data)
|
|
233
|
+
changed
|
|
234
|
+
notify_observers(data)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# @param data [WebSocket::Frame::Data]
|
|
238
|
+
# @return [void]
|
|
239
|
+
def process_websocket_control_message(data) # rubocop:disable Metrics/MethodLength
|
|
240
|
+
case data[:status]
|
|
241
|
+
when WebSocketControlStatus::CONNECTED
|
|
242
|
+
logger.debug('[control] connected')
|
|
243
|
+
@status = Status::CONNECTED
|
|
244
|
+
when WebSocketControlStatus::ERROR
|
|
245
|
+
logger.debug("[control] error: #{error.inspect}")
|
|
246
|
+
@status = Status::ERROR
|
|
247
|
+
@error = data.fetch(:error, 'Unknown connection error')
|
|
248
|
+
else
|
|
249
|
+
websocket.close
|
|
250
|
+
raise Sdk::Error, "Received invalid control message status: #{data[:status]}"
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# @param message [WebSocket::Frame::Incoming::Client]
|
|
255
|
+
# @return [void]
|
|
256
|
+
def process_websocket_close_message(message)
|
|
257
|
+
data = JSON.parse(message.data.to_s, symbolize_names: true)
|
|
258
|
+
@exit_code = data.fetch(:exitCode, nil)
|
|
259
|
+
@error = data.fetch(:exitReason, nil)
|
|
260
|
+
|
|
261
|
+
disconnect
|
|
262
|
+
rescue JSON::ParserError, TypeError
|
|
263
|
+
nil
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# @param queue [Queue]
|
|
267
|
+
# @yieldparam [WebSocket::Frame::Data]
|
|
268
|
+
# @return [void]
|
|
269
|
+
def drain(queue)
|
|
270
|
+
data = nil
|
|
271
|
+
|
|
272
|
+
yield data while (data = queue.pop(true))
|
|
273
|
+
rescue ThreadError => _e
|
|
274
|
+
nil
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
DEFAULT_TIMEOUT = 10.0
|
|
278
|
+
private_constant :DEFAULT_TIMEOUT
|
|
279
|
+
|
|
280
|
+
SLEEP_INTERVAL = 0.1
|
|
281
|
+
private_constant :SLEEP_INTERVAL
|
|
282
|
+
|
|
283
|
+
module Status
|
|
284
|
+
ALL = [
|
|
285
|
+
INIT = 'init',
|
|
286
|
+
OPEN = 'open',
|
|
287
|
+
CONNECTED = 'connected',
|
|
288
|
+
CLOSED = 'closed',
|
|
289
|
+
ERROR = 'error'
|
|
290
|
+
].freeze
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
module WebSocketMessageType
|
|
294
|
+
ALL = [
|
|
295
|
+
CONTROL = 'control'
|
|
296
|
+
].freeze
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
module WebSocketControlStatus
|
|
300
|
+
ALL = [
|
|
301
|
+
CONNECTED = 'connected',
|
|
302
|
+
ERORR = 'error'
|
|
303
|
+
].freeze
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Daytona
|
|
4
|
+
class Resources
|
|
5
|
+
# @return [Integer, nil] Number of CPU cores to allocate
|
|
6
|
+
attr_reader :cpu
|
|
7
|
+
|
|
8
|
+
# @return [Integer, nil] Amount of memory in GiB to allocate
|
|
9
|
+
attr_reader :memory
|
|
10
|
+
|
|
11
|
+
# @return [Integer, nil] Amount of disk space in GiB to allocate
|
|
12
|
+
attr_reader :disk
|
|
13
|
+
|
|
14
|
+
# @return [Integer, nil] Number of GPUs to allocate
|
|
15
|
+
attr_reader :gpu
|
|
16
|
+
|
|
17
|
+
# @param cpu [Integer, nil] Number of CPU cores to allocate
|
|
18
|
+
# @param memory [Integer, nil] Amount of memory in GiB to allocate
|
|
19
|
+
# @param disk [Integer, nil] Amount of disk space in GiB to allocate
|
|
20
|
+
# @param gpu [Integer, nil] Number of GPUs to allocate
|
|
21
|
+
def initialize(cpu: nil, memory: nil, disk: nil, gpu: nil)
|
|
22
|
+
@cpu = cpu
|
|
23
|
+
@memory = memory
|
|
24
|
+
@disk = disk
|
|
25
|
+
@gpu = gpu
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [Hash] Hash representation of the resources
|
|
29
|
+
def to_h = { cpu:, memory:, disk:, gpu: }.compact
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Daytona
|
|
4
|
+
class PaginatedResource
|
|
5
|
+
# @return [Array<Object>]
|
|
6
|
+
attr_reader :items
|
|
7
|
+
|
|
8
|
+
# @return [Float]
|
|
9
|
+
attr_reader :page
|
|
10
|
+
|
|
11
|
+
# @return [Float]
|
|
12
|
+
attr_reader :total
|
|
13
|
+
|
|
14
|
+
# @return [Float]
|
|
15
|
+
attr_reader :total_pages
|
|
16
|
+
|
|
17
|
+
# @param items [Daytona::Sandbox]
|
|
18
|
+
# @param page [Float]
|
|
19
|
+
# @param total [Float]
|
|
20
|
+
# @param total_pages [Float]
|
|
21
|
+
def initialize(items:, page:, total:, total_pages:)
|
|
22
|
+
@items = items
|
|
23
|
+
@page = page
|
|
24
|
+
@total = total
|
|
25
|
+
@total_pages = total_pages
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Daytona
|
|
4
|
+
class CreateSnapshotParams
|
|
5
|
+
# @return [String] Name of the snapshot
|
|
6
|
+
attr_reader :name
|
|
7
|
+
|
|
8
|
+
# @return [String, Daytona::Image] Image of the snapshot. If a string is provided,
|
|
9
|
+
# it should be available on some registry. If an Image instance is provided,
|
|
10
|
+
# it will be used to create a new image in Daytona.
|
|
11
|
+
attr_reader :image
|
|
12
|
+
|
|
13
|
+
# @return [Daytona::Resources, nil] Resources of the snapshot
|
|
14
|
+
attr_reader :resources
|
|
15
|
+
|
|
16
|
+
# @return [Array<String>, nil] Entrypoint of the snapshot
|
|
17
|
+
attr_reader :entrypoint
|
|
18
|
+
|
|
19
|
+
# @param name [String] Name of the snapshot
|
|
20
|
+
# @param image [String, Daytona::Image] Image of the snapshot
|
|
21
|
+
# @param resources [Daytona::Resources, nil] Resources of the snapshot
|
|
22
|
+
# @param entrypoint [Array<String>, nil] Entrypoint of the snapshot
|
|
23
|
+
def initialize(name:, image:, resources: nil, entrypoint: nil)
|
|
24
|
+
@name = name
|
|
25
|
+
@image = image
|
|
26
|
+
@resources = resources
|
|
27
|
+
@entrypoint = entrypoint
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Snapshot
|
|
32
|
+
# @return [String] Unique identifier for the Snapshot
|
|
33
|
+
attr_reader :id
|
|
34
|
+
|
|
35
|
+
# @return [String, nil] Organization ID of the Snapshot
|
|
36
|
+
attr_reader :organization_id
|
|
37
|
+
|
|
38
|
+
# @return [Boolean, nil] Whether the Snapshot is general
|
|
39
|
+
attr_reader :general
|
|
40
|
+
|
|
41
|
+
# @return [String] Name of the Snapshot
|
|
42
|
+
attr_reader :name
|
|
43
|
+
|
|
44
|
+
# @return [String] Name of the Image of the Snapshot
|
|
45
|
+
attr_reader :image_name
|
|
46
|
+
|
|
47
|
+
# @return [String] State of the Snapshot
|
|
48
|
+
attr_reader :state
|
|
49
|
+
|
|
50
|
+
# @return [Float, nil] Size of the Snapshot
|
|
51
|
+
attr_reader :size
|
|
52
|
+
|
|
53
|
+
# @return [Array<String>, nil] Entrypoint of the Snapshot
|
|
54
|
+
attr_reader :entrypoint
|
|
55
|
+
|
|
56
|
+
# @return [Float] CPU of the Snapshot
|
|
57
|
+
attr_reader :cpu
|
|
58
|
+
|
|
59
|
+
# @return [Float] GPU of the Snapshot
|
|
60
|
+
attr_reader :gpu
|
|
61
|
+
|
|
62
|
+
# @return [Float] Memory of the Snapshot in GiB
|
|
63
|
+
attr_reader :mem
|
|
64
|
+
|
|
65
|
+
# @return [Float] Disk of the Snapshot in GiB
|
|
66
|
+
attr_reader :disk
|
|
67
|
+
|
|
68
|
+
# @return [String, nil] Error reason of the Snapshot
|
|
69
|
+
attr_reader :error_reason
|
|
70
|
+
|
|
71
|
+
# @return [String] Timestamp when the Snapshot was created
|
|
72
|
+
attr_reader :created_at
|
|
73
|
+
|
|
74
|
+
# @return [String] Timestamp when the Snapshot was last updated
|
|
75
|
+
attr_reader :updated_at
|
|
76
|
+
|
|
77
|
+
# @return [String, nil] Timestamp when the Snapshot was last used
|
|
78
|
+
attr_reader :last_used_at
|
|
79
|
+
|
|
80
|
+
# @return [DaytonaApiClient::BuildInfo, nil] Build information for the snapshot
|
|
81
|
+
attr_reader :build_info
|
|
82
|
+
|
|
83
|
+
# @param snapshot_dto [DaytonaApiClient::SnapshotDto] The snapshot DTO from the API
|
|
84
|
+
def initialize(snapshot_dto) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
85
|
+
@id = snapshot_dto.id
|
|
86
|
+
@organization_id = snapshot_dto.organization_id
|
|
87
|
+
@general = snapshot_dto.general
|
|
88
|
+
@name = snapshot_dto.name
|
|
89
|
+
@image_name = snapshot_dto.image_name
|
|
90
|
+
@state = snapshot_dto.state
|
|
91
|
+
@size = snapshot_dto.size
|
|
92
|
+
@entrypoint = snapshot_dto.entrypoint
|
|
93
|
+
@cpu = snapshot_dto.cpu
|
|
94
|
+
@gpu = snapshot_dto.gpu
|
|
95
|
+
@mem = snapshot_dto.mem
|
|
96
|
+
@disk = snapshot_dto.disk
|
|
97
|
+
@error_reason = snapshot_dto.error_reason
|
|
98
|
+
@created_at = snapshot_dto.created_at
|
|
99
|
+
@updated_at = snapshot_dto.updated_at
|
|
100
|
+
@last_used_at = snapshot_dto.last_used_at
|
|
101
|
+
@build_info = snapshot_dto.build_info
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Creates a Snapshot instance from a SnapshotDto
|
|
105
|
+
#
|
|
106
|
+
# @param dto [DaytonaApiClient::SnapshotDto] The snapshot DTO from the API
|
|
107
|
+
# @return [Daytona::Snapshot] The snapshot instance
|
|
108
|
+
def self.from_dto(dto) = new(dto)
|
|
109
|
+
end
|
|
110
|
+
end
|