daytona 0.203.0 → 0.205.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57b147a70b0002de1953dcb42e98e4b5a1d6b6901637c5bc744905ae38e9e1f6
4
- data.tar.gz: 1e08d695cb382017caf131b30f7679ed3701c6c14c6578cc00e53088a3e5d6d8
3
+ metadata.gz: ba9a97a7af09b8d505de9b5d107a764c5e150e21c5b336bd732f5ff8d98341cb
4
+ data.tar.gz: 22057c0b0bd750faa8403fed0b52716ff423d0223cbfc8059935a412bc127f2f
5
5
  SHA512:
6
- metadata.gz: a6d5d0106b273bc5d0c457171624849b198a664d5ccd39924f79501d0cec11151fb2772f070f3a3a4064d89e6fc9966803fcab0409a5ea25cbbd816e85f12b77
7
- data.tar.gz: 39d104c6d0d132034bd8453546e75b3675a801f9162051591ac74b94c4045ad268b4917a514ed5d831cd47bc670804eef0b054ceda75f159646976c8ca92fac4
6
+ metadata.gz: e66d5b8c8a2b3e11468840705f4bbc8c199ece6639047c9cbab4e0c69981740a413f474ea1a18b3162963e5c599aced27878f963899b4f890094f51000baa885
7
+ data.tar.gz: 888b3b55cdaded8230e1662816eb4b8bea4541737025da1796d997cd619d1438b6108d138a6e09f19fe0956e37d6c3a2ff47bf5ea55289184c97d703ea18a252
@@ -56,12 +56,23 @@ module Daytona
56
56
  # @return [String, nil] Comma-separated list of allowed domains for the Sandbox
57
57
  attr_accessor :domain_allow_list
58
58
 
59
+ # @return [String, nil] Outbound proxy URL to route the Sandbox HTTP(S) traffic through
60
+ attr_accessor :outbound_proxy_url
61
+
62
+ # @return [String, nil] OTel collector endpoint override for the Sandbox
63
+ attr_accessor :otel_endpoint_override
64
+
59
65
  # @return [Integer, nil] Time to live in minutes (0 to disable)
60
66
  attr_accessor :ttl_minutes
61
67
 
62
68
  # @return [Boolean, nil] Whether the Sandbox should be ephemeral
63
69
  attr_accessor :ephemeral
64
70
 
71
+ # @return [Boolean, nil] GPU-only. When true, the Sandbox may be instantly terminated without notice
72
+ # to free GPU capacity for an on-demand (non-spot) GPU Sandbox. Rejected when the Sandbox
73
+ # requests no GPUs.
74
+ attr_accessor :spot
75
+
65
76
  # @return [String, nil] ID or name of an existing Sandbox to link the new Sandbox to. The new
66
77
  # Sandbox will be scheduled on the same runner as the linked Sandbox so a local network can be
67
78
  # established between them. Linked Sandboxes must be
@@ -86,8 +97,16 @@ module Daytona
86
97
  # @param network_block_all [Boolean, nil] Whether to block all network access for the Sandbox
87
98
  # @param network_allow_list [String, nil] Comma-separated list of allowed CIDR network addresses for the Sandbox
88
99
  # @param domain_allow_list [String, nil] Comma-separated list of allowed domains for the Sandbox
100
+ # @param outbound_proxy_url [String, nil] Outbound proxy URL to route the Sandbox HTTP(S) traffic through.
101
+ # Applied via the HTTP(S)_PROXY environment variables; combine with domain_allow_list for
102
+ # network-layer enforcement.
103
+ # @param otel_endpoint_override [String, nil] OTel collector endpoint override for the Sandbox. When set,
104
+ # sandbox OTel data is sent to this endpoint instead of the default collector and will not be
105
+ # available in the Daytona analytics API or dashboard.
89
106
  # @param ttl_minutes [Integer, nil] Time to live in minutes (0 to disable)
90
107
  # @param ephemeral [Boolean, nil] Whether the Sandbox should be ephemeral
108
+ # @param spot [Boolean, nil] GPU-only. Whether the Sandbox may be instantly terminated to free GPU
109
+ # capacity for an on-demand GPU Sandbox
91
110
  # @param linked_sandbox [String, nil] ID or name of an existing Sandbox to link the new Sandbox to
