class Kondate::CLI

Public Class Methods

exit_on_failure?() click to toggle source

cf. qiita.com/KitaitiMakoto/items/c6b9d6311c20a3cc21f9

# File lib/kondate/cli.rb, line 17
def self.exit_on_failure?
  true
end
new(args = [], opts = [], config = {}) click to toggle source

default_command :itamae

Calls superclass method
# File lib/kondate/cli.rb, line 25
def initialize(args = [], opts = [], config = {})
  super
  Config.configure(@options)
end

Public Instance Methods

init(target_dir) click to toggle source
# File lib/kondate/cli.rb, line 31
def init(target_dir)
  Config.kondate_directories.each do |_, dir|
    $stdout.puts "mkdir -p #{File.join(target_dir, dir)}"
    FileUtils.mkdir_p(File.join(target_dir, dir)) unless @options[:dry_run]
  end

  templates_dir = File.join(Kondate::ROOT, 'lib', 'kondate', 'templates')
  templates_dir_length = templates_dir.length
  Find.find(templates_dir).select {|f| File.file?(f) }.each do |src|
    next if File.basename(src) == '.gitkeep'
    dst = File.join(target_dir, src[templates_dir_length+1 .. -1])
    dst_dir = File.dirname(dst)
    unless Dir.exist?(dst_dir)
      $stdout.puts "mkdir -p #{dst_dir}"
      FileUtils.mkdir_p(dst_dir) unless @options[:dry_run]
    end
    $stdout.puts "cp #{src} #{dst}"
    FileUtils.copy(src, dst) unless @options[:dry_run]
  end
end
itamae(host) click to toggle source
# File lib/kondate/cli.rb, line 62
def itamae(host)
  with_host(host) {|property_files| do_itamae(host, property_files) }
end
itamae_role(role) click to toggle source
# File lib/kondate/cli.rb, line 77
def itamae_role(role)
  with_role(role) {|host, property_files| do_itamae(host, property_files) }
end
serverspec(host) click to toggle source
# File lib/kondate/cli.rb, line 87
def serverspec(host)
  with_host(host) {|property_files| do_serverspec(host, property_files) }
end
serverspec_role(role) click to toggle source
# File lib/kondate/cli.rb, line 98
def serverspec_role(role)
  with_role(role) {|host, property_files| do_serverspec(host, property_files) }
end

Private Instance Methods

build_property_files(host) click to toggle source

@return [Hash] key value pairs whoses keys are roles and values are path (or nil)

# File lib/kondate/cli.rb, line 256
def build_property_files(host)
  builder = PropertyBuilder.new(host)
  roles = builder.filter_roles(@options[:role])

  property_files = {}
  roles.each do |role|
    property_files[role] = builder.install(role, @options[:recipe])
  end

  property_files
end
build_property_files_of_host(hosts) click to toggle source
# File lib/kondate/cli.rb, line 268
def build_property_files_of_host(hosts)
  summarized_property_files = {}
  property_files_of_host = {}
  hosts_of_role = {}
  hosts.each do |host|
    property_files = build_property_files(host)
    property_files_of_host[host] = property_files
    property_files.each {|role, property_file| summarized_property_files[role] ||= property_file }
    property_files.each {|role, property_file| (hosts_of_role[role] ||= []) << host }
  end
  [property_files_of_host, summarized_property_files, hosts_of_role]
end
clean_property_files(property_files) click to toggle source
# File lib/kondate/cli.rb, line 249
def clean_property_files(property_files)
  property_files.values.each do |file|
    File.unlink(file) rescue nil
  end
end
do_itamae(host, property_files) click to toggle source
# File lib/kondate/cli.rb, line 147
def do_itamae(host, property_files)
  env = {}
  env['RUBYOPT'] = "-I #{Config.plugin_dir} -r bundler/setup -r ext/itamae/kondate"
  property_files.each do |role, property_file|
    next if property_file.empty?
    command = "itamae ssh"
    command << " -h #{host}"

    properties = property_file.load

    if itamae_options[:vagrant]
      command << " --vagrant"
    else
      # itamae itself sees Net:SSH::Config.for(host)
      # here, we set ssh config if property file specially specifies
      config = Net::SSH::Config.for(host, Net::SSH::Config.default_files)
      # itamae fallbacks to Etc.getlogin, but we prefer to fallback to ENV['USER'], then Etc.getlogin
      command << " -u #{properties['ssh_user'] || config[:user] || ENV['USER'] || ENV['LOGNAME'] || Etc.getlogin || Etc.getpwuid.name}"
      command << " -i #{(Array(properties['ssh_keys']) || []).first}" if properties['ssh_keys']
      command << " -p #{properties['ssh_port']}" if properties['ssh_port']
    end

    command << " -y #{property_file.path}"
    command << " -l=debug" if itamae_options[:debug]
    command << " --dry-run" if itamae_options[:dry_run]
    command << " --profile=#{itamae_options[:profile]}" if itamae_options[:profile]
    command << " --recipe-graph=#{itamae_options[:recipe_graph]}" if itamae_options[:recipe_graph]
    command << " --shell=#{itamae_options[:shell]}" if itamae_options[:shell]
    command << " --login-shell" if itamae_options[:login_shell]
    command << " bootstrap.rb"
    $stdout.puts "env #{env.map {|k, v| "#{k}=#{v.shellescape}" }.join(' ')} #{command}"

    return false unless system(env, command)
  end
  true
