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 +4 -4
- data/lib/daytona/common/daytona.rb +15 -0
- data/lib/daytona/common/snapshot.rb +18 -0
- data/lib/daytona/daytona.rb +1 -0
- data/lib/daytona/sandbox.rb +5 -0
- data/lib/daytona/sdk/errors.rb +4 -0
- data/lib/daytona/sdk/version.rb +1 -1
- data/lib/daytona/snapshot_service.rb +43 -9
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b9262546e49c3718967e3a0300303d4a29307bf48e05d3858adbbd64ed3c5476
|
|
4
|
+
data.tar.gz: f7292a5cb930340df80595e497782a28fab1beb9bb3bbb5b8147a52ed8a4c952
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
data/lib/daytona/daytona.rb
CHANGED
|
@@ -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
|
|
data/lib/daytona/sandbox.rb
CHANGED
|
@@ -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
|
data/lib/daytona/sdk/errors.rb
CHANGED
|
@@ -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,
|
data/lib/daytona/sdk/version.rb
CHANGED
|
@@ -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)
|
|
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]
|
|
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
|
|
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)
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
123
|
+
version: 0.204.0
|
|
124
124
|
- !ruby/object:Gem::Dependency
|
|
125
125
|
name: dotenv
|
|
126
126
|
requirement: !ruby/object:Gem::Requirement
|