92
111
  def initialize( # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
93
112
  language: nil,
@@ -106,7 +125,10 @@ module Daytona
106
125
  network_block_all: nil,
107
126
  network_allow_list: nil,
108
127
  domain_allow_list: nil,
128
+ outbound_proxy_url: nil,
129
+ otel_endpoint_override: nil,
109
130
  ephemeral: nil,
131
+ spot: nil,
110
132
  linked_sandbox: nil
111
133
  )
112
134
  @language = language
@@ -125,7 +147,10 @@ module Daytona
125
147
  @network_block_all = network_block_all
126
148
  @network_allow_list = network_allow_list
127
149
  @domain_allow_list = domain_allow_list
150
+ @outbound_proxy_url = outbound_proxy_url
151
+ @otel_endpoint_override = otel_endpoint_override
128
152
  @ephemeral = ephemeral
153
+ @spot = spot
129
154
  @linked_sandbox = linked_sandbox
130
155
 
131
156
  # Handle ephemeral and auto_delete_interval conflict
@@ -153,7 +178,10 @@ module Daytona
153
178
  network_block_all:,
154
179
  network_allow_list:,
155
180
  domain_allow_list:,
181
+ outbound_proxy_url:,
182
+ otel_endpoint_override:,
156
183
  ephemeral:,
184
+ spot:,
157
185
  linked_sandbox:
158
186
  }.compact
159
187
  end
@@ -207,6 +235,12 @@ module Daytona
207
235
  # @param network_block_all [Boolean, nil] Whether to block all network access for the Sandbox
208
236
  # @param network_allow_list [String, nil] Comma-separated list of allowed CIDR network addresses for the Sandbox
209
237
  # @param domain_allow_list [String, nil] Comma-separated list of allowed domains for the Sandbox
238
+ # @param outbound_proxy_url [String, nil] Outbound proxy URL to route the Sandbox HTTP(S) traffic through.
239
+ # Applied via the HTTP(S)_PROXY environment variables; combine with domain_allow_list for
240
+ # network-layer enforcement.
241
+ # @param otel_endpoint_override [String, nil] OTel collector endpoint override for the Sandbox. When set,
242
+ # sandbox OTel data is sent to this endpoint instead of the default collector and will not be
243
+ # available in the Daytona analytics API or dashboard.
210
244
  # @param ephemeral [Boolean, nil] Whether the Sandbox should be ephemeral
211
245
  def initialize(image:, resources: nil, **args)
212
246
  @image = image
@@ -250,6 +284,12 @@ module Daytona
250
284
  # @param network_block_all [Boolean, nil] Whether to block all network access for the Sandbox
251
285
  # @param network_allow_list [String, nil] Comma-separated list of allowed CIDR network addresses for the Sandbox
252
286
  # @param domain_allow_list [String, nil] Comma-separated list of allowed domains for the Sandbox
287
+ # @param outbound_proxy_url [String, nil] Outbound proxy URL to route the Sandbox HTTP(S) traffic through.
288
+ # Applied via the HTTP(S)_PROXY environment variables; combine with domain_allow_list for
289
+ # network-layer enforcement.
290
+ # @param otel_endpoint_override [String, nil] OTel collector endpoint override for the Sandbox. When set,
291
+ # sandbox OTel data is sent to this endpoint instead of the default collector and will not be
292
+ # available in the Daytona analytics API or dashboard.
253
293
  # @param ephemeral [Boolean, nil] Whether the Sandbox should be ephemeral
254
294
  def initialize(snapshot: nil, **args)
255
295
  @snapshot = snapshot
@@ -43,6 +43,14 @@ module Daytona
43
43
  end
44
44
 
45
45
  class Snapshot
46
+ # Matches RFC 4122 UUIDs (versions 1-5) and the nil UUID - the same set the
47
+ # Daytona API recognizes as snapshot IDs. Anything else is treated as a name.
48
+ SNAPSHOT_ID_PATTERN = Regexp.new(
49
+ '\A(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}' \
50
+ '|00000000-0000-0000-0000-000000000000)\z',
51
+ Regexp::IGNORECASE
52
+ ).freeze
53
+
46
54
  # @return [String] Unique identifier for the Snapshot
