vagabond 0.2.8 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/CHANGELOG.md +16 -0
  2. data/DEVELOP.md +38 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +33 -0
  5. data/README.md +55 -21
  6. data/USAGE.md +28 -3
  7. data/Vagabondfile.sample +47 -0
  8. data/Vagrantfile +17 -5
  9. data/bin/vagabond +5 -0
  10. data/lib/vagabond/Cheffile +7 -0
  11. data/lib/vagabond/Cheffile.dev +7 -0
  12. data/lib/vagabond/actions/cluster.rb +22 -8
  13. data/lib/vagabond/actions/create.rb +7 -4
  14. data/lib/vagabond/actions/destroy.rb +24 -14
  15. data/lib/vagabond/actions/freeze.rb +1 -0
  16. data/lib/vagabond/actions/init.rb +8 -11
  17. data/lib/vagabond/actions/provision.rb +16 -8
  18. data/lib/vagabond/actions/rebuild.rb +4 -9
  19. data/lib/vagabond/actions/ssh.rb +9 -1
  20. data/lib/vagabond/actions/start.rb +1 -0
  21. data/lib/vagabond/actions/status.rb +1 -0
  22. data/lib/vagabond/actions/thaw.rb +1 -0
  23. data/lib/vagabond/actions/up.rb +22 -7
  24. data/lib/vagabond/bootstraps/chef_10_compat_config.erb +62 -0
  25. data/lib/vagabond/bootstraps/no_lazy_load.erb +63 -0
  26. data/lib/vagabond/bootstraps/server-zero.erb +1 -8
  27. data/lib/vagabond/bootstraps/server.erb +9 -6
  28. data/lib/vagabond/constants.rb +1 -6
  29. data/lib/vagabond/core.rb +209 -0
  30. data/lib/vagabond/errors.rb +3 -0
  31. data/lib/vagabond/helpers.rb +11 -99
  32. data/lib/vagabond/helpers/base.rb +134 -0
  33. data/lib/vagabond/helpers/callbacks.rb +47 -0
  34. data/lib/vagabond/helpers/chains.rb +23 -0
  35. data/lib/vagabond/helpers/commands.rb +49 -0
  36. data/lib/vagabond/helpers/knife.rb +47 -0
  37. data/lib/vagabond/helpers/naming.rb +39 -0
  38. data/lib/vagabond/helpers/server.rb +30 -0
  39. data/lib/vagabond/internal_configuration.rb +186 -32
  40. data/lib/vagabond/kitchen.rb +110 -60
  41. data/lib/vagabond/knife.rb +5 -1
  42. data/lib/vagabond/layout.rb +1 -0
  43. data/lib/vagabond/monkey/kitchen_config.rb +1 -0
  44. data/lib/vagabond/notify_mash.rb +25 -0
  45. data/lib/vagabond/server.rb +81 -49
  46. data/lib/vagabond/settings.rb +17 -0
  47. data/lib/vagabond/spec.rb +125 -99
  48. data/lib/vagabond/uploader.rb +4 -1
  49. data/lib/vagabond/uploader/berkshelf.rb +2 -1
  50. data/lib/vagabond/uploader/knife.rb +3 -9
  51. data/lib/vagabond/uploader/librarian.rb +2 -5
  52. data/lib/vagabond/vagabond.rb +77 -93
  53. data/lib/vagabond/vagabondfile.rb +73 -9
  54. data/lib/vagabond/version.rb +2 -1
  55. data/vagabond.gemspec +7 -5
  56. metadata +58 -81
  57. data/lib/vagabond/cookbooks/apt/Berksfile +0 -8
  58. data/lib/vagabond/cookbooks/apt/CHANGELOG.md +0 -97
  59. data/lib/vagabond/cookbooks/apt/CONTRIBUTING +0 -29
  60. data/lib/vagabond/cookbooks/apt/LICENSE +0 -201
  61. data/lib/vagabond/cookbooks/apt/README.md +0 -243
  62. data/lib/vagabond/cookbooks/apt/TESTING.md +0 -25
  63. data/lib/vagabond/cookbooks/apt/attributes/default.rb +0 -4
  64. data/lib/vagabond/cookbooks/apt/files/default/apt-proxy-v2.conf +0 -50
  65. data/lib/vagabond/cookbooks/apt/metadata.rb +0 -30
  66. data/lib/vagabond/cookbooks/apt/providers/preference.rb +0 -61
  67. data/lib/vagabond/cookbooks/apt/providers/repository.rb +0 -132
  68. data/lib/vagabond/cookbooks/apt/recipes/cacher-client.rb +0 -59
  69. data/lib/vagabond/cookbooks/apt/recipes/cacher-ng.rb +0 -40
  70. data/lib/vagabond/cookbooks/apt/recipes/default.rb +0 -68
  71. data/lib/vagabond/cookbooks/apt/resources/preference.rb +0 -30
  72. data/lib/vagabond/cookbooks/apt/resources/repository.rb +0 -40
  73. data/lib/vagabond/cookbooks/apt/templates/debian-6.0/acng.conf.erb +0 -174
  74. data/lib/vagabond/cookbooks/apt/templates/default/01proxy.erb +0 -2
  75. data/lib/vagabond/cookbooks/apt/templates/default/acng.conf.erb +0 -276
  76. data/lib/vagabond/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb +0 -270
  77. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/README.md +0 -1
  78. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/cacher-ng_test.rb +0 -28
  79. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/default_test.rb +0 -28
  80. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/lwrps_test.rb +0 -48
  81. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/files/default/tests/minitest/support/helpers.rb +0 -29
  82. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/metadata.rb +0 -6
  83. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/cacher-ng.rb +0 -20
  84. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/default.rb +0 -20
  85. data/lib/vagabond/cookbooks/apt/test/cookbooks/apt_test/recipes/lwrps.rb +0 -66
  86. data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +0 -37
  87. data/lib/vagabond/cookbooks/lxc/Gemfile +0 -4
  88. data/lib/vagabond/cookbooks/lxc/Gemfile.lock +0 -41
  89. data/lib/vagabond/cookbooks/lxc/README.md +0 -112
  90. data/lib/vagabond/cookbooks/lxc/attributes/default.rb +0 -26
  91. data/lib/vagabond/cookbooks/lxc/files/default/knife_lxc +0 -228
  92. data/lib/vagabond/cookbooks/lxc/files/default/lxc-awesome-ephemeral +0 -499
  93. data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +0 -477
  94. data/lib/vagabond/cookbooks/lxc/libraries/lxc_expanded_resources.rb +0 -40
  95. data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +0 -84
  96. data/lib/vagabond/cookbooks/lxc/libraries/monkey.rb +0 -51
  97. data/lib/vagabond/cookbooks/lxc/metadata.rb +0 -12
  98. data/lib/vagabond/cookbooks/lxc/providers/config.rb +0 -75
  99. data/lib/vagabond/cookbooks/lxc/providers/container.rb +0 -354
  100. data/lib/vagabond/cookbooks/lxc/providers/default.rb +0 -57
  101. data/lib/vagabond/cookbooks/lxc/providers/ephemeral.rb +0 -40
  102. data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +0 -30
  103. data/lib/vagabond/cookbooks/lxc/providers/interface.rb +0 -45
  104. data/lib/vagabond/cookbooks/lxc/providers/service.rb +0 -53
  105. data/lib/vagabond/cookbooks/lxc/recipes/containers.rb +0 -13
  106. data/lib/vagabond/cookbooks/lxc/recipes/default.rb +0 -58
  107. data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +0 -15
  108. data/lib/vagabond/cookbooks/lxc/recipes/knife.rb +0 -37
  109. data/lib/vagabond/cookbooks/lxc/resources/config.rb +0 -19
  110. data/lib/vagabond/cookbooks/lxc/resources/container.rb +0 -54
  111. data/lib/vagabond/cookbooks/lxc/resources/default.rb +0 -12
  112. data/lib/vagabond/cookbooks/lxc/resources/ephemeral.rb +0 -13
  113. data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +0 -12
  114. data/lib/vagabond/cookbooks/lxc/resources/interface.rb +0 -13
  115. data/lib/vagabond/cookbooks/lxc/resources/service.rb +0 -5
  116. data/lib/vagabond/cookbooks/lxc/templates/default/client.rb.erb +0 -13
  117. data/lib/vagabond/cookbooks/lxc/templates/default/default-lxc.erb +0 -3
  118. data/lib/vagabond/cookbooks/lxc/templates/default/file_content.erb +0 -2
  119. data/lib/vagabond/cookbooks/lxc/templates/default/fstab.erb +0 -5
  120. data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +0 -27
  121. data/lib/vagabond/cookbooks/vagabond/README.md +0 -10
  122. data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +0 -18
  123. data/lib/vagabond/cookbooks/vagabond/files/default/lxc-centos +0 -460
  124. data/lib/vagabond/cookbooks/vagabond/libraries/vagabond.rb +0 -10
  125. data/lib/vagabond/cookbooks/vagabond/metadata.rb +0 -8
  126. data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +0 -132
  127. data/lib/vagabond/cookbooks/vagabond/recipes/zero.rb +0 -9
  128. data/lib/vagabond/helpers/cheffile_loader.rb +0 -20
  129. data/vagabond-0.2.6.gem +0 -0
