class DevboxLauncher::Box

Constants

CONFIG
CONFIG_PATH
DEFAULT_IDENTIFY_FILE_PATH
MAX_BOOT_RETRIES
SSH_CONFIG_PATH
WAIT_BOOT_IN_SECONDS
WAIT_BOOT_RESCUED_EXCEPTIONS

Attributes

account[R]
options[R]

Public Class Methods

new(account, options) click to toggle source
# File lib/devbox_launcher/models/box.rb, line 20
def initialize(account, options)
  @account = account
  @options = options
end

Public Instance Methods

cmd_args_for(method) click to toggle source
# File lib/devbox_launcher/models/box.rb, line 192
def cmd_args_for(method)
  args = {
    project: config[:project],
    account: account,
    zone: config[:zone],
  }.each_with_object([]) do |(key, val), arr|
    next if val.blank?
    arr << ["--#{key}", val].join("=")
  end.join(" ")

  [
    "gcloud",
    "compute",
    "instances",
    method,
    name,
    args
  ].join(" ")
end
config() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 178
def config
  return @config if @config

  if not CONFIG.has_key?(account)
    fail "No config in #{CONFIG_PATH} found for #{account}"
  end

  @config = CONFIG[account].with_indifferent_access
end
connect_mosh() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 42
def connect_mosh
  return if options[:mosh].nil?

  mosh_cmd = %Q(mosh #{hostname})
  system(mosh_cmd)
end
create_mutagen_session() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 134
def create_mutagen_session
  puts "Create mutagen session syncing local " \
    "#{mutagen_config.alpha_dir} with " \
    "#{hostname} #{mutagen_config.beta_dir}"

  create_mutagen_cmd = [
    "mutagen sync create",
    mutagen_config.alpha_dir,
    "#{hostname}:#{mutagen_config.beta_dir}",
    "--label=#{label}",
  ]
  create_mutagen_cmd << "--watch-mode-alpha=no-watch" if OS.linux?

  create_mutagen_stdout,
    create_mutagen_stderr,
    create_mutagen_status =
    Open3.capture3(create_mutagen_cmd.join(" "))

  if not create_mutagen_status.success?
    # mutagen prints to stdout and stderr
    msg = "Failed to create mutagen sessions: " \
      "#{create_mutagen_stdout} -" \
      "#{create_mutagen_stderr}"
    fail msg
  end
end
describe_cmd() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 86
def describe_cmd
  cmd_args_for('describe')
end
description(reload: false) click to toggle source
# File lib/devbox_launcher/models/box.rb, line 69
def description(reload: false)
  return @description if !reload && @description

  describe_stdout, describe_stderr, describe_status =
    Open3.capture3(describe_cmd)

  if !describe_status.success?
    msg = "Problem fetching the description of #{name}. "
    msg += "Please ensure you can call `#{describe_cmd}`.\n"
    msg += "Error:\n"
    msg += describe_stderr
    fail msg
  end

  @description = Description.new(describe_stdout)
end
hostname() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 170
def hostname
  [name, username, "devbox"].join("-")
end
label() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 130
def label
  "#{username}=#{name}"
end
mutagen_config() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 188
def mutagen_config
  @mutagen_config ||= Mutagen.new(config[:mutagen])
end
name() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 166
def name
  @name ||= config[:box]
end
reset_mutagen_session() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 104
def reset_mutagen_session
  return if !mutagen_config.configured?

  terminate_mutagen_session
  create_mutagen_session
  watch_alpha if OS.linux?
end
set_ssh_config!() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 90
def set_ssh_config!
  FileUtils.touch(SSH_CONFIG_PATH)
  config = ConfigFile.new
  args = {
    "HostName" => description.ip,
    "User" => username,
    "IdentityFile" => DEFAULT_IDENTIFY_FILE_PATH,
  }
  args.each do |key, value|
    config.set(hostname, key, value)
  end
  config.save
end
start() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 25
def start
  start_stdout, start_stderr, start_status =
    Open3.capture3(start_cmd)

  set_ssh_config!

  wait_boot

  reset_mutagen_session

  connect_mosh
end
start_cmd() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 38
def start_cmd
  cmd_args_for('start')
end
terminate_mutagen_session() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 112
def terminate_mutagen_session
  puts "Terminating mutagen session..."
  terminate_mutagen_cmd =
    %Q(mutagen terminate --label-selector=#{label})
  terminate_mutagen_stdout,
    terminate_mutagen_stderr,
    terminate_mutagen_status =
    Open3.capture3(terminate_mutagen_cmd)

  if not terminate_mutagen_status.success?
    # mutagen prints to stdout and stderr
    msg = "Failed to terminate mutagen sessions: " \
      "#{terminate_mutagen_stdout} -" \
      "#{terminate_mutagen_stderr}"
    fail msg
  end
end
username() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 174
def username
  @username ||= account.gsub(/\W/, "_")
end
wait_boot(tries: 1) click to toggle source
# File lib/devbox_launcher/models/box.rb, line 49
def wait_boot(tries: 1)
  Net::SSH.start(hostname, username, timeout: WAIT_BOOT_IN_SECONDS) do |ssh|
    puts "[#{ssh.exec!('date').chomp}] Machine booted"
  end
rescue *WAIT_BOOT_RESCUED_EXCEPTIONS
  puts "Not booted. Waiting #{WAIT_BOOT_IN_SECONDS} seconds before trying again..."

  sleep WAIT_BOOT_IN_SECONDS

  if !description(reload: true).running?
    puts "Detected that the machine is not running " \
      "(status is #{description.status}). Booting it..."
    start
  end

  fail if tries >= MAX_BOOT_RETRIES

  wait_boot tries: tries+1
end
watch_alpha() click to toggle source
# File lib/devbox_launcher/models/box.rb, line 161
def watch_alpha
  watchman = Watchman.new(dir: mutagen_config.alpha_dir)
  watchman.trigger("mutagen sync flush --label-selector=#{label}")
end