47
55
  attr_reader :id
48
56
 
@@ -94,6 +102,9 @@ module Daytona
94
102
  # @return [DaytonaApiClient::BuildInfo, nil] Build information for the snapshot
95
103
  attr_reader :build_info
96
104
 
105
+ # @return [String, nil] ID of the sandbox the Snapshot was created from
106
+ attr_reader :source_sandbox_id
107
+
97
108
  # @param snapshot_dto [DaytonaApiClient::SnapshotDto] The snapshot DTO from the API
98
109
  def initialize(snapshot_dto) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
99
110
  @id = snapshot_dto.id
@@ -113,6 +124,7 @@ module Daytona
113
124
  @updated_at = snapshot_dto.updated_at
114
125
  @last_used_at = snapshot_dto.last_used_at
115
126
  @build_info = snapshot_dto.build_info
127
+ @source_sandbox_id = snapshot_dto.source_sandbox_id
116
128
  end
117
129
 
118
130
  # Creates a Snapshot instance from a SnapshotDto
@@ -120,5 +132,11 @@ module Daytona
120
132
  # @param dto [DaytonaApiClient::SnapshotDto] The snapshot DTO from the API
121
133
  # @return [Daytona::Snapshot] The snapshot instance
122
134
  def self.from_dto(dto) = new(dto)
135
+
136
+ # Whether the given value looks like a Snapshot ID (a UUID) rather than a name.
137
+ #
138
+ # @param value [Object] value to test
139
+ # @return [Boolean] true when value is a UUID-shaped String
140
+ def self.id?(value) = value.is_a?(String) && SNAPSHOT_ID_PATTERN.match?(value)
123
141
  end
124
142
  end
@@ -25,6 +25,9 @@ module Daytona
25
25
  # @return [Daytona::SecretService]
26
26
  attr_reader :secret
27
27
 
28
+ # @return [Daytona::WarmPoolService]
29
+ attr_reader :warm_pool
30
+
28
31
  # @return [DaytonaApiClient::ObjectStorageApi]
29
32
  attr_reader :object_storage_api
30
33
 
@@ -53,6 +56,7 @@ module Daytona
53
56
  @analytics_api_url_mutex = Mutex.new
54
57
  @volume = VolumeService.new(DaytonaApiClient::VolumesApi.new(api_client), otel_state:)
55
58
  @secret = SecretService.new(DaytonaApiClient::SecretApi.new(api_client), otel_state:)
59
+ @warm_pool = WarmPoolService.new(DaytonaApiClient::WarmPoolsApi.new(api_client), otel_state:)
56
60
  @object_storage_api = DaytonaApiClient::ObjectStorageApi.new(api_client)
57
61
  @snapshots_api = DaytonaApiClient::SnapshotsApi.new(api_client)
58
62
  @snapshot = SnapshotService.new(
@@ -289,7 +293,10 @@ module Daytona
289
293
  network_block_all: params.network_block_all,
290
294
  network_allow_list: params.network_allow_list,
291
295
  domain_allow_list: params.domain_allow_list,
292
- linked_sandbox: params.linked_sandbox
296
+ outbound_proxy_url: params.outbound_proxy_url,
297
+ otel_endpoint_override: params.otel_endpoint_override,
298
+ linked_sandbox: params.linked_sandbox,
299
+ spot: params.spot
293
300
  )
294
301
 
295
302
  create_sandbox.snapshot = params.snapshot if params.respond_to?(:snapshot)
@@ -88,6 +88,10 @@ module Daytona
88
88
  # Not returned by list results; call #refresh on each item to populate.
89
89
  attr_reader :domain_allow_list
90
90
 
91
+ # @return [String, nil] Outbound proxy URL to route the sandbox HTTP(S) traffic through.
92
+ # Not returned by list results; call #refresh on each item to populate.
93
+ attr_reader :outbound_proxy_url
94
+
91
95
  # @return [String] The target environment for the sandbox
92
96
  attr_reader :target
93
97
 
