class ArtifactTools::Client

Use an object of this class to put/fetch files from storage specified with {ConfigFile}

Public Class Methods

new(config:, user: nil) click to toggle source

@param config [Hash] Configuration @param user [String] User name to connect to server with, overrides

ARTIFACT_STORAGE_USER and the on stored in config
# File lib/artifact_tools/client.rb, line 23
def initialize(config:, user: nil)
  @config = config
  user ||= ENV['ARTIFACT_STORAGE_USER'] || @config['user']
  @ssh = Net::SSH.start(@config['server'], user, non_interactive: true)
end

Public Instance Methods

fetch(file: nil, dest: nil, match: nil, verify: false, force: false) click to toggle source

Fetch a file from store

@param file [String] Path to file to fetch. Fetches all files from config if omitted. @param dest [String] Optional prefix to add to local path of the file being fetched. Uses cwd if omitted. @param match [Regexp] Optionally fetch only files matching this pattern. @param verify [Boolean] Whether to verify the checksum after the file is received. Slows the fetch.

@raise [HashMismatchError] In case checksum doesn’t match the one stored in the config file.

# File lib/artifact_tools/client.rb, line 37
def fetch(file: nil, dest: nil, match: nil, verify: false, force: false)
  files = @config['files'].keys
  files = [file] if file
  files.each do |entry|
    next if match && !entry.match?(match)

    entry_hash = @config['files'][entry]['hash']
    remote = compose_remote(entry, entry_hash)
    local = compose_local(dest, entry)
    next if !force && local_file_matches(local, entry_hash)

    @ssh.scp.download!(remote, local)
    verify(entry_hash, local) if verify
  end
end
put(file:) click to toggle source

Put a file to storage

@param file [String] Path to the file to store.

# File lib/artifact_tools/client.rb, line 56
def put(file:)
  hash = file_hash(file)
  remote = compose_remote(file, hash)
  ensure_remote_path_exists(remote)
  @ssh.scp.upload!(file, remote)
end

Private Instance Methods

compose_local(dest, file) click to toggle source
# File lib/artifact_tools/client.rb, line 84
def compose_local(dest, file)
  local = file
  local = "#{dest}/#{local}" if dest
  ensure_path_exists(local)
  local
end
compose_remote(file, hash) click to toggle source
# File lib/artifact_tools/client.rb, line 65
def compose_remote(file, hash)
  basename = File.basename(file)
  "#{@config['dir']}/#{hash}/#{basename}"
end
ensure_path_exists(local) click to toggle source
# File lib/artifact_tools/client.rb, line 70
def ensure_path_exists(local)
  dirname = File.dirname(local)
  return if File.directory?(dirname)

  FileUtils.mkdir_p(dirname)
end
ensure_remote_path_exists(remote) click to toggle source
# File lib/artifact_tools/client.rb, line 77
def ensure_remote_path_exists(remote)
  dirname = File.dirname(remote)
  return if File.directory?(dirname)

  @ssh.exec!("mkdir -p #{dirname}")
end
local_file_matches(local_file, expected_hash) click to toggle source
# File lib/artifact_tools/client.rb, line 98
def local_file_matches(local_file, expected_hash)
  File.exist?(local_file) && file_hash(local_file) == expected_hash
end
verify(expected_hash, path) click to toggle source
# File lib/artifact_tools/client.rb, line 91
def verify(expected_hash, path)
  actual_hash = file_hash(path)
  return unless expected_hash != actual_hash

  raise HashMismatchError, "File #{path} has hash: #{actual_hash} while it should have: #{expected_hash}"
end