end
do_serverspec(host, property_files) click to toggle source
# File lib/kondate/cli.rb, line 184
def do_serverspec(host, property_files)
  env = {}
  env['TARGET_VAGRANT'] = '1' if serverspec_options[:vagrant]
  env['RUBYOPT'] = "-I #{Config.plugin_dir} -r bundler/setup -r ext/serverspec/kondate"
  property_files.each do |role, property_file|
    next if property_file.empty?
    spec_files = property_file.load['attributes'].keys.map {|recipe|
      secret_spec_file = File.join(Config.secret_middleware_recipes_serverspec_dir, "#{recipe}_spec.rb")
      spec_file = File.join(Config.middleware_recipes_serverspec_dir, "#{recipe}_spec.rb")
      File.exist?(secret_spec_file) ? secret_spec_file : spec_file
    }.compact
    secret_role_spec_file = RoleFile.explore(Config.secret_roles_recipes_serverspec_dir, role, "_spec.rb")
    role_spec_file = RoleFile.explore(Config.roles_recipes_serverspec_dir, role, "_spec.rb")
    spec_files << (File.exist?(secret_role_spec_file) ? secret_role_spec_file : role_spec_file)
    spec_files.select! {|spec| File.exist?(spec) }

    env['TARGET_HOST'] = host
    env['TARGET_NODE_FILE'] = property_file.path
    command = "rspec #{spec_files.map{|f| f.shellescape }.join(' ')}"
    $stdout.puts "env #{env.map {|k, v| "#{k}=#{v.shellescape}" }.join(' ')} #{command}"

    return false unless system(env, command)
  end
  true
end
itamae_options() click to toggle source
# File lib/kondate/cli.rb, line 104
def itamae_options
  @itamae_options ||= Config.itamae_options.merge(@options)
end
print_property_files(property_files, hosts_of_role = {}) click to toggle source
proceed?(property_files) click to toggle source
# File lib/kondate/cli.rb, line 210
def proceed?(property_files)
  if property_files.values.compact.reject(&:empty?).empty?
    $stderr.puts "Nothing to run"
    false
  elsif @options[:confirm]
    prompt = ask "Proceed? (y/n):"
    prompt == 'y'
  else
    true
  end
end
serverspec_options() click to toggle source
# File lib/kondate/cli.rb, line 108
def serverspec_options
  @serverspec_options ||= Config.serverspec_options.merge(@options)
end
with_host(host) { |property_files| ... } click to toggle source
# File lib/kondate/cli.rb, line 112
def with_host(host, &block)
  property_files = build_property_files(host)
  begin
    print_property_files(property_files)
    if proceed?(property_files)
      exit(-1) unless yield(property_files)
    end
  ensure
    clean_property_files(property_files)
  end
end
with_role(role) { |host, property_files_of_host| ... } click to toggle source
# File lib/kondate/cli.rb, line 124
def with_role(role, &block)
  $stdout.puts "Number of parallels is #{@options[:parallel]}"
  hosts = Config.host_plugin.get_hosts(role)
  if hosts.nil? or hosts.empty?
    $stderr.puts 'No host'
    exit(1)
  end
  $stdout.puts "Target hosts are [#{hosts.join(", ")}]"

  property_files_of_host, summarized_property_files, hosts_of_role = build_property_files_of_host(hosts)
  begin
    print_property_files(summarized_property_files, hosts_of_role)
    if proceed?(summarized_property_files)
      successes = Parallel.map(hosts, in_processes: @options[:parallel]) do |host|
        yield(host, property_files_of_host[host])
      end
      exit(-1) unless successes.all?
    end
  ensure
    property_files_of_host.values.each {|property_files| clean_property_files(property_files) }
  end
end