Class: Daytona::SnapshotService

Inherits:
Object
  • Object
show all
Includes:
Instrumentation
Defined in:
lib/daytona/snapshot_service.rb

Constant Summary collapse

SNAPSHOTS_FETCH_LIMIT =
200

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Instrumentation

included

Constructor Details

#initialize(snapshots_api:, object_storage_api:, default_region_id: nil, otel_state: nil) ⇒ SnapshotService

Returns a new instance of SnapshotService.

Parameters:

  • snapshots_api (DaytonaApiClient::SnapshotsApi)

    The snapshots API client

  • object_storage_api (DaytonaApiClient::ObjectStorageApi)

    The object storage API client

  • default_region_id (String, nil) (defaults to: nil)

    Default region ID for snapshot creation

  • otel_state (Daytona::OtelState, nil) (defaults to: nil)


15
16
17
18
19
20
# File 'lib/daytona/snapshot_service.rb', line 15

def initialize(snapshots_api:, object_storage_api:, default_region_id: nil, otel_state: nil)
  @snapshots_api = snapshots_api
  @object_storage_api = object_storage_api
  @default_region_id = default_region_id
  @otel_state = otel_state
end

Class Method Details

.process_image_context(object_storage_api, image) ⇒ Array<String>

Processes the image context by uploading it to object storage

Parameters:

Returns:

  • (Array<String>)

    List of context hashes stored in object storage



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/daytona/snapshot_service.rb', line 132

def self.process_image_context(object_storage_api, image) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  return [] unless image.context_list && !image.context_list.empty?

  push_access_creds = object_storage_api.get_push_access

  object_storage = ObjectStorage.new(
    endpoint_url: push_access_creds.storage_url,
    aws_access_key_id: push_access_creds.access_key,
    aws_secret_access_key: push_access_creds.secret,
    aws_session_token: push_access_creds.session_token,
    bucket_name: push_access_creds.bucket
  )

  image.context_list.map do |context|
    object_storage.upload(
      context.source_path,
      push_access_creds.organization_id,
      context.archive_path
    )
  end
end

Instance Method Details

#activate(snapshot) ⇒ Daytona::Snapshot

Activate a snapshot

Parameters:

Returns:



124
# File 'lib/daytona/snapshot_service.rb', line 124

def activate(snapshot) = Snapshot.from_dto(snapshots_api.activate_snapshot(snapshot.id))

#create(params, on_logs: nil) ⇒ Daytona::Snapshot

Creates and registers a new snapshot from the given Image definition.

Examples:

image = Image.debianSlim('3.12').pipInstall('numpy')
params = CreateSnapshotParams.new(name: 'my-snapshot', image: image)
snapshot = daytona.snapshot.create(params) do |chunk|
  print chunk
end

Parameters:

  • params (Daytona::CreateSnapshotParams)

    Parameters for snapshot creation

  • on_logs (Proc, Nil) (defaults to: nil)

    Callback proc handling snapshot creation logs

Returns:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/daytona/snapshot_service.rb', line 82

def create(params, on_logs: nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  create_snapshot_req = DaytonaApiClient::CreateSnapshot.new(name: params.name)

  if params.image.is_a?(String)
    create_snapshot_req.image_name = params.image
    create_snapshot_req.entrypoint = params.entrypoint
  else
    create_snapshot_req.build_info = DaytonaApiClient::CreateBuildInfo.new(
      context_hashes: self.class.process_image_context(object_storage_api, params.image),
      dockerfile_content: if params.entrypoint
                            params.image.entrypoint(params.entrypoint).dockerfile
                          else
                            params.image.dockerfile
                          end
    )
  end

  if params.resources
    create_snapshot_req.cpu = params.resources.cpu
    create_snapshot_req.gpu = params.resources.gpu
    create_snapshot_req.memory = params.resources.memory
    create_snapshot_req.disk = params.resources.disk
  end

  create_snapshot_req.region_id = params.region_id || @default_region_id

  snapshot = snapshots_api.create_snapshot(create_snapshot_req)

  # Always wait for snapshot to be ready, regardless of on_logs
  snapshot = wait_for_snapshot(snapshot, on_logs:)

  if [DaytonaApiClient::SnapshotState::ERROR, DaytonaApiClient::SnapshotState::BUILD_FAILED].include?(snapshot.state)
    raise Sdk::Error, "Failed to create snapshot #{snapshot.name}, reason: #{snapshot.error_reason}"
  end

  Snapshot.from_dto(snapshot)
end

#delete(snapshot) ⇒ void

This method returns an undefined value.

Delete a Snapshot.

Examples:

daytona = Daytona::Daytona.new
snapshot = daytona.snapshot.get("demo")
daytona.snapshot.delete(snapshot)
puts "Snapshot deleted"

Parameters:



57
# File 'lib/daytona/snapshot_service.rb', line 57

def delete(snapshot) = snapshots_api.remove_snapshot(snapshot.id)

#get(name) ⇒ Daytona::Snapshot

Get a Snapshot by name.

Examples:

daytona = Daytona::Daytona.new
snapshot = daytona.snapshot.get("demo")
puts "#{snapshot.name} (#{snapshot.image_name})"

Parameters:

  • name (String)

    Name of the Snapshot to get

Returns:



68
# File 'lib/daytona/snapshot_service.rb', line 68

def get(name) = Snapshot.from_dto(snapshots_api.get_snapshot(name))

#list(page: nil, limit: nil) ⇒ Daytona::PaginatedResource

List all Snapshots.

Examples:

daytona = Daytona::Daytona.new
response = daytona.snapshot.list(page: 1, limit: 10)
snapshots.items.each { |snapshot| puts "#{snapshot.name} (#{snapshot.image_name})" }

Parameters:

  • page (Integer, Nil) (defaults to: nil)
  • limit (Integer, Nil) (defaults to: nil)

Returns:

Raises:



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/daytona/snapshot_service.rb', line 33

def list(page: nil, limit: nil)
  raise Sdk::Error, 'page must be positive integer' if page && page < 1

  raise Sdk::Error, 'limit must be positive integer' if limit && limit < 1

  response = snapshots_api.get_all_snapshots(page:, limit:)
  PaginatedResource.new(
    total: response.total,
    page: response.page,
    total_pages: response.total_pages,
    items: response.items.map { |snapshot_dto| Snapshot.from_dto(snapshot_dto) }
  )
end