@@ -97,6 +101,13 @@ module Daytona
97
101
  # @return [Float] The GPU quota for the sandbox
98
102
  attr_reader :gpu
99
103
 
104
+ # @return [Boolean] Whether this is a spot GPU sandbox. Spot sandboxes may be instantly terminated
105
+ # to free capacity for on-demand GPU sandboxes.
106
+ attr_reader :spot
107
+
108
+ # @return [String, nil] When the sandbox was evicted by spot preemption
109
+ attr_reader :spot_evicted_at
110
+
100
111
  # @return [Float] The memory quota for the sandbox
101
112
  attr_reader :memory
102
113
 
@@ -1081,6 +1092,8 @@ module Daytona
1081
1092
  @target = sandbox_dto.target
1082
1093
  @cpu = sandbox_dto.cpu
1083
1094
  @gpu = sandbox_dto.gpu
1095
+ @spot = sandbox_dto.spot || false
1096
+ @spot_evicted_at = sandbox_dto.spot_evicted_at
1084
1097
  @memory = sandbox_dto.memory
1085
1098
  @disk = sandbox_dto.disk
1086
1099
  @desired_state = sandbox_dto.desired_state
@@ -1109,6 +1122,7 @@ module Daytona
1109
1122
  @network_block_all = sandbox_dto.network_block_all
1110
1123
  @network_allow_list = sandbox_dto.network_allow_list
1111
1124
  @domain_allow_list = sandbox_dto.domain_allow_list
1125
+ @outbound_proxy_url = sandbox_dto.outbound_proxy_url
1112
1126
  @volumes = sandbox_dto.volumes
1113
1127
  @build_info = sandbox_dto.build_info
1114
1128
  @backup_created_at = sandbox_dto.backup_created_at
@@ -120,6 +120,8 @@ module Daytona
120
120
  class GitPushRejectedError < ConflictError; end
121
121
  class GitDirtyWorktreeError < ConflictError; end
122
122
  class GitMergeConflictError < ConflictError; end
123
+ class GitTransportFailedError < BadGatewayError; end
124
+ class GitRemoteRejectedError < UnprocessableEntityError; end
123
125
 
124
126
  # Daemon: filesystem
125
127
  class FileNotFoundError < NotFoundError; end
@@ -177,6 +179,8 @@ module Daytona
177
179
  [SOURCE_DAEMON, 'GIT_PUSH_REJECTED'] => GitPushRejectedError,
178
180
  [SOURCE_DAEMON, 'GIT_DIRTY_WORKTREE'] => GitDirtyWorktreeError,
179
181
  [SOURCE_DAEMON, 'GIT_MERGE_CONFLICT'] => GitMergeConflictError,
182
+ [SOURCE_DAEMON, 'GIT_TRANSPORT_FAILED'] => GitTransportFailedError,
183
+ [SOURCE_DAEMON, 'GIT_REMOTE_REJECTED'] => GitRemoteRejectedError,
180
184
 
181
185
  # Daemon: filesystem
182
186
  [SOURCE_DAEMON, 'FILE_NOT_FOUND'] => FileNotFoundError,
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Daytona
7
7
  module Sdk
8
- VERSION = '0.203.0'
8
+ VERSION = '0.205.0'
9
9
  end
10
10
  end
data/lib/daytona/sdk.rb CHANGED
@@ -47,6 +47,8 @@ require_relative 'snapshot_service'
47
47
  require_relative 'util'
48
48
  require_relative 'volume'
49
49
  require_relative 'volume_service'
50
+ require_relative 'warm_pool'
51
+ require_relative 'warm_pool_service'
50
52
  require_relative 'process'
51
53
 
52
54
  module Daytona
@@ -26,6 +26,7 @@ module Daytona
26
26
  #
27
27
  # @param page [Integer, Nil]
28
28
  # @param limit [Integer, Nil]
29
+ # @param source_sandbox_id [String, Nil] Filter by the ID of the sandbox the snapshot was created from
29
30
  # @return [Daytona::PaginatedResource] Paginated list of all Snapshots
30
31
  # @raise [Daytona::Sdk::Error]
31
32
  #
@@ -34,12 +35,12 @@ module Daytona
34
35
  # page = daytona.snapshot.list(page: 2, limit: 10)
