class Bosh::Cli::Command::Micro

Constants

DEFAULT_CONFIG_PATH
MICRO_BOSH_YAML
MICRO_DIRECTOR_PORT

Public Class Methods

new(runner) click to toggle source
Calls superclass method
# File lib/bosh/cli/commands/micro.rb, line 13
def initialize(runner)
  super(runner)
  options[:config] ||= DEFAULT_CONFIG_PATH # hijack Cli::Config
end

Public Instance Methods

agent(*args) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 283
def agent(*args)
  message = args.shift
  args = args.map do |arg|
    if File.exists?(arg)
      load_yaml_file(arg)
    else
      arg
    end
  end

  say(deployer.agent.send(message.to_sym, *args).pretty_inspect)
end
apply(spec) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 298
def apply(spec)
  config = Bosh::Deployer::Config
  deployer.apply(Bosh::Deployer::Specification.new(load_yaml_file(spec), config))
end
delete() click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 193
def delete
  unless deployer.exists?
    err 'No existing instance to delete'
  end

  name = deployer.state.name

  say(
    "\nYou are going to delete micro BOSH deployment '#{name}'.\n\n" +
    "THIS IS A VERY DESTRUCTIVE OPERATION AND IT CANNOT BE UNDONE!\n".make_red
  )

  unless confirmed?
    say 'Canceled deleting deployment'.make_green
    return
  end

  renderer = Bosh::Deployer::DeployerRenderer.new(Bosh::Cli::TaskTracking::EventLogRenderer.new)
  deployer.renderer = renderer

  start_time = Time.now

  deployer.delete_deployment

  renderer.finish('done')

  duration = renderer.duration || (Time.now - start_time)

  say("Deleted deployment '#{name}', took #{format_time(duration).make_green} to complete")
end
list() click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 226
def list
  file = File.join(work_dir, Bosh::Deployer::DeploymentsState::DEPLOYMENTS_FILE)
  if File.exists?(file)
    deployments = load_yaml_file(file)['instances']
  else
    deployments = []
  end

  err('No deployments') if deployments.size == 0

  na = 'n/a'

  deployments_table = table do |t|
    t.headings = ['Name', 'VM name', 'Stemcell name']
    deployments.each do |r|
      t << [r[:name], r[:vm_cid] || na, r[:stemcell_cid] || na]
    end
  end

  say("\n")
  say(deployments_table)
  say("\n")
  say("Deployments total: #{deployments.size}")
end
micro_deployment(name = nil) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 30
def micro_deployment(name = nil)
  if name
    set_current(name)
  else
    show_current
  end
end
micro_help() click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 20
def micro_help
  say('bosh micro sub-commands:')
  nl
  cmds = Bosh::Cli::Config.commands
  cmds = cmds.values.find_all { |c| c.usage =~ /^micro/ }
  Bosh::Cli::Command::Help.list_commands(cmds)
end
perform(stemcell = nil) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 105
def perform(stemcell = nil)
  update = !!options[:update]

  err 'No deployment set' unless deployment

  manifest = load_yaml_file(deployment)

  if stemcell.nil?
    unless manifest.is_a?(Hash)
      err('Invalid manifest format')
    end

    stemcell = dig_hash(manifest, 'resources', 'cloud_properties', 'image_id')

    if stemcell.nil?
      err 'No stemcell provided'
    end
  end

  deployer.check_dependencies

  rel_path = strip_relative_path(deployment)

  desc = "'#{rel_path.make_green}' to '#{target_name.make_green}'"

  if deployer.exists?
    if !options[:update_if_exists] && !update
      err 'Instance exists. Did you mean to --update?'
    end
    confirmation = 'Updating'
    method = :update_deployment
  else
    prefered_dir = File.dirname(File.dirname(deployment))

    unless prefered_dir == Dir.pwd
      confirm_deployment(
        "\n#{'No `bosh-deployments.yml` file found in current directory.'.make_red}\n\n" +
        'Conventionally, `bosh-deployments.yml` should be saved in ' +
        "#{prefered_dir.make_green}.\n" +
        "Is #{Dir.pwd.make_yellow} a directory where you can save state?"
      )
    end

    err 'No existing instance to update' if update
    confirmation = 'Deploying new micro BOSH instance'
    method = :create_deployment

    # make sure the user knows a persistent disk is required
    unless dig_hash(manifest, 'resources', 'persistent_disk')
      quit("No persistent disk configured in #{MICRO_BOSH_YAML}".make_red)
    end
  end

  confirm_deployment("#{confirmation} #{desc}")

  if File.extname(stemcell) == '.tgz'
    stemcell_file = Bosh::Cli::Stemcell.new(stemcell)

    say("\nVerifying stemcell...")
    stemcell_file.validate
    say("\n")

    unless stemcell_file.valid?
      err('Stemcell is invalid, please fix, verify and upload again')
    end

    stemcell_archive = Bosh::Stemcell::Archive.new(stemcell)
  end

  renderer = Bosh::Deployer::DeployerRenderer.new(Bosh::Cli::TaskTracking::EventLogRenderer.new)
  deployer.renderer = renderer

  start_time = Time.now

  deployer.send(method, stemcell, stemcell_archive)

  renderer.finish('done')

  duration = renderer.duration || (Time.now - start_time)

  update_target

  say("Deployed #{desc}, took #{format_time(duration).make_green} to complete")
