lib/vagabond/vagabond.rb in vagabond-0.2.8 vs lib/vagabond/vagabond.rb in vagabond-0.2.10
- old
+ new
@@ -1,9 +1,10 @@
+#encoding: utf-8
require 'thor'
require 'chef/knife/core/ui'
require 'vagabond/uploader'
-require File.join(File.dirname(__FILE__), 'cookbooks/lxc/libraries/lxc.rb')
+require 'elecksee/lxc'
%w(constants errors vagabondfile internal_configuration helpers).each do |dep|
require "vagabond/#{dep}"
end
@@ -15,65 +16,66 @@
require "vagabond/actions/#{File.basename(action).sub('.rb', '')}"
end
module Vagabond
class Vagabond < Thor
+
+ DISABLE_HOST_SOLO_ON = %w(status init)
include Thor::Actions
include Helpers
Actions.constants.each do |const|
klass = Actions.const_get(const)
include klass if klass.is_a?(Module)
end
- attr_reader :name
- attr_reader :vagabondfile
- attr_reader :internal_config
- attr_reader :ui
- attr_reader :options
-
attr_accessor :mappings_key
attr_accessor :lxc
attr_accessor :config
attr_accessor :action
CLI_OPTIONS = lambda do
- class_option(:debug,
- :type => :boolean,
- :default => false
- )
+ class_option(:debug,
+ :type => :boolean,
+ :default => false
+ )
- class_option(:force_solo,
- :aliases => '--force-configure',
- :type => :boolean,
- :default => false,
- :desc => 'Force configuration of system'
- )
+ class_option(:force_solo,
+ :aliases => '--force-configure',
+ :type => :boolean,
+ :default => false,
+ :desc => 'Force configuration of system'
+ )
- class_option(:color,
- :type => :boolean,
- :default => true,
- :desc => 'Enable/disable colorized output'
- )
+ class_option(:color,
+ :type => :boolean,
+ :default => true,
+ :desc => 'Enable/disable colorized output'
+ )
- class_option(:vagabond_file,
- :aliases => '-f',
- :type => :string,
- :desc => 'Provide path to Vagabondfile'
- )
-
- class_option(:local_server,
- :type => :boolean,
- :default => true,
- :desc => 'Enable/disable local Chef server usage if available'
- )
+ class_option(:vagabond_file,
+ :aliases => '-f',
+ :type => :string,
+ :desc => 'Provide path to Vagabondfile'
+ )
+
+ class_option(:local_server,
+ :type => :boolean,
+ :default => true,
+ :desc => 'Enable/disable local Chef server usage if available'
+ )
+
+ class_option(:callbacks,
+ :type => :boolean,
+ :default => true,
+ :desc => 'Enable/disable action callbacks'
+ )
end
CLI_OPTIONS.call
-
# action:: Action to perform
# name:: Name of vagabond
# config:: Hash configuration
#
# Creates an instance
@@ -99,47 +101,60 @@
self.send("_#{meth}_options").each do |opts|
method_option(*opts)
end
end
define_method meth do |*args|
- setup(meth, *args)
- execute
+ @original_args = args.dup
+ unless(args.include?(:no_setup))
+ setup(meth, *args)
+ end
+ result = execute
+ callbacks(meth)
+ chain!
+ result
end
end
end
COMMANDS.call
protected
+ def attributes
+ if(config[:attributes])
+ if(config[:attributes].is_a?(Hash))
+ JSON.dump(config[:attributes])
+ else
+ config[:attributes].to_s
+ end
+ end
+ end
+
def version
setup_ui
ui.info "#{ui.color('Vagabond:', :yellow, :bold)} - Advocating idleness and work-shyness"
ui.info " #{ui.color('Version:', :blue)} - #{VERSION.version} (#{VERSION.codename})"
exit
end
def execute
- self.send("_#{@action}")
+ self.send("_#{action}")
end
def setup(action, name=nil, *args)
@action = action
@name = name
- @options = options.dup
- if(args.last.is_a?(Hash))
- _ui = args.last.delete(:ui)
- @options.merge!(args.last)
- end
- @leftover_args = args
- setup_ui(_ui)
- load_configurations
- if(respond_to?(check = "#{action}_validate?".to_sym))
- validate! if send(check)
+ hash_args = args.detect{|x|x.is_a?(Hash)}
+ if(hash_args)
+ args.delete(hash_args)
+ _ui = hash_args.delete(:ui)
+ base_setup(_ui)
+ config.merge!(hash_args)
else
- validate!
+ base_setup
end
+ @leftover_args = args
end
def name_required!
unless(name)
ui.fatal "Node name is required!"
@@ -148,60 +163,32 @@
end
def provision_solo(dir)
ui.info "#{ui.color('Vagabond:', :bold)} Provisioning node: #{ui.color(name, :magenta)}"
lxc.container_ip(20) # force wait for container to appear and do so quietly
- direct_container_command(
+ cmd = direct_container_command(
"chef-solo -c #{File.join(dir, 'solo.rb')} -j #{File.join(dir, 'dna.json')}",
:live_stream => STDOUT
)
+ raise VagabondError::NodeProvisionFailed.new("Failed to provision: #{name}") unless cmd
end
- def load_configurations
- @vagabondfile = Vagabondfile.new(options[:vagabond_file], :allow_missing)
- options[:sudo] = sudo
- # TODO: provide action call back for full or partial solo disable
- if((@action.to_s == 'status' && lxc_installed?) || @action.to_s == 'init')
- options[:disable_solo] = true
- end
- Chef::Log.init('/dev/null') unless options[:debug]
- Lxc.use_sudo = @vagabondfile[:sudo].nil? ? true : @vagabondfile[:sudo]
- @internal_config = InternalConfiguration.new(@vagabondfile, ui, options)
- options[:disable_solo] = false if @action.to_s == 'init'
- @config = @vagabondfile[:boxes][name]
- @lxc = Lxc.new(@internal_config[mappings_key][name] || '____nonreal____')
- if(options[:local_server] && lxc_installed?)
- if(@vagabondfile[:local_chef_server] && @vagabondfile[:local_chef_server][:enabled])
- srv_name = @internal_config[:mappings][:server]
- srv = Lxc.new(srv_name) if srv_name
- if(srv_name && srv.running?)
- proto = @vagabondfile[:local_chef_server][:zero] ? 'http' : 'https'
- options[:knife_opts] = " --server-url #{proto}://#{srv.container_ip(10, true)}"
- else
- unless(@action.to_sym == :status || name.to_s =='server')
- ui.warn 'Local chef server is not currently running!' unless @action.to_sym == :status
- end
- end
- end
- end
- end
-
def validate!
if(name.to_s == 'server')
ui.fatal "RESERVED node name supplied: #{ui.color(name, :red)}"
- ui.info ui.color(" -> Try: vagabond server #{@action}", :cyan)
+ ui.info ui.color(" -> Try: vagabond server #{action}", :cyan)
raise VagabondError::ReservedName.new(name)
end
if(name && config.nil? && !options[:disable_name_validate])
ui.fatal "Invalid node name supplied: #{ui.color(name, :red)}"
ui.info ui.color(" -> Available: #{vagabondfile[:nodes].keys.sort.join(', ')}", :cyan)
raise VagabondError::InvalidName.new(name)
end
end
def check_existing!
- if(@lxc.exists?)
+ if(lxc.exists?)
ui.error "LXC: #{name} already exists!"
true
end
end
@@ -211,22 +198,19 @@
def vagabond_dir
File.join(base_dir, '.vagabond')
end
- def lxc_installed?
- system('which lxc-info > /dev/null')
- end
-
def wait_for_completion(type=nil)
+ @threads ||= []
if(type)
- Array(@threads[:type]).map(&:join)
+ Array(@threads[type]).collect{|hsh| hsh[:thread]}.map(&:join)
else
- @threads.values.map do |threads|
- threads.each do |thread_set|
- Array(thread_set).map(&:join)
- end
- end
+ @threads.values.flatten.collect{|hsh| hsh[:thread]}.map(&:join)
end
+ end
+
+ def tasks(type=nil)
+ type ? @threads[type] : @threads
end
end
end