vagabond 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. data/CHANGELOG.md +2 -0
  2. data/README.md +94 -0
  3. data/bin/vagabond +6 -0
  4. data/lib/vagabond.rb +1 -0
  5. data/lib/vagabond/actions/create.rb +29 -0
  6. data/lib/vagabond/actions/destroy.rb +31 -0
  7. data/lib/vagabond/actions/freeze.rb +14 -0
  8. data/lib/vagabond/actions/provision.rb +31 -0
  9. data/lib/vagabond/actions/ssh.rb +13 -0
  10. data/lib/vagabond/actions/status.rb +29 -0
  11. data/lib/vagabond/actions/thaw.rb +14 -0
  12. data/lib/vagabond/actions/up.rb +27 -0
  13. data/lib/vagabond/bootstraps/server.erb +62 -0
  14. data/lib/vagabond/commands.rb +58 -0
  15. data/lib/vagabond/config.rb +7 -0
  16. data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +21 -0
  17. data/lib/vagabond/cookbooks/lxc/Gemfile +3 -0
  18. data/lib/vagabond/cookbooks/lxc/Gemfile.lock +132 -0
  19. data/lib/vagabond/cookbooks/lxc/README.md +83 -0
  20. data/lib/vagabond/cookbooks/lxc/attributes/default.rb +26 -0
  21. data/lib/vagabond/cookbooks/lxc/files/default/knife_lxc +228 -0
  22. data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +279 -0
  23. data/lib/vagabond/cookbooks/lxc/libraries/lxc_expanded_resources.rb +40 -0
  24. data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +81 -0
  25. data/lib/vagabond/cookbooks/lxc/metadata.rb +11 -0
  26. data/lib/vagabond/cookbooks/lxc/providers/config.rb +82 -0
  27. data/lib/vagabond/cookbooks/lxc/providers/container.rb +342 -0
  28. data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +71 -0
  29. data/lib/vagabond/cookbooks/lxc/providers/interface.rb +99 -0
  30. data/lib/vagabond/cookbooks/lxc/providers/service.rb +53 -0
  31. data/lib/vagabond/cookbooks/lxc/recipes/containers.rb +13 -0
  32. data/lib/vagabond/cookbooks/lxc/recipes/default.rb +45 -0
  33. data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +15 -0
  34. data/lib/vagabond/cookbooks/lxc/recipes/knife.rb +37 -0
  35. data/lib/vagabond/cookbooks/lxc/resources/#container.rb# +28 -0
  36. data/lib/vagabond/cookbooks/lxc/resources/config.rb +19 -0
  37. data/lib/vagabond/cookbooks/lxc/resources/container.rb +28 -0
  38. data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +11 -0
  39. data/lib/vagabond/cookbooks/lxc/resources/interface.rb +10 -0
  40. data/lib/vagabond/cookbooks/lxc/resources/service.rb +5 -0
  41. data/lib/vagabond/cookbooks/lxc/templates/default/client.rb.erb +13 -0
  42. data/lib/vagabond/cookbooks/lxc/templates/default/default-lxc.erb +3 -0
  43. data/lib/vagabond/cookbooks/lxc/templates/default/fstab.erb +5 -0
  44. data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +21 -0
  45. data/lib/vagabond/cookbooks/lxc/test/kitchen/Kitchenfile +7 -0
  46. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/metadata.rb +2 -0
  47. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/centos_lxc.rb +0 -0
  48. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/chef-bootstrap.rb +0 -0
  49. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_files.rb +0 -0
  50. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_templates.rb +0 -0
  51. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/ubuntu_lxc.rb +0 -0
  52. data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +2 -0
  53. data/lib/vagabond/cookbooks/vagabond/libraries/vagabond.rb +10 -0
  54. data/lib/vagabond/cookbooks/vagabond/metadata.rb +6 -0
  55. data/lib/vagabond/cookbooks/vagabond/recipes/create.rb +3 -0
  56. data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +30 -0
  57. data/lib/vagabond/internal_configuration.rb +147 -0
  58. data/lib/vagabond/server.rb +158 -0
  59. data/lib/vagabond/vagabond.rb +109 -0
  60. data/lib/vagabond/vagabondfile.rb +34 -0
  61. data/lib/vagabond/version.rb +10 -0
  62. data/vagabond.gemspec +18 -0
  63. metadata +125 -0