@@ -0,0 +1,47 @@
1
+ #encoding: utf-8
2
+ require 'vagabond/constants'
3
+
4
+ module Vagabond
5
+ module Helpers
6
+ module Callbacks
7
+
8
+ def callbacks(key)
9
+ if(vagabondfile[:callbacks][key])
10
+ if(options[:callbacks])
11
+ ui.info " Running #{ui.color(key, :bold)} callbacks..."
12
+ if(options[:cluster])
13
+ cluster_name = name
14
+ names = vagabondfile[:clusters][name] if vagabondfile[:clusters]
15
+ else
16
+ names = [name]
17
+ end
18
+ names.compact.each do |n|
19
+ @name = n
20
+ callbacks = Array(vagabondfile.callbacks_for(name)[key]).compact.flatten
21
+ callbacks.each do |command|
22
+ Array(command.scan(/\$\{(\w+)\}/).first).each do |repl|
23
+ command = command.gsub("${#{repl}}", self.send(repl.downcase))
24
+ end
25
+ ui.info " Running: #{command}"
26
+ opts = {:timeout => 30}
27
+ opts.merge(vagabondfile[:callbacks][:options] || {})
28
+ cmd = Mixlib::ShellOut.new(command,
29
+ opts.merge(:live_stream => options[:debug])
30
+ )
31
+ cmd.run_command
32
+ if(cmd.status.success?)
33
+ ui.info ui.color(' -> SUCCESS', :green)
34
+ else
35
+ ui.info ui.color(" -> FAILED - (#{cmd.stderr.strip.gsub("\n", ' ')})", :red)
36
+ end
37
+ end
38
+ end
39
+ @name = cluster_name if cluster_name
40
+ ui.info ui.color(' -> COMPLETE', :green)
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,23 @@
1
+ #encoding: utf-8
2
+ require 'vagabond/constants'
3
+
4
+ module Vagabond
5
+ module Helpers
6
+ module Chains
7
+
8
+ def add_link(action)
9
+ @chain ||= []
10
+ @chain << action
11
+ end
12
+
13
+ def chain!
14
+ if(@chain)
15
+ while(action = @chain.shift)
16
+ send(action, *@original_args)
17
+ end
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ #encoding: utf-8
2
+
3
+ require 'vagabond/constants'
4
+
5
+ module Vagabond
6
+ module Helpers
7
+ module Commands
8
+
9
+ def direct_container_command(command, args={})
10
+ _lxc = args[:lxc] || lxc
11
+ com = "#{sudo}ssh root@#{lxc.container_ip} -i #{Settings[:ssh_key]} -oStrictHostKeyChecking=no '#{command}'"
12
+ debug(com)
13
+ begin
14
+ cmd = Mixlib::ShellOut.new(com,
15
+ :live_stream => args[:live_stream] || options[:debug],
16
+ :timeout => args[:timeout] || 1200
17
+ )
18
+ cmd.run_command
19
+ cmd.error!
20
+ cmd
21
+ rescue
22
+ raise if args[:raise_on_failure]
23
+ false
24
+ end
25
+ end
26
+
27
+ def via_bundle
28
+ if(defined?(Bundler) && Bundler.bundle_path)
29
+ 'bundle exec '
30
+ end
31
+ end
32
+
33
+ def build_command(command, args={})
34
+ command = "#{via_bundle}#{command}" unless args[:no_bundle]
35
+ command = "#{sudo}#{command}" if args[:sudo]
36
+ pre_args = args[:shellout] || {}
37
+ debug(command)
38
+ cmd = Mixlib::ShellOut.new(
39
+ command, {
40
+ :live_stream => options[:debug],
41
+ :timeout => 3600
42
+ }.merge(pre_args)
43
+ )
44
+ cmd
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,47 @@
1
+ #encoding: utf-8
2
+
3
+ require 'vagabond/settings'
4
+ require 'vagabond/constants'
5
+ require 'vagabond/helpers/commands'
6
+
7
+ module Vagabond
8
+ module Helpers
9
+ module Knife
10
+
11
+ def knife_command(action, opts={})
12
+ conf = knife_config_build.to_a.map do |ary|
13
+ scrub = ary.compact.map do |arg|
14
+ if(arg)
15
+ arg.gsub('_', '-')
16
+ end
17
+ end
18
+ "--#{scrub.join(' ')}"
19
+ end.join(' ')
20
+ build_command("knife #{action} #{conf}", :shellout => opts)
21
+ end
22
+
23
+ def knife_config_build
24
+ base = Mash.new
25
+ if(File.exists?(kconf = File.join(vagabondfile.store_directory, '.chef/knife.rb')))
26
+ base[:config] = File.expand_path(kconf)
27
+ end
28
+ base.merge(knife_config)
29
+ end
30
+
31
+ def knife_config(args = {})
32
+ Settings[:knife] ||= Mash.new
33
+ Settings[:knife].merge!(args)
34
+ Settings[:knife]
35
+ end
36
+
37
+ class << self
38
+ def included(klass)
39
+ unless(klass.ancestors.include?(::Vagabond::Helpers::Commands))
40
+ klass.send(:include, ::Vagabond::Helpers::Commands)
41
+ end
42
+ end
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,39 @@
1
+ #encoding: utf-8
2
+
3
+ require 'vagabond/constants'
4
+
5
+ module Vagabond
6
+ module Helpers
7
+ module Naming
8
+
9
+ RAND_CHARS = ('a'..'z').map(&:to_s) + ('A'..'Z').map(&:to_s) + (0..9).map(&:to_s)
10
+ GEN_NAME_LENGTH = 10
11
+
12
+ private
13
+
14
+ def random_name(n=nil)
15
+ n = name unless n
16
+ [n, SecureRandom.hex].compact.join('-')
17
+ end
18
+
19
+ def generated_name(n=nil)
20
+ seed = vagabondfile.directory.chars.map(&:ord).inject(&:+)
21
+ srand(seed)
22
+ n = name unless n
23
+ if(@_gn.nil? || @_gn[n].nil?)
24
+ @_gn ||= Mash.new
25
+ @_gn[n] = "#{n}-"
26
+ GEN_NAME_LENGTH.times do
27
+ @_gn[n] << RAND_CHARS[rand(RAND_CHARS.size)]
28
+ end
29
+ end
30
+ @_gn[n]
31
+ end
32
+
33
+ def generate_hash
34
+ Digest::MD5.hexdigest(@vagabondfile.path)
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ module Vagabond
2
+ module Helpers
3
+ module Server
4
+ def setup_server_if_needed
5
+ require 'vagabond/server'
6
+ srv = ::Vagabond::Server.new
7
+ srv.options = options.dup
8
+ unless(vagabondfile.local_chef_server?)
9
+ srv.options[:force_zero] = true
10
+ end
11
+ srv.options[:auto_provision] = true
12
+ unless(srv.lxc.running?)
13
+ vagabondfile.generate_store_path
14
+ internal_config.make_knife_config_if_required(:force)
15
+ srv.up
16
+ knife_config :server_url => "http#{'s' unless srv.lxc.name.include?('zero')}://#{srv.lxc.container_ip(20, true)}"
17
+ srv.send(:upload_cookbooks)
18
+ @srv = srv
19
+ end
20
+ knife_config :server_url => "http#{'s' unless srv.lxc.name.include?('zero')}://#{srv.lxc.container_ip(20, true)}"
21
+ end
22
+
23
+ def destroy_server_if_needed
24
+ if(@srv)
25
+ @srv.destroy
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,12 +1,28 @@
1
- require 'digest/sha2'
1
+ #encoding: utf-8
2
2
  require 'json'
