cogbox 0.190.1
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/.rspec +3 -0
- data/.rubocop.yml +22 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE +190 -0
- data/README.md +184 -0
- data/Rakefile +12 -0
- data/lib/cogbox/code_interpreter.rb +360 -0
- data/lib/cogbox/cogbox.rb +337 -0
- data/lib/cogbox/common/charts.rb +125 -0
- data/lib/cogbox/common/code_interpreter.rb +57 -0
- data/lib/cogbox/common/code_language.rb +15 -0
- data/lib/cogbox/common/cogbox.rb +231 -0
- data/lib/cogbox/common/file_system.rb +27 -0
- data/lib/cogbox/common/git.rb +20 -0
- data/lib/cogbox/common/image.rb +501 -0
- data/lib/cogbox/common/process.rb +150 -0
- data/lib/cogbox/common/pty.rb +310 -0
- data/lib/cogbox/common/resources.rb +40 -0
- data/lib/cogbox/common/response.rb +84 -0
- data/lib/cogbox/common/snapshot.rb +125 -0
- data/lib/cogbox/computer_use.rb +920 -0
- data/lib/cogbox/config.rb +110 -0
- data/lib/cogbox/file_system.rb +452 -0
- data/lib/cogbox/file_transfer.rb +384 -0
- data/lib/cogbox/git.rb +335 -0
- data/lib/cogbox/lsp_server.rb +140 -0
- data/lib/cogbox/object_storage.rb +173 -0
- data/lib/cogbox/otel.rb +184 -0
- data/lib/cogbox/process.rb +551 -0
- data/lib/cogbox/sandbox.rb +752 -0
- data/lib/cogbox/sdk/version.rb +11 -0
- data/lib/cogbox/sdk.rb +57 -0
- data/lib/cogbox/snapshot_service.rb +239 -0
- data/lib/cogbox/util.rb +81 -0
- data/lib/cogbox/volume.rb +47 -0
- data/lib/cogbox/volume_service.rb +62 -0
- data/lib/cogbox.rb +11 -0
- data/project.json +100 -0
- data/scripts/generate-docs.rb +403 -0
- data/sig/cogbox/sdk.rbs +6 -0
- metadata +240 -0
data/lib/cogbox/sdk.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# Copyright Cognifyi
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
require 'logger'
|
|
8
|
+
|
|
9
|
+
require 'cogbox_api_client'
|
|
10
|
+
require 'cogbox_toolbox_api_client'
|
|
11
|
+
require 'toml'
|
|
12
|
+
require 'websocket-client-simple'
|
|
13
|
+
|
|
14
|
+
require_relative 'sdk/version'
|
|
15
|
+
require_relative 'config'
|
|
16
|
+
require_relative 'otel'
|
|
17
|
+
require_relative 'common/charts'
|
|
18
|
+
require_relative 'common/code_interpreter'
|
|
19
|
+
require_relative 'common/code_language'
|
|
20
|
+
require_relative 'common/cogbox'
|
|
21
|
+
require_relative 'common/file_system'
|
|
22
|
+
require_relative 'common/image'
|
|
23
|
+
require_relative 'common/git'
|
|
24
|
+
require_relative 'common/process'
|
|
25
|
+
require_relative 'common/pty'
|
|
26
|
+
require_relative 'common/resources'
|
|
27
|
+
require_relative 'common/response'
|
|
28
|
+
require_relative 'common/snapshot'
|
|
29
|
+
require_relative 'code_interpreter'
|
|
30
|
+
require_relative 'computer_use'
|
|
31
|
+
require_relative 'cogbox'
|
|
32
|
+
require_relative 'file_system'
|
|
33
|
+
require_relative 'git'
|
|
34
|
+
require_relative 'lsp_server'
|
|
35
|
+
require_relative 'object_storage'
|
|
36
|
+
require_relative 'sandbox'
|
|
37
|
+
require_relative 'snapshot_service'
|
|
38
|
+
require_relative 'util'
|
|
39
|
+
require_relative 'volume'
|
|
40
|
+
require_relative 'volume_service'
|
|
41
|
+
require_relative 'process'
|
|
42
|
+
|
|
43
|
+
module Cogbox
|
|
44
|
+
module Sdk
|
|
45
|
+
class Error < StandardError; end
|
|
46
|
+
class TimeoutError < Error; end
|
|
47
|
+
class AuthenticationError < Error; end
|
|
48
|
+
class ForbiddenError < Error; end
|
|
49
|
+
class NotFoundError < Error; end
|
|
50
|
+
class ConflictError < Error; end
|
|
51
|
+
class ValidationError < Error; end
|
|
52
|
+
class RateLimitError < Error; end
|
|
53
|
+
class ServerError < Error; end
|
|
54
|
+
|
|
55
|
+
def self.logger = @logger ||= Logger.new($stdout, level: Logger::INFO)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# Copyright Cognifyi
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
require 'uri'
|
|
8
|
+
|
|
9
|
+
module Cogbox
|
|
10
|
+
class SnapshotService
|
|
11
|
+
include Instrumentation
|
|
12
|
+
|
|
13
|
+
SNAPSHOTS_FETCH_LIMIT = 200
|
|
14
|
+
|
|
15
|
+
# @param snapshots_api [CogboxApiClient::SnapshotsApi] The snapshots API client
|
|
16
|
+
# @param object_storage_api [CogboxApiClient::ObjectStorageApi] The object storage API client
|
|
17
|
+
# @param default_region_id [String, nil] Default region ID for snapshot creation
|
|
18
|
+
# @param otel_state [Cogbox::OtelState, nil]
|
|
19
|
+
def initialize(snapshots_api:, object_storage_api:, default_region_id: nil, otel_state: nil)
|
|
20
|
+
@snapshots_api = snapshots_api
|
|
21
|
+
@object_storage_api = object_storage_api
|
|
22
|
+
@default_region_id = default_region_id
|
|
23
|
+
@otel_state = otel_state
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# List all Snapshots.
|
|
27
|
+
#
|
|
28
|
+
# @param page [Integer, Nil]
|
|
29
|
+
# @param limit [Integer, Nil]
|
|
30
|
+
# @return [Cogbox::PaginatedResource] Paginated list of all Snapshots
|
|
31
|
+
# @raise [Cogbox::Sdk::Error]
|
|
32
|
+
#
|
|
33
|
+
# @example
|
|
34
|
+
# cogbox = Cogbox::Cogbox.new
|
|
35
|
+
# response = cogbox.snapshot.list(page: 1, limit: 10)
|
|
36
|
+
# snapshots.items.each { |snapshot| puts "#{snapshot.name} (#{snapshot.image_name})" }
|
|
37
|
+
def list(page: nil, limit: nil)
|
|
38
|
+
raise Sdk::Error, 'page must be positive integer' if page && page < 1
|
|
39
|
+
|
|
40
|
+
raise Sdk::Error, 'limit must be positive integer' if limit && limit < 1
|
|
41
|
+
|
|
42
|
+
response = snapshots_api.get_all_snapshots(page:, limit:)
|
|
43
|
+
PaginatedResource.new(
|
|
44
|
+
total: response.total,
|
|
45
|
+
page: response.page,
|
|
46
|
+
total_pages: response.total_pages,
|
|
47
|
+
items: response.items.map { |snapshot_dto| Snapshot.from_dto(snapshot_dto) }
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Delete a Snapshot.
|
|
52
|
+
#
|
|
53
|
+
# @param snapshot [Cogbox::Snapshot] Snapshot to delete
|
|
54
|
+
# @return [void]
|
|
55
|
+
#
|
|
56
|
+
# @example
|
|
57
|
+
# cogbox = Cogbox::Cogbox.new
|
|
58
|
+
# snapshot = cogbox.snapshot.get("demo")
|
|
59
|
+
# cogbox.snapshot.delete(snapshot)
|
|
60
|
+
# puts "Snapshot deleted"
|
|
61
|
+
def delete(snapshot) = snapshots_api.remove_snapshot(snapshot.id)
|
|
62
|
+
|
|
63
|
+
# Get a Snapshot by name.
|
|
64
|
+
#
|
|
65
|
+
# @param name [String] Name of the Snapshot to get
|
|
66
|
+
# @return [Cogbox::Snapshot] The Snapshot object
|
|
67
|
+
#
|
|
68
|
+
# @example
|
|
69
|
+
# cogbox = Cogbox::Cogbox.new
|
|
70
|
+
# snapshot = cogbox.snapshot.get("demo")
|
|
71
|
+
# puts "#{snapshot.name} (#{snapshot.image_name})"
|
|
72
|
+
def get(name) = Snapshot.from_dto(snapshots_api.get_snapshot(name))
|
|
73
|
+
|
|
74
|
+
# Creates and registers a new snapshot from the given Image definition.
|
|
75
|
+
#
|
|
76
|
+
# @param params [Cogbox::CreateSnapshotParams] Parameters for snapshot creation
|
|
77
|
+
# @param on_logs [Proc, Nil] Callback proc handling snapshot creation logs
|
|
78
|
+
# @return [Cogbox::Snapshot] The created snapshot
|
|
79
|
+
#
|
|
80
|
+
# @example
|
|
81
|
+
# image = Image.debianSlim('3.12').pipInstall('numpy')
|
|
82
|
+
# params = CreateSnapshotParams.new(name: 'my-snapshot', image: image)
|
|
83
|
+
# snapshot = cogbox.snapshot.create(params) do |chunk|
|
|
84
|
+
# print chunk
|
|
85
|
+
# end
|
|
86
|
+
def create(params, on_logs: nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
87
|
+
create_snapshot_req = CogboxApiClient::CreateSnapshot.new(name: params.name)
|
|
88
|
+
|
|
89
|
+
if params.image.is_a?(String)
|
|
90
|
+
create_snapshot_req.image_name = params.image
|
|
91
|
+
create_snapshot_req.entrypoint = params.entrypoint
|
|
92
|
+
else
|
|
93
|
+
create_snapshot_req.build_info = CogboxApiClient::CreateBuildInfo.new(
|
|
94
|
+
context_hashes: self.class.process_image_context(object_storage_api, params.image),
|
|
95
|
+
dockerfile_content: if params.entrypoint
|
|
96
|
+
params.image.entrypoint(params.entrypoint).dockerfile
|
|
97
|
+
else
|
|
98
|
+
params.image.dockerfile
|
|
99
|
+
end
|
|
100
|
+
)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
if params.resources
|
|
104
|
+
create_snapshot_req.cpu = params.resources.cpu
|
|
105
|
+
create_snapshot_req.gpu = params.resources.gpu
|
|
106
|
+
if params.resources.gpu_type
|
|
107
|
+
create_snapshot_req.gpu_type =
|
|
108
|
+
params.resources.gpu_type.is_a?(Array) ? params.resources.gpu_type : [params.resources.gpu_type]
|
|
109
|
+
end
|
|
110
|
+
create_snapshot_req.memory = params.resources.memory
|
|
111
|
+
create_snapshot_req.disk = params.resources.disk
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
create_snapshot_req.region_id = params.region_id || @default_region_id
|
|
115
|
+
create_snapshot_req.sandbox_class = params.sandbox_class
|
|
116
|
+
|
|
117
|
+
snapshot = snapshots_api.create_snapshot(create_snapshot_req)
|
|
118
|
+
|
|
119
|
+
# Always wait for snapshot to be ready, regardless of on_logs
|
|
120
|
+
snapshot = wait_for_snapshot(snapshot, on_logs:)
|
|
121
|
+
|
|
122
|
+
if [CogboxApiClient::SnapshotState::ERROR, CogboxApiClient::SnapshotState::BUILD_FAILED].include?(snapshot.state)
|
|
123
|
+
raise Sdk::Error, "Failed to create snapshot #{snapshot.name}, reason: #{snapshot.error_reason}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
Snapshot.from_dto(snapshot)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Activate a snapshot
|
|
130
|
+
#
|
|
131
|
+
# @param snapshot [Cogbox::Snapshot] The snapshot instance
|
|
132
|
+
# @return [Cogbox::Snapshot]
|
|
133
|
+
def activate(snapshot) = Snapshot.from_dto(snapshots_api.activate_snapshot(snapshot.id))
|
|
134
|
+
|
|
135
|
+
instrument :list, :delete, :get, :create, :activate, component: 'SnapshotService'
|
|
136
|
+
|
|
137
|
+
# Processes the image context by uploading it to object storage
|
|
138
|
+
#
|
|
139
|
+
# @param image [Cogbox::Image] The Image instance
|
|
140
|
+
# @return [Array<String>] List of context hashes stored in object storage
|
|
141
|
+
def self.process_image_context(object_storage_api, image) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
142
|
+
return [] unless image.context_list && !image.context_list.empty?
|
|
143
|
+
|
|
144
|
+
push_access_creds = object_storage_api.get_push_access
|
|
145
|
+
|
|
146
|
+
object_storage = ObjectStorage.new(
|
|
147
|
+
endpoint_url: push_access_creds.storage_url,
|
|
148
|
+
aws_access_key_id: push_access_creds.access_key,
|
|
149
|
+
aws_secret_access_key: push_access_creds.secret,
|
|
150
|
+
aws_session_token: push_access_creds.session_token,
|
|
151
|
+
bucket_name: push_access_creds.bucket
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
image.context_list.map do |context|
|
|
155
|
+
object_storage.upload(
|
|
156
|
+
context.source_path,
|
|
157
|
+
push_access_creds.organization_id,
|
|
158
|
+
context.archive_path
|
|
159
|
+
)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
private
|
|
164
|
+
|
|
165
|
+
# @return [CogboxApiClient::SnapshotsApi] The snapshots API client
|
|
166
|
+
attr_reader :snapshots_api
|
|
167
|
+
|
|
168
|
+
# @return [CogboxApiClient::ObjectStorageApi, nil] The object storage API client
|
|
169
|
+
attr_reader :object_storage_api
|
|
170
|
+
|
|
171
|
+
# @return [String, nil] Default region ID for snapshot creation
|
|
172
|
+
attr_reader :default_region_id
|
|
173
|
+
|
|
174
|
+
# @return [Cogbox::OtelState, nil]
|
|
175
|
+
attr_reader :otel_state
|
|
176
|
+
|
|
177
|
+
# Wait for snapshot to reach a terminal state (ACTIVE, ERROR, or BUILD_FAILED)
|
|
178
|
+
# Optionally streams logs if on_logs callback is provided
|
|
179
|
+
#
|
|
180
|
+
# @param snapshot [CogboxApiClient::SnapshotDto]
|
|
181
|
+
# @param on_logs [Proc, nil]
|
|
182
|
+
# @return [CogboxApiClient::SnapshotDto]
|
|
183
|
+
def wait_for_snapshot(snapshot, on_logs:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
184
|
+
terminal_states = [
|
|
185
|
+
CogboxApiClient::SnapshotState::ACTIVE,
|
|
186
|
+
CogboxApiClient::SnapshotState::ERROR,
|
|
187
|
+
CogboxApiClient::SnapshotState::BUILD_FAILED
|
|
188
|
+
]
|
|
189
|
+
|
|
190
|
+
thread = nil
|
|
191
|
+
previous_state = snapshot.state
|
|
192
|
+
|
|
193
|
+
# Log initial state if callback provided
|
|
194
|
+
on_logs&.call("Creating snapshot #{snapshot.name} (#{snapshot.state})")
|
|
195
|
+
|
|
196
|
+
until terminal_states.include?(snapshot.state)
|
|
197
|
+
Sdk.logger.debug("Waiting for snapshot to be created: #{snapshot.state}")
|
|
198
|
+
|
|
199
|
+
# Start log streaming thread if callback provided and snapshot is building
|
|
200
|
+
if on_logs && thread.nil? && snapshot.state != CogboxApiClient::SnapshotState::PENDING
|
|
201
|
+
thread = start_log_streaming(snapshot, on_logs:)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Log state changes if callback provided
|
|
205
|
+
if on_logs && previous_state != snapshot.state
|
|
206
|
+
if snapshot.state != CogboxApiClient::SnapshotState::PENDING && thread.nil?
|
|
207
|
+
thread = start_log_streaming(snapshot, on_logs:)
|
|
208
|
+
end
|
|
209
|
+
on_logs.call("Creating snapshot #{snapshot.name} (#{snapshot.state})")
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
sleep(1)
|
|
213
|
+
previous_state = snapshot.state
|
|
214
|
+
snapshot = snapshots_api.get_snapshot(snapshot.id)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
thread&.join
|
|
218
|
+
|
|
219
|
+
if on_logs && snapshot.state == CogboxApiClient::SnapshotState::ACTIVE
|
|
220
|
+
on_logs.call("Created snapshot #{snapshot.name} (#{snapshot.state})")
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
snapshot
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# @param snapshot [CogboxApiClient::SnapshotDto]
|
|
227
|
+
# @param on_logs [Proc]
|
|
228
|
+
# @return [Thread]
|
|
229
|
+
def start_log_streaming(snapshot, on_logs:)
|
|
230
|
+
# Get build logs URL from API
|
|
231
|
+
build_logs_response = snapshots_api.get_snapshot_build_logs_url(snapshot.id)
|
|
232
|
+
uri = URI.parse("#{build_logs_response.url}?follow=true")
|
|
233
|
+
|
|
234
|
+
headers = {}
|
|
235
|
+
snapshots_api.api_client.update_params_for_auth!(headers, nil, ['bearer'])
|
|
236
|
+
Util.stream_async(uri:, headers:, on_chunk: on_logs)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|
data/lib/cogbox/util.rb
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# Copyright Cognifyi
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
require 'net/http'
|
|
8
|
+
|
|
9
|
+
module Cogbox
|
|
10
|
+
module Util
|
|
11
|
+
STDOUT_PREFIX = "\x01\x01\01"
|
|
12
|
+
private_constant :STDOUT_PREFIX
|
|
13
|
+
|
|
14
|
+
STDERR_PREFIX = "\x02\x02\02"
|
|
15
|
+
private_constant :STDERR_PREFIX
|
|
16
|
+
|
|
17
|
+
PREFIX_LEN = STDOUT_PREFIX.bytesize
|
|
18
|
+
private_constant :PREFIX_LEN
|
|
19
|
+
|
|
20
|
+
def self.demux(line)
|
|
21
|
+
out_parts = []
|
|
22
|
+
err_parts = []
|
|
23
|
+
state = nil
|
|
24
|
+
pos = 0
|
|
25
|
+
|
|
26
|
+
while pos < line.bytesize
|
|
27
|
+
si = line.index(STDOUT_PREFIX, pos)
|
|
28
|
+
ei = line.index(STDERR_PREFIX, pos)
|
|
29
|
+
|
|
30
|
+
if si && (ei.nil? || si < ei)
|
|
31
|
+
next_idx = si
|
|
32
|
+
next_state = :stdout
|
|
33
|
+
elsif ei
|
|
34
|
+
next_idx = ei
|
|
35
|
+
next_state = :stderr
|
|
36
|
+
else
|
|
37
|
+
case state
|
|
38
|
+
when :stdout then out_parts << line[pos..]
|
|
39
|
+
when :stderr then err_parts << line[pos..]
|
|
40
|
+
end
|
|
41
|
+
break
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if pos < next_idx
|
|
45
|
+
chunk = line[pos...next_idx]
|
|
46
|
+
case state
|
|
47
|
+
when :stdout then out_parts << chunk
|
|
48
|
+
when :stderr then err_parts << chunk
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
state = next_state
|
|
53
|
+
pos = next_idx + PREFIX_LEN
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
[out_parts.join, err_parts.join]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @param uri [URI]
|
|
60
|
+
# @param on_chunk [Proc]
|
|
61
|
+
# @param headers [Hash<String, String>]
|
|
62
|
+
# @return [Thread]
|
|
63
|
+
def self.stream_async(uri:, on_chunk:, headers: nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
64
|
+
Sdk.logger.debug("Starting async stream: #{uri}")
|
|
65
|
+
Thread.new do
|
|
66
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
|
67
|
+
request = Net::HTTP::Get.new(uri, headers)
|
|
68
|
+
|
|
69
|
+
http.request(request) do |response|
|
|
70
|
+
response.read_body do |chunk|
|
|
71
|
+
Sdk.logger.debug("Chunked response received: #{chunk.inspect}")
|
|
72
|
+
on_chunk.call(chunk)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
rescue Net::ReadTimeout => e
|
|
77
|
+
Sdk.logger.debug("Async stream (#{uri}) timeout: #{e.inspect}")
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# Copyright Cognifyi
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
module Cogbox
|
|
8
|
+
class Volume
|
|
9
|
+
# @return [String]
|
|
10
|
+
attr_reader :id
|
|
11
|
+
|
|
12
|
+
# @return [String]
|
|
13
|
+
attr_reader :name
|
|
14
|
+
|
|
15
|
+
# @return [String]
|
|
16
|
+
attr_reader :organization_id
|
|
17
|
+
|
|
18
|
+
# @return [String]
|
|
19
|
+
attr_reader :state
|
|
20
|
+
|
|
21
|
+
# @return [String]
|
|
22
|
+
attr_reader :created_at
|
|
23
|
+
|
|
24
|
+
# @return [String]
|
|
25
|
+
attr_reader :updated_at
|
|
26
|
+
|
|
27
|
+
# @return [String]
|
|
28
|
+
attr_reader :last_used_at
|
|
29
|
+
|
|
30
|
+
# @return [String, nil]
|
|
31
|
+
attr_reader :error_reason
|
|
32
|
+
|
|
33
|
+
# Initialize volume from DTO
|
|
34
|
+
#
|
|
35
|
+
# @param volume_dto [CogboxApiClient::SandboxVolume]
|
|
36
|
+
def initialize(volume_dto)
|
|
37
|
+
@id = volume_dto.id
|
|
38
|
+
@name = volume_dto.name
|
|
39
|
+
@organization_id = volume_dto.organization_id
|
|
40
|
+
@state = volume_dto.state
|
|
41
|
+
@created_at = volume_dto.created_at
|
|
42
|
+
@updated_at = volume_dto.updated_at
|
|
43
|
+
@last_used_at = volume_dto.last_used_at
|
|
44
|
+
@error_reason = volume_dto.error_reason
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# Copyright Cognifyi
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
module Cogbox
|
|
8
|
+
class VolumeService
|
|
9
|
+
include Instrumentation
|
|
10
|
+
|
|
11
|
+
# Service for managing Cogbox Volumes. Can be used to list, get, create and delete Volumes.
|
|
12
|
+
#
|
|
13
|
+
# @param volumes_api [CogboxApiClient::VolumesApi]
|
|
14
|
+
# @param otel_state [Cogbox::OtelState, nil]
|
|
15
|
+
def initialize(volumes_api, otel_state: nil)
|
|
16
|
+
@volumes_api = volumes_api
|
|
17
|
+
@otel_state = otel_state
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Create new Volume.
|
|
21
|
+
#
|
|
22
|
+
# @param name [String]
|
|
23
|
+
# @return [Cogbox::Volume]
|
|
24
|
+
def create(name) = Volume.new(volumes_api.create_volume(CogboxApiClient::CreateVolume.new(name:)))
|
|
25
|
+
|
|
26
|
+
# Delete a Volume.
|
|
27
|
+
#
|
|
28
|
+
# @param volume [Cogbox::Volume]
|
|
29
|
+
# @return [void]
|
|
30
|
+
def delete(volume) = volumes_api.delete_volume(volume.id)
|
|
31
|
+
|
|
32
|
+
# Get a Volume by name.
|
|
33
|
+
#
|
|
34
|
+
# @param name [String]
|
|
35
|
+
# @param create [Boolean]
|
|
36
|
+
# @return [Cogbox::Volume]
|
|
37
|
+
def get(name, create: false)
|
|
38
|
+
Volume.new(volumes_api.get_volume_by_name(name))
|
|
39
|
+
rescue CogboxApiClient::ApiError => e
|
|
40
|
+
raise unless create && e.code == 404 && e.message.include?("Volume with name #{name} not found")
|
|
41
|
+
|
|
42
|
+
create(name)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# List all Volumes.
|
|
46
|
+
#
|
|
47
|
+
# @return [Array<Cogbox::Volume>]
|
|
48
|
+
def list
|
|
49
|
+
volumes_api.list_volumes.map { |volume| Volume.new(volume) }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
instrument :create, :delete, :get, :list, component: 'VolumeService'
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
# @return [CogboxApiClient::VolumesApi]
|
|
57
|
+
attr_reader :volumes_api
|
|
58
|
+
|
|
59
|
+
# @return [Cogbox::OtelState, nil]
|
|
60
|
+
attr_reader :otel_state
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/cogbox.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Copyright Daytona Platforms Inc.
|
|
2
|
+
# Copyright Cognifyi
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
# Main entry point for the Cogbox Ruby SDK
|
|
8
|
+
# This file provides a convenient way to require the entire SDK with:
|
|
9
|
+
# require 'cogbox'
|
|
10
|
+
|
|
11
|
+
require_relative 'cogbox/sdk'
|
data/project.json
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sdk-ruby",
|
|
3
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"projectType": "library",
|
|
5
|
+
"sourceRoot": "libs/sdk-ruby",
|
|
6
|
+
"tags": [],
|
|
7
|
+
"targets": {
|
|
8
|
+
"build": {
|
|
9
|
+
"executor": "nx:run-commands",
|
|
10
|
+
"options": {
|
|
11
|
+
"cwd": "{projectRoot}",
|
|
12
|
+
"commands": ["rm -f *.gem", "bundle install", "gem build cogbox.gemspec"],
|
|
13
|
+
"parallel": false
|
|
14
|
+
},
|
|
15
|
+
"dependsOn": [
|
|
16
|
+
{
|
|
17
|
+
"target": "build",
|
|
18
|
+
"projects": ["api-client-ruby", "toolbox-api-client-ruby"]
|
|
19
|
+
},
|
|
20
|
+
"set-version"
|
|
21
|
+
],
|
|
22
|
+
"outputs": ["{projectRoot}/**/*.gem"]
|
|
23
|
+
},
|
|
24
|
+
"set-version": {
|
|
25
|
+
"executor": "nx:run-commands",
|
|
26
|
+
"options": {
|
|
27
|
+
"cwd": "{projectRoot}",
|
|
28
|
+
"command": "if [ -n \"$RUBYGEMS_PKG_VERSION\" ]; then VER=\"${RUBYGEMS_PKG_VERSION#v}\"; sed -i \"s/VERSION = '[^']*'/VERSION = '$VER'/\" lib/cogbox/sdk/version.rb && echo \"Changed version to $VER\"; else echo \"Using version from version.rb\"; fi"
|
|
29
|
+
},
|
|
30
|
+
"cache": true,
|
|
31
|
+
"inputs": [
|
|
32
|
+
{ "env": "RUBYGEMS_PKG_VERSION" },
|
|
33
|
+
{ "env": "VERSION" }
|
|
34
|
+
],
|
|
35
|
+
"outputs": ["{projectRoot}/lib/cogbox/sdk/version.rb"]
|
|
36
|
+
},
|
|
37
|
+
"lint": {
|
|
38
|
+
"executor": "nx:run-commands",
|
|
39
|
+
"options": {
|
|
40
|
+
"cwd": "{projectRoot}",
|
|
41
|
+
"command": "bundle exec rubocop"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"test": {
|
|
45
|
+
"executor": "nx:run-commands",
|
|
46
|
+
"cache": true,
|
|
47
|
+
"inputs": [
|
|
48
|
+
"default",
|
|
49
|
+
"{workspaceRoot}/libs/api-client-ruby/**/*",
|
|
50
|
+
"{workspaceRoot}/libs/toolbox-api-client-ruby/**/*"
|
|
51
|
+
],
|
|
52
|
+
"outputs": [],
|
|
53
|
+
"options": {
|
|
54
|
+
"cwd": "{projectRoot}",
|
|
55
|
+
"command": "bundle exec rspec --format documentation --tag '~e2e'"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"test:e2e": {
|
|
59
|
+
"executor": "nx:run-commands",
|
|
60
|
+
"options": {
|
|
61
|
+
"cwd": "{projectRoot}",
|
|
62
|
+
"command": "bundle exec rspec spec/e2e_spec.rb --format documentation"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"format": {
|
|
66
|
+
"executor": "nx:run-commands",
|
|
67
|
+
"options": {
|
|
68
|
+
"cwd": "{projectRoot}",
|
|
69
|
+
"commands": ["bundle exec rubocop -a --fail-level=E"],
|
|
70
|
+
"parallel": false
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"docs": {
|
|
74
|
+
"executor": "nx:run-commands",
|
|
75
|
+
"outputs": ["{workspaceRoot}/apps/docs/src/content/docs/en/ruby-sdk/**/*"],
|
|
76
|
+
"options": {
|
|
77
|
+
"cwd": "{projectRoot}",
|
|
78
|
+
"command": "bash -O extglob -c 'rm -rf ../../apps/docs/src/content/docs/en/ruby-sdk/!(index.mdx)' && bundle exec ruby scripts/generate-docs.rb"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"publish": {
|
|
82
|
+
"executor": "nx:run-commands",
|
|
83
|
+
"options": {
|
|
84
|
+
"cwd": "{projectRoot}",
|
|
85
|
+
"commands": [
|
|
86
|
+
"mkdir -p ~/.gem && echo \":rubygems: $RUBYGEMS_API_KEY\" > ~/.gem/credentials && chmod 0600 ~/.gem/credentials",
|
|
87
|
+
"VER=${RUBYGEMS_PKG_VERSION#v}; if [ -n \"$VER\" ] && gem list -r \"^cogbox$\" --version \"$VER\" 2>/dev/null | grep -q .; then echo \"cogbox==$VER already on RubyGems, skipping push\"; else gem push cogbox-*.gem --key rubygems --host https://rubygems.org; fi"
|
|
88
|
+
],
|
|
89
|
+
"parallel": false
|
|
90
|
+
},
|
|
91
|
+
"dependsOn": [
|
|
92
|
+
{
|
|
93
|
+
"target": "publish",
|
|
94
|
+
"projects": ["api-client-ruby", "toolbox-api-client-ruby"]
|
|
95
|
+
},
|
|
96
|
+
"build"
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|