Class: Daytona::FileSystem
- Inherits:
-
Object
- Object
- Daytona::FileSystem
- Includes:
- Instrumentation
- Defined in:
- lib/daytona/file_system.rb
Overview
rubocop:disable Metrics/ClassLength
Instance Attribute Summary collapse
-
#sandbox_id ⇒ String
readonly
The Sandbox ID.
-
#toolbox_api ⇒ DaytonaToolboxApiClient::FileSystemApi
readonly
API client for Sandbox operations.
Instance Method Summary collapse
-
#create_folder(path, mode) ⇒ void
Creates a new directory in the Sandbox at the specified path with the given permissions.
-
#delete_file(path, recursive: false) ⇒ void
Deletes a file from the Sandbox.
-
#download_file(remote_path, local_path = nil) ⇒ File?
Downloads a file from the Sandbox.
-
#download_file_stream(remote_path, timeout: 30 * 60, on_progress: nil, cancel_event: nil) {|chunk| ... } ⇒ Enumerator?
Downloads a single file from the Sandbox as a stream without buffering the entire file into memory.
-
#find_files(path, pattern) ⇒ Array<DaytonaApiClient::Match>
Searches for files containing a pattern, similar to the grep command.
-
#get_file_info(path) ⇒ DaytonaApiClient::FileInfo
Gets detailed information about a file or directory, including its size, permissions, and timestamps.
-
#initialize(sandbox_id:, toolbox_api:, otel_state: nil) ⇒ FileSystem
constructor
Initializes a new FileSystem instance.
-
#list_files(path, depth: nil) ⇒ Array<DaytonaApiClient::FileInfo>
Lists files and directories in a given path and returns their information, similar to the ls -l command.
-
#move_files(source, destination) ⇒ void
Moves or renames a file or directory.
-
#replace_in_files(files:, pattern:, new_value:) ⇒ Array<DaytonaApiClient::ReplaceResult>
Performs search and replace operations across multiple files.
-
#search_files(path, pattern) ⇒ DaytonaApiClient::SearchFilesResponse
Searches for files and directories whose names match the specified pattern.
-
#set_file_permissions(path:, mode: nil, owner: nil, group: nil) ⇒ void
Sets permissions and ownership for a file or directory.
-
#upload_file(source, remote_path) ⇒ void
Uploads a file to the specified path in the Sandbox.
-
#upload_file_stream(source, remote_path, timeout: 30 * 60, on_progress: nil, cancel_event: nil) ⇒ void
Streams
sourceto the Sandbox without buffering its contents in memory, with optional progress reporting. -
#upload_files(files) ⇒ void
Uploads multiple files to the Sandbox.
Methods included from Instrumentation
Constructor Details
#initialize(sandbox_id:, toolbox_api:, otel_state: nil) ⇒ FileSystem
Initializes a new FileSystem instance.
25 26 27 28 29 |
# File 'lib/daytona/file_system.rb', line 25 def initialize(sandbox_id:, toolbox_api:, otel_state: nil) @sandbox_id = sandbox_id @toolbox_api = toolbox_api @otel_state = otel_state end |
Instance Attribute Details
#sandbox_id ⇒ String (readonly)
Returns The Sandbox ID.
15 16 17 |
# File 'lib/daytona/file_system.rb', line 15 def sandbox_id @sandbox_id end |
#toolbox_api ⇒ DaytonaToolboxApiClient::FileSystemApi (readonly)
Returns API client for Sandbox operations.
18 19 20 |
# File 'lib/daytona/file_system.rb', line 18 def toolbox_api @toolbox_api end |
Instance Method Details
#create_folder(path, mode) ⇒ void
This method returns an undefined value.
Creates a new directory in the Sandbox at the specified path with the given permissions.
46 47 48 49 50 51 |
# File 'lib/daytona/file_system.rb', line 46 def create_folder(path, mode) Sdk.logger.debug("Creating folder #{path} with mode #{mode}") toolbox_api.create_folder(path, mode) rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to create folder') end |
#delete_file(path, recursive: false) ⇒ void
This method returns an undefined value.
Deletes a file from the Sandbox.
66 67 68 69 70 |
# File 'lib/daytona/file_system.rb', line 66 def delete_file(path, recursive: false) toolbox_api.delete_file(path, { recursive: }) rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to delete file') end |
#download_file(remote_path, local_path = nil) ⇒ File?
Downloads a file from the Sandbox. Returns the file contents as a string. This method is useful when you want to load the file into memory without saving it to disk. It can only be used for smaller files.
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/daytona/file_system.rb', line 149 def download_file(remote_path, local_path = nil) # rubocop:disable Metrics/MethodLength file = toolbox_api.download_file(remote_path) if local_path parent_dir = File.dirname(local_path) FileUtils.mkdir_p(parent_dir) unless parent_dir == '.' File.binwrite(local_path, file.open.read) nil else file end rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to download file') rescue IOError, SystemCallError => e raise Sdk::Error, "Failed to download file: #{e.}" end |
#download_file_stream(remote_path, timeout: 30 * 60, on_progress: nil, cancel_event: nil) {|chunk| ... } ⇒ Enumerator?
Downloads a single file from the Sandbox as a stream without buffering the entire file into memory. Yields file content in chunks to the given block, or returns an Enumerator if no block is given.
196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/daytona/file_system.rb', line 196 def download_file_stream(remote_path, timeout: 30 * 60, on_progress: nil, cancel_event: nil, &) return enum_for(__method__, remote_path, timeout:, on_progress:, cancel_event:) unless block_given? FileTransfer.stream_download(api_client: toolbox_api.api_client, remote_path: remote_path, timeout: timeout, on_progress: on_progress, cancel_event: cancel_event, &) nil rescue *Sdk::API_ERROR_CLASSES, Sdk::Error => e raise Sdk.wrap_error(e, 'Failed to download file') rescue IOError, SystemCallError => e raise Sdk::Error, "Failed to download file: #{e.}" end |
#find_files(path, pattern) ⇒ Array<DaytonaApiClient::Match>
Searches for files containing a pattern, similar to the grep command.
324 325 326 327 328 |
# File 'lib/daytona/file_system.rb', line 324 def find_files(path, pattern) toolbox_api.find_in_files(path, pattern) rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to find files') end |
#get_file_info(path) ⇒ DaytonaApiClient::FileInfo
Gets detailed information about a file or directory, including its size, permissions, and timestamps.
90 91 92 93 94 |
# File 'lib/daytona/file_system.rb', line 90 def get_file_info(path) toolbox_api.get_file_info(path) rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to get file info') end |
#list_files(path, depth: nil) ⇒ Array<DaytonaApiClient::FileInfo>
Lists files and directories in a given path and returns their information, similar to the ls -l command.
118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/daytona/file_system.rb', line 118 def list_files(path, depth: nil) if !depth.nil? && (!depth.is_a?(Integer) || depth < 1) raise Sdk::Error, 'Failed to list files: depth must be an integer of at least 1' end toolbox_api.list_files({ path:, depth: }.compact) rescue Sdk::Error raise rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to list files') end |
#move_files(source, destination) ⇒ void
This method returns an undefined value.
Moves or renames a file or directory. The parent directory of the destination must exist.
381 382 383 384 385 |
# File 'lib/daytona/file_system.rb', line 381 def move_files(source, destination) toolbox_api.move_file(source, destination) rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to move files') end |
#replace_in_files(files:, pattern:, new_value:) ⇒ Array<DaytonaApiClient::ReplaceResult>
Performs search and replace operations across multiple files.
412 413 414 415 416 417 418 419 420 421 |
# File 'lib/daytona/file_system.rb', line 412 def replace_in_files(files:, pattern:, new_value:) replace_request = DaytonaToolboxApiClient::ReplaceRequest.new( files: files, pattern: pattern, new_value: new_value ) toolbox_api.replace_in_files(replace_request) rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to replace in files') end |
#search_files(path, pattern) ⇒ DaytonaApiClient::SearchFilesResponse
Searches for files and directories whose names match the specified pattern. The pattern can be a simple string or a glob pattern.
348 349 350 351 352 |
# File 'lib/daytona/file_system.rb', line 348 def search_files(path, pattern) toolbox_api.search_files(path, pattern) rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to search files') end |
#set_file_permissions(path:, mode: nil, owner: nil, group: nil) ⇒ void
This method returns an undefined value.
Sets permissions and ownership for a file or directory. Any of the parameters can be nil to leave that attribute unchanged.
447 448 449 450 451 452 453 454 455 456 |
# File 'lib/daytona/file_system.rb', line 447 def (path:, mode: nil, owner: nil, group: nil) opts = {} opts[:mode] = mode if mode opts[:owner] = owner if owner opts[:group] = group if group toolbox_api.(path, opts) rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to set file permissions') end |
#upload_file(source, remote_path) ⇒ void
This method returns an undefined value.
Uploads a file to the specified path in the Sandbox. If a file already exists at the destination path, it will be overwritten.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/daytona/file_system.rb', line 229 def upload_file(source, remote_path) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength if source.is_a?(String) && File.exist?(source) # Source is a file path File.open(source, 'rb') { |file| toolbox_api.upload_file(remote_path, file: file) } elsif source.respond_to?(:read) # Source is an IO object toolbox_api.upload_file(remote_path, file: source) else # Tempfile.create yields a ::File (works with Typhoeus) but deletes # on block exit — too early if curl reads asynchronously. Write via # Tempfile, close it, then reopen as ::File for the upload. tmp = Tempfile.new('daytona_upload') begin tmp.binmode tmp.write(source.to_s.b) tmp.close File.open(tmp.path, 'rb') { |file| toolbox_api.upload_file(remote_path, file: file) } ensure tmp.unlink end end rescue *Sdk::API_ERROR_CLASSES => e raise Sdk.wrap_error(e, 'Failed to upload file') rescue IOError, SystemCallError => e raise Sdk::Error, "Failed to upload file: #{e.}" end |
#upload_file_stream(source, remote_path, timeout: 30 * 60, on_progress: nil, cancel_event: nil) ⇒ void
This method returns an undefined value.
Streams source to the Sandbox without buffering its contents in memory, with
optional progress reporting.
278 279 280 281 282 283 284 285 286 |
# File 'lib/daytona/file_system.rb', line 278 def upload_file_stream(source, remote_path, timeout: 30 * 60, on_progress: nil, cancel_event: nil) FileTransfer.stream_upload(api_client: toolbox_api.api_client, remote_path: remote_path, source: source, timeout: timeout, on_progress: on_progress, cancel_event: cancel_event) rescue *Sdk::API_ERROR_CLASSES, Sdk::Error => e raise Sdk.wrap_error(e, 'Failed to upload file') rescue IOError, SystemCallError => e raise Sdk::Error, "Failed to upload file: #{e.}" end |
#upload_files(files) ⇒ void
This method returns an undefined value.
Uploads multiple files to the Sandbox. If files already exist at the destination paths, they will be overwritten.
303 304 305 306 307 |
# File 'lib/daytona/file_system.rb', line 303 def upload_files(files) files.each { |file_upload| upload_file(file_upload.source, file_upload.destination) } rescue *Sdk::API_ERROR_CLASSES, Sdk::Error => e raise Sdk.wrap_error(e, 'Failed to upload files') end |