3
+ require 'digest/sha2'
4
+
5
+ require 'chef'
6
+ require 'chef/mixin/deep_merge'
7
+
3
8
  require 'vagabond/helpers'
4
9
  require 'vagabond/constants'
5
- require 'chef/mixin/deep_merge'
10
+ require 'vagabond/version'
11
+ require 'vagabond/notify_mash'
6
12
 
7
13
  module Vagabond
8
14
  class InternalConfiguration
9
15
 
16
+ DEFAULT_ERCHEF_VERSION = '11.0.8'
17
+
18
+ class << self
19
+ attr_accessor :host_provisioned
20
+
21
+ def host_provisioned?
22
+ !!@host_provisioned
23
+ end
24
+ end
25
+
10
26
  include Helpers
11
27
 
12
28
  attr_reader :config
@@ -17,29 +33,53 @@ module Vagabond
17
33
  def initialize(vagabondfile, ui, options, args={})
18
34
  @vagabondfile = vagabondfile
19
35
  @checksums = Mash.new
20
- @ui = ui
36
+ if(ui)
37
+ @ui = ui
38
+ else
39
+ @ui = Logger.new('/dev/null')
40
+ @ui.instance_eval do
41
+ def color(*args)
42
+ end
43
+ end
44
+ end
21
45
  @options = options
