daytona 0.203.0 → 0.204.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: b9262546e49c3718967e3a0300303d4a29307bf48e05d3858adbbd64ed3c5476
4
+ data.tar.gz: f7292a5cb930340df80595e497782a28fab1beb9bb3bbb5b8147a52ed8a4c952
5
5
  SHA512:
6
- metadata.gz: a6d5d0106b273bc5d0c457171624849b198a664d5ccd39924f79501d0cec11151fb2772f070f3a3a4064d89e6fc9966803fcab0409a5ea25cbbd816e85f12b77
7
- data.tar.gz: 39d104c6d0d132034bd8453546e75b3675a801f9162051591ac74b94c4045ad268b4917a514ed5d831cd47bc670804eef0b054ceda75f159646976c8ca92fac4
6
+ metadata.gz: 5ea724b9fd64d2efc919c764b7236b008e4eeda909b1796d0c05b91e31085cc379fe7a8215949ec1d0f8de40851a045edffd9aaabdfa13767d2346567876ef18
7
+ data.tar.gz: 44b45171c7a2d21e1060c52f85ef90a9379d10ddaeaf5bd4b66ecd3dd097ba6cfe1b67ec86e8feb00cdd96bd25853ef82e8bcd35b53db3e395fcc39b04199420
@@ -56,6 +56,9 @@ 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
+
59
62
  # @return [Integer, nil] Time to live in minutes (0 to disable)
60
63
  attr_accessor :ttl_minutes
61
64
 
@@ -86,6 +89,9 @@ module Daytona
86
89
  # @param network_block_all [Boolean, nil] Whether to block all network access for the Sandbox
87
90
  # @param network_allow_list [String, nil] Comma-separated list of allowed CIDR network addresses for the Sandbox
88
91
  # @param domain_allow_list [String, nil] Comma-separated list of allowed domains for the Sandbox
92
+ # @param outbound_proxy_url [String, nil] Outbound proxy URL to route the Sandbox HTTP(S) traffic through.
93
+ # Applied via the HTTP(S)_PROXY environment variables; combine with domain_allow_list for
94
+ # network-layer enforcement.
89
95
  # @param ttl_minutes [Integer, nil] Time to live in minutes (0 to disable)
90
96
  # @param ephemeral [Boolean, nil] Whether the Sandbox should be ephemeral
91
97
  # @param linked_sandbox [String, nil] ID or name of an existing Sandbox to link the new Sandbox to
@@ -106,6 +112,7 @@ module Daytona
106
112
  network_block_all: nil,
107
113
  network_allow_list: nil,
108
114
  domain_allow_list: nil,
115
+ outbound_proxy_url: nil,
109
116
  ephemeral: nil,
110
117
  linked_sandbox: nil
111
118
  )
@@ -125,6 +132,7 @@ module Daytona
125
132
  @network_block_all = network_block_all
126
133
  @network_allow_list = network_allow_list
127
134
  @domain_allow_list = domain_allow_list
135
+ @outbound_proxy_url = outbound_proxy_url
128
136
  @ephemeral = ephemeral
129
137
  @linked_sandbox = linked_sandbox
130
138
 
@@ -153,6 +161,7 @@ module Daytona
153
161
  network_block_all:,
154
162
  network_allow_list:,
155
163
  domain_allow_list:,
164
+ outbound_proxy_url:,
156
165
  ephemeral:,
157
166
  linked_sandbox:
158
167
  }.compact
@@ -207,6 +216,9 @@ module Daytona
207
216
  # @param network_block_all [Boolean, nil] Whether to block all network access for the Sandbox
208
217
  # @param network_allow_list [String, nil] Comma-separated list of allowed CIDR network addresses for the Sandbox
209
218
  # @param domain_allow_list [String, nil] Comma-separated list of allowed domains for the Sandbox
219
+ # @param outbound_proxy_url [String, nil] Outbound proxy URL to route the Sandbox HTTP(S) traffic through.
220
+ # Applied via the HTTP(S)_PROXY environment variables; combine with domain_allow_list for
221
+ # network-layer enforcement.
210
222
  # @param ephemeral [Boolean, nil] Whether the Sandbox should be ephemeral
211
223
  def initialize(image:, resources: nil, **args)
212
224
  @image = image
@@ -250,6 +262,9 @@ module Daytona
250
262
  # @param network_block_all [Boolean, nil] Whether to block all network access for the Sandbox
251
263
  # @param network_allow_list [String, nil] Comma-separated list of allowed CIDR network addresses for the Sandbox
252
264
  # @param domain_allow_list [String, nil] Comma-separated list of allowed domains for the Sandbox
265
+ # @param outbound_proxy_url [String, nil] Outbound proxy URL to route the Sandbox HTTP(S) traffic through.
266
+ # Applied via the HTTP(S)_PROXY environment variables; combine with domain_allow_list for
267
+ # network-layer enforcement.
253
268
  # @param ephemeral [Boolean, nil] Whether the Sandbox should be ephemeral
254
269
  def initialize(snapshot: nil, **args)
255
270
  @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
@@ -289,6 +289,7 @@ module Daytona
289
289
  network_block_all: params.network_block_all,
290
290
  network_allow_list: params.network_allow_list,
291
291
  domain_allow_list: params.domain_allow_list,
292
+ outbound_proxy_url: params.outbound_proxy_url,
292
293
  linked_sandbox: params.linked_sandbox
293
294
  )
294
295
 
@@ -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
 
@@ -1109,6 +1113,7 @@ module Daytona
1109
1113
  @network_block_all = sandbox_dto.network_block_all
1110
1114
  @network_allow_list = sandbox_dto.network_allow_list
1111
1115
  @domain_allow_list = sandbox_dto.domain_allow_list
1116
+ @outbound_proxy_url = sandbox_dto.outbound_proxy_url
1112
1117
  @volumes = sandbox_dto.volumes
1113
1118
  @build_info = sandbox_dto.build_info
1114
1119
  @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.204.0'
9
9
  end
10
10
  end
@@ -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
  #
metadata CHANGED
@@ -1,7 +1,7 @@
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.204.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daytona Platforms Inc.
@@ -85,42 +85,42 @@ dependencies:
85
85
  requirements:
86
86
  - - '='
87
87
  - !ruby/object:Gem::Version
88
- version: 0.203.0
88
+ version: 0.204.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.204.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.204.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.204.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.204.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.204.0
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: dotenv
126
126
  requirement: !ruby/object:Gem::Requirement