@@ -0,0 +1,53 @@
1
+ def load_current_resource
2
+ new_resource._lxc Lxc.new(
3
+ new_resource.name,
4
+ :base_dir => node[:lxc][:container_directory],
5
+ :dnsmasq_lease_file => node[:lxc][:dnsmasq_lease_file]
6
+ )
7
+ if(new_resource.service_name.to_s.empty?)
8
+ new_resource.service_name new_resource.name
9
+ end
10
+ end
11
+
12
+ action :start do
13
+ if(new_resource._lxc.stopped?)
14
+ new_resource._lxc.start
15
+ new_resource.updated_by_last_action(true)
16
+ end
17
+ end
18
+
19
+ action :halt do
20
+ if(new_resource._lxc.running?)
21
+ new_resource._lxc.stop
22
+ new_resource.updated_by_last_action(true)
23
+ end
24
+ end
25
+
26
+ action :restart do
27
+ if(new_resource._lxc.running?)
28
+ new_resource._lxc.shutdown
29
+ end
30
+ new_resource._lxc.start
31
+ new_resource.updated_by_last_action(true)
32
+ end
33
+
34
+ action :stop do
35
+ if(new_resource._lxc.running?)
36
+ new_resource._lxc.stop
37
+ new_resource.updated_by_last_action(true)
38
+ end
39
+ end
40
+
41
+ action :freeze do
42
+ if(new_resource._lxc.running?)
43
+ new_resource._lxc.freeze
44
+ new_resource.updated_by_last_action(true)
45
+ end
46
+ end
47
+
48
+ action :unfreeze do
49
+ if(new_resource._lxc.frozen?)
50
+ new_resource._lxc.unfreeze
51
+ new_resource.updated_by_last_action(true)
52
+ end
53
+ end
@@ -0,0 +1,13 @@
1
+ # create the containers defined in the ['lxc']['containers'] hash
2
+
3
+ include_recipe "lxc"
4
+
5
+ node['lxc']['containers'].each do | name, container |
6
+ Chef::Log.info "Creating LXC container name:#{name}"
7
+ lxc_container name do
8
+ container.each do |meth, param|
9
+ self.send(meth, param)
10
+ end
11
+ action :create unless container.has_key?(:action)
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ # install the server dependencies to run lxc
2
+ node[:lxc][:packages].each do |lxcpkg|
3
+ package lxcpkg
4
+ end
5
+
6
+ include_recipe 'lxc::install_dependencies'
7
+
8
+ #if the server uses the apt::cacher-client recipe, re-use it
9
+ unless Chef::Config[:solo]
10
+ if File.exists?('/etc/apt/apt.conf.d/01proxy')
11
+ query = 'recipes:apt\:\:cacher-ng'
12
+ query += " AND chef_environment:#{node.chef_environment}" if node['apt']['cacher-client']['restrict_environment']
13
+ Chef::Log.debug("apt::cacher-client searching for '#{query}'")
14
+ servers = search(:node, query)
15
+ if servers.length > 0
16
+ Chef::Log.info("apt-cacher-ng server found on #{servers[0]}.")
17
+ node.default[:lxc][:mirror] = "http://#{servers[0]['ipaddress']}:3142/archive.ubuntu.com/ubuntu"
18
+ end
19
+ end
20
+ end
21
+
22
+ template '/etc/default/lxc' do
23
+ source 'default-lxc.erb'
24
+ mode 0644
25
+ variables(
26
+ :config => {
27
+ :lxc_auto => node[:lxc][:auto_start],
28
+ :use_lxc_bridge => node[:lxc][:use_bridge],
29
+ :lxc_bridge => node[:lxc][:bridge],
30
+ :lxc_addr => node[:lxc][:addr],
31
+ :lxc_netmask => node[:lxc][:netmask],
32
+ :lxc_network => node[:lxc][:network],
33
+ :lxc_dhcp_range => node[:lxc][:dhcp_range],
34
+ :lxc_dhcp_max => node[:lxc][:dhcp_max],
35
+ :lxc_shutdown_timeout => node[:lxc][:shutdown_timeout],
36
+ :mirror => node[:lxc][:mirror]
37
+ }
38
+ )
39
+ end
40
+
41
+ #this just reloads the dnsmasq rules when
42
+ service "lxc-net" do
43
+ action :enable
44
+ subscribes :restart, resources("template[/etc/default/lxc]")
45
+ end
@@ -0,0 +1,15 @@
1
+ # Fedora allowed? Needs yum and curl to download packages
2
+ if node[:lxc][:allowed_types].include?('fedora')
3
+ ['yum', 'curl'].each do |pkg|
4
+ package pkg
5
+ end
6
+ end
7
+
8
+ # OpenSuse allowed? Needs zypper (no package available yet!)
9
+ # package 'zypper' if node[:lxc][:allowed_types].include?('opensuse')
10
+ raise 'OpenSuse not currently supported' if node[:lxc][:allowed_types].include?('opensuse')
11
+
12
+ #store a copy of the Omnibus installer for use by the lxc containers
13
+ if(node[:omnibus_updater] && node[:omnibus_updater][:cache_omnibus_installer])
14
+ include_recipe 'omnibus_updater::deb_downloader'
15
+ end
@@ -0,0 +1,37 @@
1
+ include_recipe 'lxc'
2
+
3
+ # This shuts down the default lxcbr0
4
+ node[:lxc][:use_bridge] = false
5
+ service 'lxc' do
6
+ action :stop
7
+ end
8
+
9
+ directory '/etc/knife-lxc' do
10
+ action :create
11
+ mode 0755
12
+ end
13
+
14
+ file '/etc/knife-lxc/config.json' do
15
+ mode 0644
16
+ content(
17
+ JSON.pretty_generate(
18
+ :addresses => {
19
+ :static => node[:lxc][:knife][:static_ips],
20
+ :range => node[:lxc][:knife][:static_range]
21
+ }
22
+ )
23
+ )
24
+ end
25
+
26
+ cookbook_file '/usr/local/bin/knife_lxc' do
27
+ source 'knife_lxc'
28
+ mode 0755
29
+ end
30
+
31
+ node[:lxc][:allowed_types].each do |type|
32
+ lxc_container "#{type}_base" do
33
+ template type
34
+ chef_enabled false
35
+ action :create
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ actions :create, :delete, :clone
2
+ default_action :create
3
+
4
+ attribute :base_container, :kind_of => String
5
+ attribute :validation_client, :kind_of => String
6
+ attribute :validator_pem, :kind_of => String, :default => nil
7
+ attribute :server_uri, :kind_of => String
8
+ attribute :chef_environment, :kind_of => String, :default => '_default'
9
+ attribute :node_name, :kind_of => String
10
+ attribute :run_list, :kind_of => Array
11
+ attribute :chef_enabled, :kind_of => [TrueClass, FalseClass], :default => false
12
+ attribute :chef_retries, :kind_of => Fixnum, :default => 0
13
+ attribute :copy_data_bag_secret_file, :kind_of => [TrueClass, FalseClass], :default => false
14
+ attribute :data_bag_secret_file, :kind_of => String, :default => Chef::EncryptedDataBagItem::DEFAULT_SECRET_FILE
15
+ attribute :default_bridge, :kind_of => String
16
+ attribute :static_ip, :kind_of => String
17
+ attribute :static_netmask, :kind_of => String, :default => '255.255.255.0'
18
+ attribute :static_gateway, :kind_of => String
19
+ attribute :default_config, :kind_of => [TrueClass, FalseClass], :default => true
20
+ attribute :default_fstab, :kind_of => [TrueClass, FalseClass], :default => true
21
+ attribute :container_commands, :kind_of => Array, :default => []
22
+ attribute :initialize_commands, :kind_of => Array, :default => []
23
+ attribute :new_container, :kind_of => [TrueClass, FalseClass], :default => false
24
+ attribute :template, :kind_of => String, :default => 'ubuntu'
25
+ attribute :template_opts, :kind_of => Hash, :default => {}
26
+ attribute :_lxc
27
+ # TODO: We should ultimately have support for all these templates
28
+ #attribute :template, :equal_to => %w(busybox debian fedora opensuse sshd ubuntu ubuntu-cloud), :default => 'ubuntu'
@@ -0,0 +1,19 @@
1
+ actions :create, :delete
2
+ default_action :create
3
+
4
+ attribute :utsname, :kind_of => String, :default => nil # defaults to resource name
5
+ attribute :network, :kind_of => [Array, Hash]
6
+ attribute :default_bridge, :kind_of => String
7
+ attribute :static_ip, :kind_of => String
8
+ attribute :pts, :kind_of => Numeric, :default => 1024
9
+ attribute :tty, :kind_of => Numeric, :default => 4
10
+ attribute :arch, :kind_of => String, :default => 'amd64'
11
+ attribute :devttydir, :kind_of => String, :default => 'lxc'
12
+ attribute :cgroup, :kind_of => Hash, :default => Mash.new
13
+ attribute :cap_drop, :kind_of => [String, Array], :default => %w(sys_module mac_admin)
14
+ attribute :mount, :kind_of => String
15
+ attribute :mount_entry, :kind_of => String
16
+ attribute :rootfs, :kind_of => String
17
+ attribute :rootfs_mount, :kind_of => String
18
+ attribute :pivotdir, :kind_of => String
19
+ attribute :_lxc
@@ -0,0 +1,28 @@
1
+ actions :create, :delete, :clone
2
+ default_action :create
3
+
4
+ attribute :base_container, :kind_of => String
5
+ attribute :validation_client, :kind_of => String
6
+ attribute :validator_pem, :kind_of => String, :default => nil
7
+ attribute :server_uri, :kind_of => String
8
+ attribute :chef_environment, :kind_of => String, :default => '_default'
9
+ attribute :node_name, :kind_of => String
10
+ attribute :run_list, :kind_of => Array
11
+ attribute :chef_enabled, :kind_of => [TrueClass, FalseClass], :default => false
12
+ attribute :chef_retries, :kind_of => Fixnum, :default => 0
13
+ attribute :copy_data_bag_secret_file, :kind_of => [TrueClass, FalseClass], :default => false
14
+ attribute :data_bag_secret_file, :kind_of => String, :default => Chef::EncryptedDataBagItem::DEFAULT_SECRET_FILE
15
+ attribute :default_bridge, :kind_of => String
16
+ attribute :static_ip, :kind_of => String
17
+ attribute :static_netmask, :kind_of => String, :default => '255.255.255.0'
18
+ attribute :static_gateway, :kind_of => String
19
+ attribute :default_config, :kind_of => [TrueClass, FalseClass], :default => true
20
+ attribute :default_fstab, :kind_of => [TrueClass, FalseClass], :default => true
21
+ attribute :container_commands, :kind_of => Array, :default => []
22
+ attribute :initialize_commands, :kind_of => Array, :default => []
23
+ attribute :new_container, :kind_of => [TrueClass, FalseClass], :default => false
24
+ attribute :template, :kind_of => String, :default => 'ubuntu'
25
+ attribute :template_opts, :kind_of => Hash, :default => {}
26
+ attribute :_lxc
27
+ # TODO: We should ultimately have support for all these templates
28
+ #attribute :template, :equal_to => %w(busybox debian fedora opensuse sshd ubuntu ubuntu-cloud), :default => 'ubuntu'
@@ -0,0 +1,11 @@
1
+ actions :create, :delete
2
+ default_action :create
3
+
4
+ attribute :container, :kind_of => String, :required => true
5
+ attribute :file_system, :kind_of => String, :required => true
6
+ attribute :mount_point, :kind_of => String, :required => true
7
+ attribute :type, :kind_of => String, :required => true
8
+ attribute :options, :kind_of => [String, Array]
9
+ attribute :dump, :kind_of => Numeric, :default => 0
10
+ attribute :pass, :kind_of => Numeric, :default => 0
11
+ attribute :_lxc
@@ -0,0 +1,10 @@
1
+ actions :create, :delete
2
+ default_action :create
3
+
4
+ attribute :container, :kind_of => String, :required => true
5
+ attribute :device, :kind_of => String, :required => true
6
+ attribute :auto, :kind_of => [TrueClass, FalseClass], :default => true
7
+ attribute :dynamic, :kind_of => [TrueClass, FalseClass], :default => false
8
+ attribute :address, :regex => %r{\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}}
9
+ attribute :gateway, :regex => %r{\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}}
10
+ attribute :netmask, :regex => %r{\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}}, :default => '255.255.255.0'
@@ -0,0 +1,5 @@
1
+ actions :start, :stop, :halt, :restart, :freeze, :unfreeze
2
+ default_action :start
3
+
4
+ attribute :service_name, :kind_of => String
5
+ attribute :_lxc
@@ -0,0 +1,13 @@
1
+ log_level :info
2
+ log_location "/var/log/chef-client.log"
3
+
4
+ chef_server_url '<%= @server_uri %>'
5
+ validation_client_name '<%= @validation_client %>'
6
+ node_name '<%= @node_name %>'
7
+ environment '<%= @chef_environment %>'
8
+
9
+ file_backup_path "/var/lib/chef"
10
+ file_cache_path "/var/cache/chef"
11
+
12
+ pid_file "/var/run/chef/client.pid"
13
+
@@ -0,0 +1,3 @@
1
+ <% @config.each_pair do |key, val| %>
2
+ <%= key.to_s.upcase %>=<%= val.inspect %>
3
+ <% end %>
@@ -0,0 +1,5 @@
1
+ # Chef generated fstab!
2
+ <% node.run_state[:lxc][:fstabs][@container].each do |line| -%>
3
+ <%= line %>
4
+ <% end -%>
5
+
@@ -0,0 +1,21 @@
1
+ # Auto config dropped off by chef!
2
+
3
+ # Always setup loopback
4
+ auto lo
5
+ iface lo inet loopback
6
+
7
+ <% node[:lxc][:interfaces][@container].each do |net_set| -%>
8
+ <% if net_set[:auto] -%>
9
+ auto <%= net_set[:device] %>
10
+ <% end -%>
11
+ <% if net_set[:dynamic] -%>
12
+ iface <%= net_set[:device] %> inet dhcp
13
+ <% else -%>
14
+ iface <%= net_set[:device] %> inet static
15
+ address <%= net_set[:address] %>
16
+ <% if net_set[:gateway] -%>
17
+ gateway <%= net_set[:gateway] %>
18
+ <% end -%>
19
+ netmask <%= net_set[:netmask] %>
20
+ <% end -%>
21
+ <% end %>
@@ -0,0 +1,7 @@
1
+ cookbook "lxc" do
2
+ configuration "ubuntu_lxc"
3
+ configuration "centos_lxc"
4
+ configuration "lxc_templates"
5
+ configuration "lxc_files"
6
+ configuration "chef-bootstrap"
7
+ end
@@ -0,0 +1,2 @@
1
+ name 'lxc_test'
2
+ version '0.1.0'
@@ -0,0 +1,2 @@
1
+ default[:vagabond][:bases][:ubuntu_1204][:template_options] = {'--release' => 'precise'}
2
+ default[:vagabond][:bases][:ubuntu_1210][:template_options] = {'--release' => 'quantal'}
@@ -0,0 +1,10 @@
1
+ module Vagabond
2
+ class << self
3
+ def get_bytes(s)
4
+ s = s.to_s
5
+ indx = [nil, 'k', 'm', 'g']
6
+ power = indx.index(s.slice(-1, s.length).to_s.downcase).to_i * 10
7
+ (2**power) * s.to_i
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ name 'vagabond'
2
+ version '1.0.0'
3
+ maintainer 'Chris Roberts'
4
+ maintainer_email 'chrisroberts.code@gmail.com'
5
+
6
+ depends 'lxc'
@@ -0,0 +1,3 @@
1
+
2
+ node[:vagabond][:containers].each do |name, options|
3
+ end
@@ -0,0 +1,30 @@
1
+
2
+ node[:vagabond][:bases].each do |name, options|
3
+
4
+ lxc_container name do
5
+ template options[:template]
6
+ template_opts options[:template_options]
7
+ default_config false if options[:memory]
8
+ initialize_commands [
9
+ 'rm -f /etc/sysctl.d/10-console-messages.conf',
10
+ 'rm -f /etc/sysctl.d/10-ptrace.conf',
11
+ 'rm -f /etc/sysctl.d/10-kernel-hardening.conf',
12
+ 'apt-get install -q -y curl',
13
+ 'curl -L https://www.opscode.com/chef/install.sh | sudo bash'
14
+ ]
15
+ end
16
+
17
+ if(options[:memory])
18
+ lxc_config name do
19
+ cgroup(
20
+ 'memory.limit_in_bytes' => options[:memory][:maximum_ram],
21
+ 'memory.memsw.limit_in_bytes' => (
22
+ Vagabond.get_bytes(options[:memory][:maximum_ram]) +
23
+ Vagabond.get_bytes(options[:memory][:maximum_swap])
24
+ )
25
+ )
26
+ end
27
+ end
28
+ end
29
+
30
+
@@ -0,0 +1,147 @@
1
+ require 'digest/sha2'
2
+
3
+ module Vagabond
4
+ class InternalConfiguration
5
+
6
+ attr_reader :config
7
+ attr_reader :ui
8
+
9
+ def initialize(v_config, ui)
10
+ @v_config = v_config
11
+ @config = Mash.new(:mappings => Mash.new)
12
+ @checksums = Mash.new
13
+ @ui = ui
14
+ create_store
15
+ load_existing
16
+ store_checksums
17
+ write_dna_json
18
+ write_solo_rb
19
+ run_solo if solo_needed?
20
+ end
21
+
22
+ def [](k)
23
+ @config[k]
24
+ end
25
+
26
+ def []=(k,v)
27
+ @config[k] = v
28
+ end
29
+
30
+ def create_store
31
+ FileUtils.mkdir_p(store_path)
32
+ end
33
+
34
+ def load_existing
35
+ if(File.exists?(path = File.join(store_path, 'vagabond.json')))
36
+ @config = Mash.new(
37
+ JSON.load(
38
+ File.read(path)
39
+ )
40
+ )
41
+ end
42
+ end
43
+
44
+ def store_path
45
+ FileUtils.mkdir_p(
46
+ File.join(
47
+ File.dirname(@v_config.path), '.vagabond'
48
+ )
49
+ )
50
+ end
51
+
52
+ def dna_path
53
+ File.join(store_path, 'dna.json')
54
+ end
55
+
56
+ def solo_path
57
+ File.join(store_path, 'solo.rb')
58
+ end
59
+
60
+ def write_dna_json
61
+ templates = @v_config.config[:boxes].map(&:last).map{|i| i[:template]}.compact.uniq
62
+ templates = Hash[*(
63
+ templates.map do |t|
64
+ if(@v_config.config[:templates] && @v_config[:templates][t])
65
+ [t, @v_config.config[:templates][t]]
66
+ else
67
+ [t, nil]
68
+ end
69
+ end
70
+ ).flatten]
71
+ File.open(dna_path, 'w') do |file|
72
+ file.write(
73
+ JSON.dump(
74
+ :vagabond => {
75
+ :bases => templates
76
+ },
77
+ :run_list => %w(recipe[vagabond])
78
+ )
79
+ )
80
+ end
81
+ end
82
+
83
+ def write_solo_rb
84
+ File.open(solo_path, 'w') do |file|
85
+ file.write("\nfile_cache_path \"#{cache_path}\"\ncookbook_path \"#{cookbook_path}\"\n")
86
+ end
87
+ end
88
+
89
+ def store_checksums
90
+ [dna_path, solo_path].each do |path|
91
+ @checksums[path] = get_checksum(path)
92
+ end
93
+ end
94
+
95
+ def get_checksum(path)
96
+ if(File.exists?(path))
97
+ s = Digest::SHA256.new
98
+ s << File.read(path)
99
+ s.hexdigest
100
+ else
101
+ ''
102
+ end
103
+ end
104
+
105
+ def solo_needed?
106
+ if(Config[:force_solo])
107
+ true
108
+ elsif(Config[:disable_solo])
109
+ false
110
+ else
111
+ [dna_path, solo_path].detect do |path|
112
+ @checksums[path] != get_checksum(path)
113
+ end
114
+ end
115
+ end
116
+
117
+ def cache_path
118
+ unless(@cache_path)
119
+ FileUtils.mkdir_p(@cache_path = File.join(store_path, 'chef_cache'))
120
+ end
121
+ @cache_path
122
+ end
123
+
124
+ def cookbook_path
125
+ File.expand_path(
126
+ File.join(
127
+ File.dirname(__FILE__), 'cookbooks'
128
+ )
129
+ )
130
+ end
131
+
132
+ def run_solo
133
+ ui.info 'Ensuring expected system state...'
134
+ com = "#{Config[:sudo]}chef-solo -j #{File.join(store_path, 'dna.json')} -c #{File.join(store_path, 'solo.rb')}"
135
+ cmd = Mixlib::ShellOut.new(com, :timeout => 1200)
136
+ cmd.run_command
137
+ cmd.error!
138
+ end
139
+
140
+ def save
141
+ File.open(File.join(store_path, 'vagabond.json'), 'w') do |file|
142
+ file.write(JSON.dump(@config))
143
+ end
144
+ end
145
+
146
+ end
147
+ end