22
46
  create_store
23
47
  load_existing
24
- @config = Mash.new(
25
- :mappings => Mash.new,
26
- :template_mappings => Mash.new,
27
- :test_mappings => Mash.new,
28
- :spec_mappings => Mash.new,
29
- :spec_clusters => Mash.new
30
- ).merge(config)
48
+ @config = storage_hash(
49
+ Mash.new(
50
+ :mappings => {},
51
+ :template_mappings => {},
52
+ :test_mappings => {},
53
+ :spec_mappings => {},
54
+ :spec_clusters => {}
55
+ ).merge(config)
56
+ )
31
57
  @force_bases = args[:force_bases] || []
32
58
  ensure_state
33
59
  make_knife_config_if_required
34
60
  end
35
61
 
36
62
  def ensure_state
63
+ unless(self.class.host_provisioned?)
64
+ install_cookbooks
65
+ end
37
66
  check_bases_and_customs!
67
+ set_templates
68
+ store_checksums
69
+ write_dna_json
70
+ write_solo_rb
38
71
  if(solo_needed?)
39
- store_checksums
40
- write_dna_json
41
- write_solo_rb
42
- run_solo if solo_needed?
72
+ run_solo
73
+ else
74
+ self.class.host_provisioned = true
75
+ end
76
+ end
77
+
78
+ def set_templates
79
+ unless(Vagabond.const_defined?(:BASE_TEMPLATES))
80
+ Vagabond.const_set(
81
+ :BASE_TEMPLATES, cookbook_attributes(:vagabond).bases.keys
82
+ )
43
83
  end
