module CORL module Action class Spawn < Plugin::CloudAction include Mixin::Action::Keypair #---------------------------------------------------------------------------- # Settings def configure super do codes :key_failure, :node_create_failure register :bootstrap, :bool, true register :seed, :bool, true register :provision, :bool, true register :groups, :array, [] register :region, :str, nil register :machine_type, :str, nil register :image, :str, nil register :user, :str, nil register :hostnames, :array, nil keypair_config config.defaults(CORL.action_config(:bootstrap)) config.defaults(CORL.action_config(:seed)) end end #--- def ignore node_ignore - [ :parallel, :node_provider ] + [ :bootstrap_nodes ] end def arguments [ :node_provider, :image, :hostnames ] end #----------------------------------------------------------------------------- # Operations def execute super do |node, network| ensure_network(network) do if keypair && keypair_clean hostnames = [] results = [] node_provider = settings.delete(:node_provider) if CORL.vagrant? && ! CORL.loaded_plugins(:node).keys.include?(node_provider.to_sym) settings[:machine_type] = node_provider settings[:user] = :vagrant unless settings[:user] node_provider = :vagrant end unless settings[:user] settings[:user] = :root end info('corl.actions.spawn.start', { :node_provider => node_provider }) settings.delete(:hostnames).each do |hostname| hostnames << extract_hostnames(hostname) end hostnames.flatten.each do |hostname| if hostname.is_a?(Hash) settings[:public_ip] = hostname[:ip] hostname = hostname[:hostname] end if settings[:parallel] results << network.future.add_node(node_provider, hostname, settings) else results << network.add_node(node_provider, hostname, settings) end end results = results.map { |future| future.value } if settings[:parallel] myself.status = code.batch_error if results.include?(false) else myself.status = code.key_failure end end end end #----------------------------------------------------------------------------- # Utilities def extract_hostnames(hostname) hostnames = [] if hostname.match(/([^\[]+)\[([^\]]+)\](.*)/) before = $1 extra = $2.strip after = $3 if extra.match(/\-/) low, high = extra.split(/\s*\-\s*/) range = Range.new(low, high) range.each do |item| hostnames << "#{before}#{item}#{after}" end elsif extra.match(/\d+\.\d+\.\d+\.\d+/) hostnames = [ { :hostname => "#{before}#{after}", :ip => extra } ] end else hostnames = [ hostname ] end hostnames end protected :extract_hostnames end end end