end
set_current(name) click to toggle source

rubocop:disable MethodLength

# File lib/bosh/cli/commands/micro.rb, line 39
def set_current(name)
  manifest_filename = find_deployment(name)

  unless File.exists?(manifest_filename)
    err "Missing manifest for #{name} (tried '#{manifest_filename}')"
  end

  manifest = load_yaml_file(manifest_filename)

  unless manifest.is_a?(Hash)
    err 'Invalid manifest format'
  end

  if manifest['network'].blank?
    err 'network is not defined in deployment manifest'
  end
  ip = deployer(manifest_filename).client_services_ip

  if target
    old_director_ip = URI.parse(target).host
  else
    old_director_ip = nil
  end

  if old_director_ip != ip
    set_target(ip)
    say "#{'WARNING!'.make_red} Your target has been changed to '#{target.make_red}'!"
  end

  say "Deployment set to '#{manifest_filename.make_green}'"
  config.set_deployment(manifest_filename)
  config.save
end
show_current() click to toggle source

rubocop:enable MethodLength

# File lib/bosh/cli/commands/micro.rb, line 74
def show_current
  say(deployment ? "Current deployment is '#{deployment.make_green}'" : 'Deployment not set')
end
status() click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 80
def status
  stemcell_cid = deployer_state(:stemcell_cid)
  stemcell_name = deployer_state(:stemcell_name)
  vm_cid = deployer_state(:vm_cid)
  disk_cid = deployer_state(:disk_cid)
  deployment = config.deployment ? config.deployment.make_green : 'not set'.make_red

  say('Stemcell CID'.ljust(15) + stemcell_cid)
  say('Stemcell name'.ljust(15) + stemcell_name)
  say('VM CID'.ljust(15) + vm_cid)
  say('Disk CID'.ljust(15) + disk_cid)
  say('Micro BOSH CID'.ljust(15) + Bosh::Deployer::Config.uuid)
  say('Deployment'.ljust(15) + deployment)

  update_target

  target_name = target ? target.make_green : 'not set'.make_red
  say('Target'.ljust(15) + target_name)
end

Private Instance Methods

confirm_deployment(msg) click to toggle source

rubocop:enable MethodLength

# File lib/bosh/cli/commands/micro.rb, line 383
def confirm_deployment(msg)
  unless confirmed?(msg)
    cancel_deployment
  end
end
deployer(manifest_filename = nil) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 305
def deployer(manifest_filename = nil)
  deployment_required unless manifest_filename

  if @deployer.nil?
    manifest_filename ||= deployment

    unless File.exists?(manifest_filename)
      err("Cannot find deployment manifest in '#{manifest_filename}'")
    end

    manifest = load_yaml_file(manifest_filename)

    manifest['dir'] ||= work_dir
    manifest['logging'] ||= {}
    unless manifest['logging']['file']
      log_file = File.join(File.dirname(manifest_filename),
                           'bosh_micro_deploy.log')
      manifest['logging']['file'] = log_file
    end

    @deployer = Bosh::Deployer::InstanceManager.create(manifest)
  end

  @deployer
end
deployer_state(column) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 389
def deployer_state(column)
  value = deployer.state.send(column)

  if value
    value.make_green
  else
    'n/a'.make_red
  end
end
deployment_name() click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 341
def deployment_name
  File.basename(File.dirname(deployment))
end
dig_hash(hash, *path) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 403
def dig_hash(hash, *path)
  path.inject(hash) do |location, key|
    location.respond_to?(:keys) ? location[key] : nil
  end
end
find_deployment(name) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 331
def find_deployment(name)
  if File.directory?(name)
    filename = File.join("#{name}", MICRO_BOSH_YAML)
  else
    filename = name
  end

  File.expand_path(filename, Dir.pwd)
end
set_target(ip) click to toggle source

set new target and clear out cached values does not persist the new values (set_current() does this)

# File lib/bosh/cli/commands/micro.rb, line 347
def set_target(ip)
  config.target = "https://#{ip}:#{MICRO_DIRECTOR_PORT}"
  config.target_name = nil
  config.target_version = nil
  config.target_uuid = nil
end
strip_relative_path(path) click to toggle source
# File lib/bosh/cli/commands/micro.rb, line 399
def strip_relative_path(path)
  path[/#{Regexp.escape File.join(Dir.pwd, '')}(.*)/, 1] || path
end
update_target() click to toggle source

rubocop:disable MethodLength

# File lib/bosh/cli/commands/micro.rb, line 355
def update_target
  set_target(deployer.client_services_ip)

  if deployer.exists?
    if options[:director_checks]
      begin
        director = Bosh::Cli::Client::Director.new(target)
        status = director.get_status
      rescue Bosh::Cli::AuthError
        status = {}
      rescue Bosh::Cli::DirectorError
        err("Cannot talk to director at '#{target}', please set correct target")
      end
    else
      status = { 'name' => 'Unknown Director', 'version' => 'n/a' }
    end
  else
    status = {}
  end

  config.target_name = status['name']
  config.target_version = status['version']
  config.target_uuid = status['uuid']

  config.save
end