44
84
  end
45
85
 
@@ -53,6 +93,16 @@ module Vagabond
53
93
  end
54
94
  end
55
95
  end
96
+ if(dna[:vagabond][:server])
97
+ srv_name = [
98
+ cookbook_attributes(:vagabond).server.prefix,
99
+ dna[:vagabond][:server][:erchefs].first.to_s.gsub('.', '_')
100
+ ].join
101
+ options[:force_solo] = true unless Lxc.new(srv_name).exists?
102
+ end
103
+ unless(Lxc.new(cookbook_attributes(:vagabond).server.zero_lxc_name).exists?)
104
+ options[:force_solo] = true
105
+ end
56
106
  end
57
107
  end
58
108
 
@@ -61,7 +111,11 @@ module Vagabond
61
111
  end
62
112
 
63
113
  def []=(k,v)
114
+ if(v.is_a?(Hash))
115
+ v = storage_hash(v)
116
+ end
64
117
  @config[k] = v
118
+ save
65
119
  end
66
120
 
67
121
  def create_store
@@ -83,9 +137,9 @@ module Vagabond
83
137
  JSON.load(content)
84
138
  )
85
139
  end
86
- @config = Chef::Mixin::DeepMerge.merge(config, @config)
140
+ @config = storage_hash(Chef::Mixin::DeepMerge.merge(config, @config))
87
141
  else
88
- @config = Mash.new
142
+ @config = storage_hash
89
143
  end
90
144
  end
91
145
 
@@ -108,10 +162,10 @@ module Vagabond
108
162
  def write_dna_json