35
36
  # puts "Page #{page.page} of #{page.total_pages} (#{page.total} snapshots total)"
36
37
  # page.items.each { |snapshot| puts "#{snapshot.name} (#{snapshot.image_name})" }
37
- def list(page: nil, limit: nil)
38
+ def list(page: nil, limit: nil, source_sandbox_id: nil)
38
39
  raise Sdk::Error, 'page must be positive integer' if page && page < 1
39
40
 
40
41
  raise Sdk::Error, 'limit must be positive integer' if limit && limit < 1
41
42
 
42
- response = snapshots_api.get_all_snapshots(page:, limit:)
43
+ response = snapshots_api.get_all_snapshots(page:, limit:, source_sandbox_id:)
43
44
  PaginatedResource.new(
44
45
  total: response.total,
45
46
  page: response.page,
@@ -50,7 +51,10 @@ module Daytona
50
51
 
51
52
  # Delete a Snapshot.
52
53
  #
53
- # @param snapshot [Daytona::Snapshot] Snapshot to delete
54
+ # @param snapshot [Daytona::Snapshot, String] Snapshot to delete, or its ID or name.
55
+ # Call cost: 1 API call for a Snapshot object or UUID string; 2 for a name
56
+ # (resolve, then delete); up to 3 in the worst case for a UUID-formatted name
57
+ # (the optimistic delete 404s, then resolve + delete).
54
58
  # @return [void]
55
59
  #
56
60
  # @example
@@ -58,11 +62,13 @@ module Daytona
58
62
  # snapshot = daytona.snapshot.get("demo")
59
63
  # daytona.snapshot.delete(snapshot)
60
64
  # puts "Snapshot deleted"
61
- def delete(snapshot) = snapshots_api.remove_snapshot(snapshot.id)
65
+ def delete(snapshot)
66
+ call_with_resolved_id(snapshot) { |id| snapshots_api.remove_snapshot(id) }
67
+ end
62
68
 
63
- # Get a Snapshot by name.
69
+ # Get a Snapshot by ID or name.
64
70
  #
65
- # @param name [String] Name of the Snapshot to get
71
+ # @param name [String] ID or name of the Snapshot to get
66
72
  # @return [Daytona::Snapshot] The Snapshot object
67
73
  #
68
74
  # @example
@@ -126,11 +132,15 @@ module Daytona
126
132
  Snapshot.from_dto(snapshot)
127
133
  end
128
134
 
129
- # Activate a snapshot
135
+ # Activate a snapshot.
130
136
  #
131
- # @param snapshot [Daytona::Snapshot] The snapshot instance
137
+ # @param snapshot [Daytona::Snapshot, String] The Snapshot instance, or its ID or name.
138
+ # Call cost matches `delete`: 1 for an object or UUID string, 2 for a name,
139
+ # up to 3 for a UUID-formatted name (optimistic 404 then resolve + activate).
132
140
  # @return [Daytona::Snapshot]
133
- def activate(snapshot) = Snapshot.from_dto(snapshots_api.activate_snapshot(snapshot.id))
141
+ def activate(snapshot)
142
+ Snapshot.from_dto(call_with_resolved_id(snapshot) { |id| snapshots_api.activate_snapshot(id) })
143
+ end
134
144
 
135
145
  instrument :list, :delete, :get, :create, :activate, component: 'SnapshotService'
136
146
 
@@ -175,6 +185,30 @@ module Daytona
175
185
  # @return [Daytona::OtelState, nil]
176
186
  attr_reader :otel_state
177
187
 
188
+ # Invoke an ID-based Snapshot operation, resolving the given identifier with as
189
+ # few API calls as possible. Snapshot names may themselves be UUID-formatted, so
190
+ # a UUID-shaped string is first tried directly as an ID (single call) and only
191
+ # resolved through the API on a 404. Any other string costs one resolution call.
192
+ #
193
+ # @param snapshot [Daytona::Snapshot, String] Snapshot instance, ID, or name
194
+ # @yield [String] resolved Snapshot ID
195
+ # @yieldreturn [Object] operation result
196
+ # @return [Object] whatever the block returns
197
+ def call_with_resolved_id(snapshot)
198
+ return yield(snapshot.id) unless snapshot.is_a?(String)
199
+
200
+ if Snapshot.id?(snapshot)
201
+ begin
202
+ return yield(snapshot)
203
+ rescue DaytonaApiClient::ApiError => e
204
+ raise unless e.code == 404
205
+ end
206
+ end
207
+
208
+ resolved = snapshots_api.get_snapshot(snapshot)
209
+ yield(resolved.id)
210
+ end
211
+
178
212
  # Wait for snapshot to reach a terminal state (ACTIVE, ERROR, or BUILD_FAILED)
179
213
  # Optionally streams logs if on_logs callback is provided
180
214
  #
@@ -0,0 +1,75 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ # frozen_string_literal: true
5
+
6
+ module Daytona
7
+ # A warm pool of ready-to-use Sandboxes for a snapshot. `current_size` versus
8
+ # `pool` is the pool's status: `current_size` is the number of ready warm
9
+ # sandboxes, `pool` is the desired number. `error_reason` is set when the
10
+ # pool cannot be filled.
11
+ class WarmPool
12
+ # @return [String]
13
+ attr_reader :id
14
+
15
+ # @return [String]
16
+ attr_reader :organization_id
17
+
18
+ # @return [String]
19
+ attr_reader :snapshot
20
+
21
+ # @return [String]
22
+ attr_reader :target
23
+
24
+ # @return [Integer]
25
+ attr_reader :pool
26
+
27
+ # @return [Integer]
28
+ attr_reader :current_size
29
+
30
+ # @return [Integer]
31
+ attr_reader :cpu
32
+
33
+ # @return [Integer]
34
+ attr_reader :mem
35
+
36
+ # @return [Integer]
37
+ attr_reader :disk
38
+
39
+ # @return [String]
40
+ attr_reader :os_user
41
+
42
+ # @return [Hash{String => String}]
43
+ attr_reader :env
44
+
45
+ # @return [String, nil]
46
+ attr_reader :error_reason
47
+
48
+ # @return [String]
49
+ attr_reader :created_at
50
+
51
+ # @return [String]
52
+ attr_reader :updated_at
53
+
54
+ # Initialize warm pool from DTO
55
+ #
56
+ # @param warm_pool_dto [DaytonaApiClient::WarmPool]
57
+ def initialize(warm_pool_dto)
58
+ @id = warm_pool_dto.id
59
+ @organization_id = warm_pool_dto.organization_id
60
+ @snapshot = warm_pool_dto.snapshot
61
+ @target = warm_pool_dto.target
62
+ # The generated client deserializes OpenAPI numbers as Float; these are all integral.
63
+ @pool = warm_pool_dto.pool.to_i
64
+ @current_size = warm_pool_dto.current_size.to_i
65
+ @cpu = warm_pool_dto.cpu.to_i
66
+ @mem = warm_pool_dto.mem.to_i
67
+ @disk = warm_pool_dto.disk.to_i
68
+ @os_user = warm_pool_dto.os_user
69
+ @env = warm_pool_dto.env
70
+ @error_reason = warm_pool_dto.error_reason
71
+ @created_at = warm_pool_dto.created_at
72
+ @updated_at = warm_pool_dto.updated_at
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright Daytona Platforms Inc.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ # frozen_string_literal: true
5
+
6
+ module Daytona
7
+ class WarmPoolService
8
+ include Instrumentation
9
+
10
+ # Service for managing Daytona Warm Pools. Can be used to list, create, update and delete Warm Pools.
11
+ #
12
+ # @param warm_pools_api [DaytonaApiClient::WarmPoolsApi]
13
+ # @param otel_state [Daytona::OtelState, nil]
14
+ def initialize(warm_pools_api, otel_state: nil)
15
+ @warm_pools_api = warm_pools_api
16
+ @otel_state = otel_state
17
+ end
18
+
19
+ # Create a new Warm Pool.
20
+ #
21
+ # @param snapshot [String] The snapshot (ID or name) to keep warm sandboxes for
22
+ # @param pool [Integer] Number of warm sandboxes to keep ready
23
+ # @param target [String, nil] Target region; defaults to the organization default region
24
+ # @return [Daytona::WarmPool]
25
+ def create(snapshot, pool, target: nil)
26
+ WarmPool.new(warm_pools_api.create_warm_pool(DaytonaApiClient::CreateWarmPool.new(snapshot:, pool:, target:)))
27
+ end
28
+
29
+ # Delete a Warm Pool.
30
+ #
31
+ # @param warm_pool_id [String]
32
+ # @return [void]
33
+ def delete(warm_pool_id) = warm_pools_api.delete_warm_pool(warm_pool_id)
34
+
35
+ # List all Warm Pools.
36
+ #
37
+ # @return [Array<Daytona::WarmPool>]
38
+ def list
39
+ warm_pools_api.list_warm_pools.map { |warm_pool| WarmPool.new(warm_pool) }
40
+ end
41
+
42
+ # Update the desired size of a Warm Pool.
43
+ #
44
+ # @param warm_pool_id [String]
45
+ # @param pool [Integer] New desired number of warm sandboxes (0 drains the pool)
46
+ # @return [Daytona::WarmPool]
47
+ def update(warm_pool_id, pool)
48
+ WarmPool.new(warm_pools_api.update_warm_pool(warm_pool_id, DaytonaApiClient::UpdateWarmPool.new(pool:)))
49
+ end
50
+
51
+ instrument :create, :delete, :list, :update, component: 'WarmPoolService'
52
+
53
+ private
54
+
55
+ # @return [DaytonaApiClient::WarmPoolsApi]
56
+ attr_reader :warm_pools_api
57
+
58
+ # @return [Daytona::OtelState, nil]
59
+ attr_reader :otel_state
60
+ end
61
+ end
data/project.json CHANGED
@@ -92,7 +92,7 @@
92
92
  "dependsOn": [
93
93
  {
94
94
  "target": "publish",
95
- "projects": ["api-client-ruby", "toolbox-api-client-ruby", "analytics-api-client-ruby"]
95
+ "projects": ["analytics-api-client-ruby"]
96
96
  },
97
97
  "build"
98
98
  ]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daytona
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.203.0
4
+ version: 0.205.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daytona Platforms Inc.
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 1980-01-01 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: opentelemetry-exporter-otlp
@@ -85,42 +85,42 @@ dependencies:
85
85
  requirements:
86
86
  - - '='
87
87
  - !ruby/object:Gem::Version
88
- version: 0.203.0
88
+ version: 0.205.0
89
89
  type: :runtime
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - '='
94
94
  - !ruby/object:Gem::Version
95
- version: 0.203.0
95
+ version: 0.205.0
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: daytona_api_client
98
98
  requirement: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - '='
101
101
  - !ruby/object:Gem::Version
102
- version: 0.203.0
102
+ version: 0.205.0
103
103
  type: :runtime
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - '='
108
108
  - !ruby/object:Gem::Version
109
- version: 0.203.0
109
+ version: 0.205.0
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: daytona_toolbox_api_client
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - '='
115
115
  - !ruby/object:Gem::Version
116
- version: 0.203.0
116
+ version: 0.205.0
117
117
  type: :runtime
118
118
  prerelease: false
119
119
  version_requirements: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - '='
122
122
  - !ruby/object:Gem::Version
123
- version: 0.203.0
123
+ version: 0.205.0
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: dotenv
126
126
  requirement: !ruby/object:Gem::Requirement
@@ -238,6 +238,8 @@ files:
238
238
  - lib/daytona/utils/file_url_signing.rb
239
239
  - lib/daytona/volume.rb
240
240
  - lib/daytona/volume_service.rb
241
+ - lib/daytona/warm_pool.rb
242
+ - lib/daytona/warm_pool_service.rb
241
243
  - project.json
242
244
  - scripts/generate-docs.rb
243
245
  - sig/daytona/sdk.rbs
@@ -264,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
266
  - !ruby/object:Gem::Version
265
267
  version: '0'
266
268
  requirements: []
267
- rubygems_version: 3.6.9
269
+ rubygems_version: 3.7.2
268
270
  specification_version: 4
269
271
  summary: Ruby SDK for Daytona
270
272
  test_files: []