109
163
  conf = Mash.new(:bases => Mash.new, :customs => Mash.new)
110
164
  (Array(@vagabondfile[:nodes]).map(&:last).map{|i| i[:template]}.compact + Array(force_bases)).uniq.each do |t|
111
- conf[:bases][t] = Mash.new(:enabled => true) if BASE_TEMPLATES.include?(t.to_s)
165
+ conf[:bases][t] = Mash.new(:enabled => true) if Vagabond::BASE_TEMPLATES.include?(t.to_s)
112
166
  end
113
167
  Array(@vagabondfile[:templates]).each do |t_name, opts|
114
- if(BASE_TEMPLATES.include?(opts[:base].to_s))
168
+ if(Vagabond::BASE_TEMPLATES.include?(opts[:base].to_s))
115
169
  conf[:bases][opts[:base]] = Mash.new(:enabled => true)
116
170
  if(opts.has_key?(:memory) && !opts[:memory].is_a?(Hash))
117
171
  opts[:memory][:ram] = opts[:memory].to_s
@@ -124,6 +178,13 @@ module Vagabond
124
178
  raise VagabondError::InvalidBaseTemplate.new(t_name)
125
179
  end
126
180
  end
181
+ if(@vagabondfile.local_chef_server? && !@vagabondfile[:local_chef_server][:zero])
182
+ version = cookbook_attributes(:vagabond).server.erchefs.dup || []
183
+ version.push @vagabondfile[:local_chef_server][:version] || DEFAULT_ERCHEF_VERSION
184
+ conf[:server] = Mash.new
185
+ conf[:server][:erchefs] = [version].flatten.uniq
186
+ end
187
+ conf[:host_cookbook_store] = cookbook_path
127
188
  File.open(dna_path, 'w') do |file|
128
189
  file.write(
129
190
  JSON.dump(
@@ -177,28 +238,86 @@ module Vagabond
177
238
  end
178
239
 
179
240
  def cookbook_path
241
+ unless(@cookbook_path)
242
+ FileUtils.mkdir_p(@cookbook_path = File.join(store_path, 'cookbooks'))
243
+ end
244
+ @cookbook_path
245
+ end
246
+
247
+ def cheffile_path
180
248
  File.expand_path(
181
249
  File.join(
182
- File.dirname(__FILE__), 'cookbooks'
250
+ File.dirname(__FILE__),
251
+ running_development_vagabond? ? 'Cheffile.dev' : 'Cheffile'
183
252
  )
184
253
  )
185
254
  end
255
+
256
+ def vendor_cheffile_path
257
+ File.expand_path(
258
+ File.join(File.dirname(cookbook_path), 'Cheffile')
259
+ )
260
+ end
186
261
 
187
- def run_solo
262
+ def cookbook_vendor_required?
263
+ need_vendor = !File.exists?(vendor_cheffile_path)
264
+ need_vendor ||= get_checksum(vendor_cheffile_path) != get_checksum(cheffile_path)
265
+ spec = Gem::Specification.find_by_name('vagabond', ::Vagabond::VERSION.version)
266
+ if(running_development_vagabond?)
267
+ if(self[:dev_mode] && self[:dev_mode][:vendor_cookbook_check])
268
+ elapsed_time = Time.now.to_i - self[:dev_mode][:vendor_cookbook_check].to_i
269
+ need_vendor = elapsed_time > (ENV['VAGABOND_DEV_VENDOR_EVERY'] || 3600).to_i
270
+ end
271
+ self[:dev_mode] ||= Mash.new
272
+ self[:dev_mode][:vendor_cookbook_check] = Time.now.to_i if need_vendor
273
+ end
274
+ unless(ENV['VAGABOND_FORCE_VENDOR'].to_s == 'false')
275
+ ENV['VAGABOND_FORCE_VENDOR'] || need_vendor
276
+ end
277
+ end
278
+
279
+ def running_development_vagabond?
280
+ spec = Gem::Specification.find_by_name('vagabond', ::Vagabond::VERSION.version)
281
+ ::Vagabond::VERSION.segments.last.odd?
282
+ end
283
+
284
+ def install_cookbooks
188
285
  begin
189
- ui.info ui.color('Ensuring expected system state (creating required base containers)', :yellow)
190
- ui.info ui.color(' - This can take a while on first run or new templates...', :yellow)
191
- com = "#{options[:sudo]}chef-solo -j #{File.join(store_path, 'dna.json')} -c #{File.join(store_path, 'solo.rb')}"
192
- debug(com)
193
- cmd = Mixlib::ShellOut.new(com, :timeout => 12000, :live_stream => options[:debug])
194
- cmd.run_command
195
- cmd.error!
196
- ui.info ui.color(' -> COMPLETE!', :yellow)
286
+ if(cookbook_vendor_required?)
287
+ FileUtils.copy(cheffile_path, vendor_cheffile_path)
288
+ ui.info ui.color('Fetching required cookbooks...', :yellow)
289
+ cmd = build_command('librarian-chef update', :shellout => {:cwd => File.dirname(cookbook_path)})
290
+ cmd.run_command
291
+ cmd.error!
292
+ ui.info ui.color(' -> COMPLETE!', :yellow)
293
+ else
294
+ cmd = build_command('librarian-chef install', :shellout => {:cwd => File.dirname(cookbook_path)})
295
+ cmd.run_command
296
+ cmd.error!
297
+ end
197
298
  rescue => e
198
299
  ui.info e.to_s
199
- FileUtils.rm(solo_path)
200
300
  ui.info ui.color(' -> FAILED!', :red, :bold)
201
- raise VagabondError::HostProvisionFailed.new(e)
301
+ raise VagabondError::LibrarianHostInstallFailed.new(e)
302
+ end
303
+ end
304
+
305
+ def run_solo
306
+ unless(self.class.host_provisioned?)
307
+ begin
308
+ ui.info ui.color('Ensuring expected system state (creating required base containers)', :yellow)
309
+ ui.info ui.color(' - This can take a while on first run or new templates...', :yellow)
310
+ cmd = build_command("chef-solo -j #{File.join(store_path, 'dna.json')} -c #{File.join(store_path, 'solo.rb')}", :sudo => true)
311
+ cmd.run_command
312
+ cmd.error!
313
+ ui.info ui.color(' -> COMPLETE!', :yellow)
314
+ self.class.host_provisioned = true
315
+ rescue => e
316
+ ui.info e.to_s
317
+ FileUtils.rm(solo_path)
318
+ ui.info ui.color(' -> FAILED!', :red, :bold)
319
+ raise VagabondError::HostProvisionFailed.new(e)
320
+ end
202
321
  end
203
322
  end
204
323
 
@@ -238,10 +357,45 @@ module Vagabond
238
357
  def file_changed?(path)
239
358
  checksum = get_checksum(path)
240
359
  checksum unless @checksums[path] == checksum
241
- end
360
+ end
361
+
362
+ def storage_hash(hsh={})
363
+ new_hash = {}
364
+ hsh.each_pair do |k,v|
365
+ if(v.is_a?(Hash))
366
+ new_hash[k] = storage_hash(v)
367
+ else
368
+ new_hash[k] = v
369
+ end
370
+ end
371
+ n = NotifyMash.new(new_hash)
372
+ n.add_notification do
373
+ save
374
+ end
375
+ n
376
+ end
377
+
378
+ def cookbook_attributes(cookbook, namespace=true)
379
+ @_attr_cache ||= Mash.new
380
+ unless(@_attr_cache[cookbook])
381
+ node = Chef::Node.new
382
+ %w(rb json js).each do |ext|
383
+ Dir.glob(File.join(cookbook_path, cookbook.to_s, 'attributes', "*.#{ext}")).each do |attr_file|
384
+ node.from_file(attr_file)
385
+ end
386
+ end
387
+ if(namespace)
388
+ key = namespace.is_a?(String) || namespace.is_a?(Symbol) ? namespace : cookbook
389
+ @_attr_cache[cookbook] = node.attributes.send(key)
390
+ else
391
+ @_attr_cache[cookbook] = node.attributes
392
+ end
393
+ end
394
+ @_attr_cache[cookbook]
395
+ end
242
396
 
243
397
  def make_knife_config_if_required(force=false)
244
- if((@vagabondfile[:local_chef_server] && @vagabondfile[:local_chef_server][:enabled]) || force)
398
+ if(@vagabondfile.local_chef_server? || force)
245
399
  unless(knife_config_available?)
246
400
  store_dir = File.dirname(store_path)
247
401
  k_dir = File.join(store_dir, '.chef')