vagabond 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/CHANGELOG.md +18 -0
  2. data/README.md +125 -4
  3. data/bin/vagabond +43 -16
  4. data/lib/vagabond/actions/cluster.rb +66 -0
  5. data/lib/vagabond/actions/create.rb +12 -7
  6. data/lib/vagabond/actions/destroy.rb +69 -15
  7. data/lib/vagabond/actions/init.rb +75 -0
  8. data/lib/vagabond/actions/provision.rb +4 -2
  9. data/lib/vagabond/actions/status.rb +33 -22
  10. data/lib/vagabond/actions/up.rb +8 -1
  11. data/lib/vagabond/bootstraps/server-zero.erb +20 -0
  12. data/lib/vagabond/bootstraps/server.erb +3 -2
  13. data/lib/vagabond/constants.rb +0 -15
  14. data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +16 -0
  15. data/lib/vagabond/cookbooks/lxc/Gemfile +3 -2
  16. data/lib/vagabond/cookbooks/lxc/Gemfile.lock +30 -121
  17. data/lib/vagabond/cookbooks/lxc/README.md +43 -14
  18. data/lib/vagabond/cookbooks/lxc/attributes/default.rb +3 -3
  19. data/lib/vagabond/cookbooks/lxc/files/default/lxc-awesome-ephemeral +499 -0
  20. data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +223 -58
  21. data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +3 -0
  22. data/lib/vagabond/cookbooks/lxc/libraries/monkey.rb +51 -0
  23. data/lib/vagabond/cookbooks/lxc/metadata.rb +6 -5
  24. data/lib/vagabond/cookbooks/lxc/providers/config.rb +9 -16
  25. data/lib/vagabond/cookbooks/lxc/providers/container.rb +241 -229
  26. data/lib/vagabond/cookbooks/lxc/providers/default.rb +57 -0
  27. data/lib/vagabond/cookbooks/lxc/providers/ephemeral.rb +40 -0
  28. data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +13 -54
  29. data/lib/vagabond/cookbooks/lxc/providers/interface.rb +13 -67
  30. data/lib/vagabond/cookbooks/lxc/providers/service.rb +14 -14
  31. data/lib/vagabond/cookbooks/lxc/recipes/default.rb +17 -4
  32. data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +1 -1
  33. data/lib/vagabond/cookbooks/lxc/resources/config.rb +2 -2
  34. data/lib/vagabond/cookbooks/lxc/resources/container.rb +31 -6
  35. data/lib/vagabond/cookbooks/lxc/resources/default.rb +12 -0
  36. data/lib/vagabond/cookbooks/lxc/resources/ephemeral.rb +13 -0
  37. data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +2 -1
  38. data/lib/vagabond/cookbooks/lxc/resources/interface.rb +6 -3
  39. data/lib/vagabond/cookbooks/lxc/resources/service.rb +1 -1
  40. data/lib/vagabond/cookbooks/lxc/templates/default/file_content.erb +2 -0
  41. data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +9 -3
  42. data/lib/vagabond/cookbooks/vagabond/README.md +10 -0
  43. data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +1 -0
  44. data/lib/vagabond/cookbooks/vagabond/files/default/lxc-centos +13 -6
  45. data/lib/vagabond/cookbooks/vagabond/metadata.rb +1 -0
  46. data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +46 -4
  47. data/lib/vagabond/cookbooks/vagabond/recipes/zero.rb +9 -0
  48. data/lib/vagabond/errors.rb +23 -0
  49. data/lib/vagabond/helpers.rb +41 -14
  50. data/lib/vagabond/internal_configuration.rb +120 -27
  51. data/lib/vagabond/kitchen.rb +143 -63
  52. data/lib/vagabond/knife.rb +8 -5
  53. data/lib/vagabond/layout.rb +16 -0
  54. data/lib/vagabond/monkey/kitchen_config.rb +23 -0
  55. data/lib/vagabond/server.rb +79 -63
  56. data/lib/vagabond/spec.rb +345 -0
  57. data/lib/vagabond/uploader.rb +30 -0
  58. data/lib/vagabond/uploader/berkshelf.rb +53 -0
  59. data/lib/vagabond/uploader/knife.rb +24 -0
  60. data/lib/vagabond/uploader/librarian.rb +31 -0
  61. data/lib/vagabond/vagabond.rb +30 -11
  62. data/lib/vagabond/vagabondfile.rb +40 -5
  63. data/lib/vagabond/version.rb +1 -1
  64. data/vagabond.gemspec +5 -2
  65. metadata +75 -15
  66. data/lib/vagabond/cookbooks/lxc/resources/#container.rb# +0 -28
  67. data/lib/vagabond/cookbooks/lxc/test/kitchen/Kitchenfile +0 -7
  68. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/metadata.rb +0 -2
  69. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/centos_lxc.rb +0 -0
  70. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/chef-bootstrap.rb +0 -0
  71. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_files.rb +0 -0
  72. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_templates.rb +0 -0
  73. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/ubuntu_lxc.rb +0 -0
@@ -1,9 +1,10 @@
1
- maintainer "Chris Roberts"
2
- maintainer_email "chrisroberts.code@gmail.com"
3
- license "Apache 2.0"
4
- description "Chef driven Linux Containers"
1
+ name 'lxc'
2
+ maintainer 'Chris Roberts'
3
+ maintainer_email 'chrisroberts.code@gmail.com'
4
+ license 'Apache 2.0'
5
+ description 'Chef driven Linux Containers'
5
6
  long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
6
- version "0.1.1"
7
+ version '1.0.1'
7
8
 
8
9
  supports 'ubuntu'
9
10
 
@@ -1,16 +1,16 @@
1
1
  require 'securerandom'
2
2
 
3
3
  def load_current_resource
4
- new_resource._lxc Lxc.new(
4
+ @lxc = ::Lxc.new(
5
5
  new_resource.name,
6
6
  :base_dir => node[:lxc][:container_directory],
7
7
  :dnsmasq_lease_file => node[:lxc][:dnsmasq_lease_file]
8
8
  )
9
9
  new_resource.utsname new_resource.name unless new_resource.utsname
10
- new_resource.rootfs new_resource._lxc.rootfs unless new_resource.rootfs
10
+ new_resource.rootfs @lxc.rootfs.to_path unless new_resource.rootfs
11
11
  new_resource.default_bridge node[:lxc][:bridge] unless new_resource.default_bridge
12
- new_resource.mount ::File.join(new_resource._lxc.path, 'fstab') unless new_resource.mount
13
- config = LxcFileConfig.new(new_resource._lxc.container_config)
12
+ new_resource.mount @lxc.path.join('fstab').to_path unless new_resource.mount
13
+ config = LxcFileConfig.new(@lxc.container_config)
14
14
  if((new_resource.network.nil? || new_resource.network.empty?))
15
15
  if(config.network.empty?)
16
16
  default_net = {
@@ -19,11 +19,10 @@ def load_current_resource
19
19
  :flags => :up,
20
20
  :hwaddr => "00:16:3e#{SecureRandom.hex(3).gsub(/(..)/, ':\1')}"
21
21
  }
22
- default_net.merge!(:ipv4 => new_resource.static_ip) if new_resource.static_ip
23
22
  else
24
23
  default_net = config.network.first
24
+ default_net.delete(:ipv4) if default_net.has_key?(:ipv4)
25
25
  default_net.merge!(:link => new_resource.default_bridge)
26
- default_net.merge!(:ipv4 => new_resource.static_ip) if new_resource.static_ip
27
26
  end
28
27
  new_resource.network(default_net)
29
28
  else
@@ -62,21 +61,15 @@ def load_current_resource
62
61
  end
63
62
 
64
63
  action :create do
65
- ruby_block "lxc config_updater[#{new_resource.utsname}]" do
66
- block do
67
- new_resource.updated_by_last_action(true)
68
- end
69
- action :nothing
70
- end
71
-
72
- directory new_resource._lxc.container_path do
64
+ _lxc = @lxc
65
+
66
+ directory @lxc.path.to_path do
73
67
  action :create
74
68
  end
75
69
 
76
70
  file "lxc update_config[#{new_resource.utsname}]" do
77
- path new_resource._lxc.container_config
71
+ path _lxc.container_config.to_path
78
72
  content LxcFileConfig.generate_config(new_resource)
79
73
  mode 0644
80
- notifies :create, resources(:ruby_block => "lxc config_updater[#{new_resource.utsname}]"), :immediately
81
74
  end
82
75
  end
@@ -1,38 +1,51 @@
1
1
  def load_current_resource
2
- new_resource._lxc Lxc.new(
2
+ @lxc = ::Lxc.new(
3
3
  new_resource.name,
4
4
  :base_dir => node[:lxc][:container_directory],
5
5
  :dnsmasq_lease_file => node[:lxc][:dnsmasq_lease_file]
6
6
  )
7
+ new_resource.subresources.map! do |s_r|
8
+ s_r.first.run_context = run_context
9
+ s_r.first.instance_eval(&s_r.last)
10
+ s_r.first
11
+ end
12
+
7
13
  # TODO: Use some actual logic here, sheesh
8
14
  if(new_resource.static_ip && new_resource.static_gateway.nil?)
9
- new_resource.static_gateway new_resource.static_ip.sub(/\d+$/, '1')
15
+ raise "Static gateway must be defined when static IP is provided (Container: #{new_resource.name})"
10
16
  end
11
17
  new_resource.default_bridge node[:lxc][:bridge] unless new_resource.default_bridge
12
- new_resource.new_container !new_resource._lxc.exists?
18
+ node.run_state[:lxc] ||= Mash.new
19
+ node.run_state[:lxc][:meta] ||= Mash.new
20
+ node.run_state[:lxc][:meta][new_resource.name] = Mash.new(
21
+ :new_container => !@lxc.exists?,
22
+ :lxc => @lxc
23
+ )
13
24
  end
14
25
 
15
26
  action :create do
27
+ _lxc = @lxc # for use inside resources
28
+ stopped_end_state = _lxc.stopped?
16
29
 
17
30
  #### Add custom key for host based interactions
18
- lxc_dir = directory '/opt/hw-lxc-config' do
19
- action :nothing
31
+ directory '/opt/hw-lxc-config' do
32
+ recursive true
20
33
  end
21
- lxc_dir.run_action(:create)
22
34
 
23
- lxc_key = execute "lxc host_ssh_key" do
35
+ execute 'lxc host_ssh_key' do
24
36
  command "ssh-keygen -P '' -f /opt/hw-lxc-config/id_rsa"
25
- creates "/opt/hw-lxc-config/id_rsa"
26
- action :nothing
37
+ creates '/opt/hw-lxc-config/id_rsa'
27
38
  end
28
- lxc_key.run_action(:run)
29
39
 
30
40
  #### Create container
31
- execute "lxc create[#{new_resource.name}]" do
32
- command "lxc-create -n #{new_resource.name} -t #{new_resource.template} -- #{new_resource.template_opts.to_a.flatten.join(' ')}"
33
- environment new_resource.create_environment
34
- only_if do
35
- !new_resource._lxc.exists? && new_resource.updated_by_last_action(true)
41
+ lxc new_resource.name do
42
+ if(new_resource.clone)
43
+ action :clone
44
+ base_container new_resource.clone
45
+ else
46
+ action :create
47
+ template new_resource.template
48
+ template_opts new_resource.template_opts
36
49
  end
37
50
  end
38
51
 
@@ -41,7 +54,6 @@ action :create do
41
54
  lxc_config new_resource.name do
42
55
  action :create
43
56
  default_bridge new_resource.default_bridge
44
- static_ip new_resource.static_ip
45
57
  end
46
58
  end
47
59
 
@@ -71,272 +83,272 @@ action :create do
71
83
  netmask new_resource.static_netmask
72
84
  gateway new_resource.static_gateway
73
85
  end
86
+ end
74
87
 
75
- ruby_block "force container gateway[#{new_resource.name}]" do
76
- block do
77
- file = Chef::Util::FileEdit.new(
78
- ::File.join(
79
- new_resource._lxc.rootfs, 'etc', 'rc.local'
80
- )
81
- )
82
- file.search_file_delete_line(%r{route add default gw})
83
- file.search_file_replace(
84
- %r{exit 0$},
85
- "route add default gw #{new_resource.static_gateway}\nexit 0"
86
- )
87
- file.write_file
88
+ ruby_block "LXC #{new_resource.name} - Run subresources" do
89
+ block do
90
+ new_resource.subresources.each do |s_r|
91
+ s_r.run_action(:create)
88
92
  end
89
- not_if "grep \"route add default gw #{new_resource.static_gateway}\" #{::File.join(new_resource._lxc.rootfs, 'etc', 'rc.local')}"
93
+ end
94
+ not_if do
95
+ new_resource.subresources.empty?
90
96
  end
91
97
  end
92
98
 
93
- #### Ensure host has ssh access into container
94
- directory ::File.join(new_resource._lxc.rootfs, 'root', '.ssh')
95
-
96
- file ::File.join(new_resource._lxc.rootfs, 'root', '.ssh', 'authorized_keys') do
97
- content "# Chef generated key file\n#{::File.read('/opt/hw-lxc-config/id_rsa.pub')}\n"
99
+ template @lxc.path.join('fstab').to_path do
100
+ source 'fstab.erb'
101
+ cookbook 'lxc'
102
+ variables :container => new_resource.name
103
+ only_if do
104
+ node.run_state[:lxc][:fstabs] &&
105
+ node.run_state[:lxc][:fstabs][new_resource.name]
106
+ end
107
+ mode 0644
98
108
  end
99
109
 
100
- if(new_resource.chef_enabled || !new_resource.container_commands.empty? || !new_resource.initialize_commands.empty?)
101
- if(new_resource.chef_enabled && new_resource.new_container)
102
-
103
- #### Use cached chef package from host if available
104
- if(%w(debian ubuntu).include?(new_resource.template) && system('ls /opt/chef*.deb 2>1 > /dev/null'))
105
- file_name = Dir.new('/opt').detect do |item|
106
- item.start_with?('chef') && item.end_with?('.deb')
107
- end
108
- if(file_name)
109
- execute "lxc copy_chef_full[#{new_resource.name}]" do
110
- command "cp /opt/#{file_name} #{::File.join(new_resource._lxc.rootfs, 'opt')}"
111
- not_if do
112
- ::File.exists?(
113
- ::File.join(new_resource._lxc.rootfs, 'opt', file_name)
114
- )
115
- end
116
- end
117
-
118
- execute "lxc install_chef_full[#{new_resource.name}]" do
119
- action :nothing
120
- command "chroot #{new_resource._lxc.rootfs} dpkg -i #{::File.join('/opt', file_name)}"
121
- subscribes :run, resources(:execute => "lxc copy_chef_full[#{new_resource.name}]"), :immediately
122
- end
123
- @chef_installed = true
124
- end
125
- end
126
-
127
- # TODO: Add resources for RPM install
128
-
129
- #### Setup chef related bits within container
130
- directory ::File.join(new_resource._lxc.rootfs, 'etc', 'chef') do
131
- action :create
132
- mode 0755
133
- end
134
-
135
- template "lxc chef-config[#{new_resource.name}]" do
136
- source 'client.rb.erb'
137
- cookbook 'lxc'
138
- path ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'client.rb')
139
- variables(
140
- :validation_client => new_resource.validation_client,
141
- :node_name => new_resource.node_name || "#{node.name}-#{new_resource.name}",
142
- :server_uri => new_resource.server_uri,
143
- :chef_environment => new_resource.chef_environment || '_default'
144
- )
145
- mode 0644
146
- end
110
+ template @lxc.rootfs.join('etc/network/interfaces').to_path do
111
+ source 'interface.erb'
112
+ cookbook 'lxc'
113
+ variables :container => new_resource.name
114
+ mode 0644
115
+ only_if do
116
+ node.run_state[:lxc][:interfaces] &&
117
+ node.run_state[:lxc][:interfaces][new_resource.name]
118
+ end
119
+ end
147
120
 
148
- file "lxc chef-validator[#{new_resource.name}]" do
149
- path ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'validator.pem')
150
- content new_resource.validator_pem || node[:lxc][:validator_pem]
151
- mode 0600
152
- end
121
+ #### Ensure host has ssh access into container
122
+ directory @lxc.rootfs.join('root/.ssh').to_path
153
123
 
154
- file "lxc chef-runlist[#{new_resource.name}]" do
155
- path ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'first_run.json')
156
- content({:run_list => new_resource.run_list}.to_json)
157
- not_if do
158
- ::File.exists?(
159
- ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'client.pem')
160
- )
161
- end
162
- mode 0644
163
- end
124
+ template @lxc.rootfs.join('root/.ssh/authorized_keys').to_path do
125
+ source 'file_content.erb'
126
+ cookbook 'lxc'
127
+ mode 0600
128
+ variables(:path => '/opt/hw-lxc-config/id_rsa.pub')
129
+ end
164
130
 
165
- #### Provide data bag secret file if required
166
- if(new_resource.copy_data_bag_secret_file)
167
- if ::File.readable?(new_resource.data_bag_secret_file)
168
- file "lxc chef-data-bag-secret[#{new_resource.name}]" do
169
- path ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'encrypted_data_bag_secret')
170
- content ::File.open(new_resource.data_bag_secret_file, "rb").read
171
- mode 0600
172
- end
173
- else
174
- Chef::Log.warn "Could not read #{new_resource.data_bag_secret_file}"
175
- end
131
+ #### Use cached chef package from host if available
132
+ if(%w(debian ubuntu).include?(new_resource.template) && system('ls /opt/chef*.deb 2>1 > /dev/null'))
133
+ if(::File.directory?('/opt'))
134
+ file_name = Dir.new('/opt').detect do |item|
135
+ item.start_with?('chef') && item.end_with?('.deb')
176
136
  end
177
137
  end
178
-
179
- ruby_block "lxc start[#{new_resource.name}]" do
180
- block do
181
- new_resource._lxc.start
182
- end
183
- only_if do
184
- ::File.exists?(
185
- ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'first_run.json')
186
- ) || (new_resource.new_container && new_resource.initialize_commands)
138
+
139
+ execute "lxc copy_chef_full[#{new_resource.name}]" do
140
+ command "cp /opt/#{file_name} #{_lxc.rootfs.join('opt')}"
141
+ not_if do
142
+ file_name.nil? || !new_resource.chef_enabled || _lxc.rootfs.join('opt', file_name).exist?
187
143
  end
188
144
  end
145
+
146
+ execute "lxc install_chef_full[#{new_resource.name}]" do
147
+ action :nothing
148
+ command "chroot #{_lxc.rootfs} dpkg -i #{::File.join('/opt', file_name)}"
149
+ subscribes :run, "execute[lxc copy_chef_full[#{new_resource.name}]]", :immediately
150
+ end
151
+ elsif(new_resource.chef_enabled)
152
+ pkg_coms = ['update -y -q', 'upgrade -y -q','install curl -y -q']
153
+ if(!new_resource.template.to_s.scan(%r{debian|ubuntu}).empty?)
154
+ pkg_man = 'apt-get'
155
+ elsif(!new_resource.template.to_s.scan(%r{fedora|centos}).empty?)
156
+ pkg_man = 'yum'
157
+ end
158
+ if(pkg_man)
159
+ new_resource.initialize_commands(
160
+ pkg_coms.map do |c|
161
+ "#{pkg_man} #{c}"
162
+ end + new_resource.initialize_commands
163
+ )
164
+ end
165
+ end
189
166
 
190
- if(new_resource.chef_enabled && new_resource.new_container)
191
- # Make sure we have chef in the container
192
- unless(@chef_installed)
193
- # Use remote file to remove curl dep
194
- remote_file "lxc chef_install_script[#{new_resource.name}]" do
195
- source "http://opscode.com/chef/install.sh"
196
- path ::File.join(new_resource._lxc.rootfs, 'opt', 'chef-install.sh')
197
- action :create_if_missing
198
- end
199
-
200
- ruby_block "lxc install_chef[#{new_resource.name}]" do
201
- block do
202
- new_resource._lxc.container_command(
203
- "bash /opt/chef-install.sh"
204
- )
205
- end
206
- not_if do
207
- ::File.exists?(
208
- ::File.join(new_resource._lxc.rootfs, 'usr', 'bin', 'chef-client')
209
- )
167
+ ruby_block "lxc lock_default_users" do
168
+ block do
169
+ contents = ::File.readlines(_lxc.rootfs.join('etc/shadow').to_path)
170
+ ::File.open(_lxc.rootfs.join('etc/shadow').to_path, 'w') do |file|
171
+ contents.each do |line|
172
+ parts = line.split(':')
173
+ if(node[:lxc][:user_locks].include?(parts.first) && !parts[1].start_with?('!'))
174
+ parts[1] = "!#{parts[1]}"
210
175
  end
211
- end
212
- end
213
-
214
- #### Let chef configure the container
215
- ruby_block "lxc run_chef[#{new_resource.name}]" do
216
- block do
217
- new_resource._lxc.container_command(
218
- "chef-client -K /etc/chef/validator.pem -c /etc/chef/client.rb -j /etc/chef/first_run.json",
219
- new_resource.chef_retries
220
- )
221
- end
222
- not_if do
223
- ::File.exists?(
224
- ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'client.pem')
225
- )
176
+ file.write parts.join(':')
226
177
  end
227
178
  end
228
179
  end
229
-
230
- #### Have initialize commands for the container? Run them now
231
- if(new_resource.new_container && !new_resource.initialize_commands.empty?)
232
- ruby_block "lxc initialize_commands[#{new_resource.name}]" do
233
- block do
234
- new_resource.initialize_commands.each do |cmd|
235
- new_resource._lxc.container_command(cmd, 2)
236
- end
237
- end
180
+ only_if do
181
+ ::File.readlines(_lxc.rootfs.join('etc/shadow').to_path).detect do |line|
182
+ parts = line.split(':')
183
+ node[:lxc][:user_locks].include?(parts.first) && !parts[1].start_with?('!')
238
184
  end
239
185
  end
186
+ end
240
187
 
241
- #### Have commands for the container? Run them now
242
- unless(new_resource.container_commands.empty?)
243
- ruby_block "lxc container_commands[#{new_resource.name}]" do
244
- block do
245
- new_resource.container_commands.each do |cmd|
246
- new_resource._lxc.container_command(cmd, 2)
188
+ ruby_block "lxc default_password_scrub" do
189
+ block do
190
+ contents = ::File.readlines(_lxc.rootfs.join('etc/shadow').to_path)
191
+ ::File.open(_lxc.rootfs.join('etc/shadow'), 'w') do |file|
192
+ contents.each do |line|
193
+ if(line.start_with?('root:'))
194
+ line.sub!(%r{root:.+?:}, 'root:*')
247
195
  end
196
+ file.write line
248
197
  end
249
198
  end
250
199
  end
200
+ not_if "grep 'root:*' #{_lxc.rootfs.join('etc/shadow').to_path}"
201
+ end
251
202
 
252
- #### NOTE: Creation always leaves the container in a stopped state
253
- ruby_block "lxc shutdown[#{new_resource.name}]" do
254
- block do
255
- new_resource._lxc.shutdown
256
- end
257
- only_if do
258
- new_resource.new_container
259
- end
203
+ ruby_block "lxc start[#{new_resource.name}]" do
204
+ block do
205
+ _lxc.start
260
206
  end
261
-
262
- #### Clean up after chef if it's enabled
263
- if(new_resource.chef_enabled)
264
- file ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'first_run.json') do
265
- action :delete
266
- end
267
-
268
- file ::File.join(new_resource._lxc.rootfs, 'etc', 'chef', 'validator.pem') do
269
- action :delete
207
+ only_if do
208
+ _lxc.rootfs.join('etc/chef/first_run.json').exist? ||
209
+ !new_resource.container_commands.empty? ||
210
+ (node.run_state[:lxc][:meta][new_resource.name][:new_container] && new_resource.initialize_commands)
211
+ end
212
+ end
213
+
214
+ #### Have initialize commands for the container? Run them now
215
+ ruby_block "lxc initialize_commands[#{new_resource.name}]" do
216
+ block do
217
+ new_resource.initialize_commands.each do |cmd|
218
+ Chef::Log.info "Running command on #{new_resource.name}: #{cmd}"
219
+ _lxc.container_command(cmd, 2)
270
220
  end
271
221
  end
222
+ only_if do
223
+ node.run_state[:lxc][:meta][new_resource.name][:new_container] &&
224
+ !new_resource.initialize_commands.empty?
225
+ end
272
226
  end
273
227
 
274
- end
228
+ # Make sure we have chef in the container
229
+ remote_file "lxc chef_install_script[#{new_resource.name}]" do
230
+ source "http://opscode.com/chef/install.sh"
231
+ path _lxc.rootfs.join('opt/chef-install.sh').to_path
232
+ action :create_if_missing
233
+ only_if do
234
+ new_resource.chef_enabled && !_lxc.rootfs.join('usr/bin/chef-client').exist?
235
+ end
236
+ end
275
237
 
276
- action :delete do
277
- ruby_block "lxc stop[#{new_resource.name}]" do
238
+ ruby_block "lxc install_chef[#{new_resource.name}]" do
278
239
  block do
279
- new_resource._lxc.stop
240
+ _lxc.container_command('bash /opt/chef-install.sh')
280
241
  end
242
+ action :create
281
243
  only_if do
282
- new_resource._lxc.running?
244
+ new_resource.chef_enabled &&
245
+ !_lxc.rootfs.join('usr/bin/chef-client').exist? &&
246
+ _lxc.rootfs.join('opt/chef-install.sh').exist?
283
247
  end
284
248
  end
285
-
286
- execute "lxc delete[#{new_resource.name}]" do
287
- command "lxc-destroy -n #{new_resource.name}"
288
- only_if do
289
- new_resource._lxc.exists? && new_resource.updated_by_last_action(true)
290
- end
249
+
250
+ #### Setup chef related bits within container
251
+ directory @lxc.rootfs.join('etc/chef').to_path do
252
+ action :create
253
+ mode 0755
254
+ only_if{ new_resource.chef_enabled }
255
+ end
256
+
257
+ template "lxc chef-config[#{new_resource.name}]" do
258
+ source 'client.rb.erb'
259
+ cookbook 'lxc'
260
+ path _lxc.rootfs.join('etc/chef/client.rb').to_path
261
+ variables(
262
+ :validation_client => new_resource.validation_client || Chef::Config[:validation_client_name],
263
+ :node_name => new_resource.node_name || "#{node.name}-#{new_resource.name}",
264
+ :server_uri => new_resource.server_uri || Chef::Config[:chef_server_url],
265
+ :chef_environment => new_resource.chef_environment || '_default'
266
+ )
267
+ mode 0644
268
+ only_if{ new_resource.chef_enabled }
291
269
  end
292
- end
293
270
 
294
- action :clone do
295
- execute "lxc clone[#{new_resource.base_container} -> #{new_resource.name}]" do
296
- command "lxc-clone -o #{new_resource.base_container} -n #{new_resource.name}"
271
+ file "lxc chef-validator[#{new_resource.name}]" do
272
+ path _lxc.rootfs.join('etc/chef/validator.pem').to_path
273
+ content new_resource.validator_pem || node[:lxc][:validator_pem]
274
+ mode 0600
275
+ only_if{ new_resource.chef_enabled && !_lxc.rootfs.join('etc/chef/client.pem').exist? }
276
+ end
277
+
278
+ file "lxc chef-runlist[#{new_resource.name}]" do
279
+ path _lxc.rootfs.join('etc/chef/first_run.json').to_path
280
+ content({:run_list => new_resource.run_list}.to_json)
297
281
  only_if do
298
- !new_resource._lxc.exists? && new_resource.updated_by_last_action(true)
282
+ new_resource.chef_enabled && !_lxc.rootfs.join('etc/chef/client.pem').exist?
299
283
  end
284
+ mode 0644
300
285
  end
301
286
 
302
- lxc_service "lxc config_restart[#{new_resource.name}]" do
303
- service_name new_resource.name
304
- action :nothing
287
+ file "lxc chef-data-bag-secret[#{new_resource.name}]" do
288
+ path _lxc.rootfs.join('etc/chef/encrypted_data_bag_secret').to_path
289
+ content(
290
+ ::File.exists?(new_resource.data_bag_secret_file) ? ::File.open(new_resource.data_bag_secret_file, "rb").read : ''
291
+ )
292
+ mode 0600
305
293
  only_if do
306
- new_resource._lxc.running?
294
+ new_resource.chef_enabled &&
295
+ new_resource.copy_data_bag_secret_file &&
296
+ ::File.exists?(new_resource.copy_data_bag_secret_file)
307
297
  end
308
298
  end
309
299
 
310
- lxc_config new_resource.name do
311
- action :create
312
- notifies :restart, resources(:lxc_service => "lxc config_restart[#{new_resource.name}]"), :immediately
300
+ #### Let chef configure the container
301
+ # NOTE: We run chef-client if the validator.pem exists and the
302
+ # client.pem file does not exist.
303
+ ruby_block "lxc run_chef[#{new_resource.name}]" do
304
+ block do
305
+ cmd = 'chef-client -K /etc/chef/validator.pem -c /etc/chef/client.rb -j /etc/chef/first_run.json'
306
+ Chef::Log.info "Running command on #{new_resource.name}: #{cmd}"
307
+ _lxc.container_command(cmd, new_resource.chef_retries)
308
+ end
309
+ only_if do
310
+ new_resource.chef_enabled &&
311
+ _lxc.rootfs.join('etc/chef/validator.pem').exist? &&
312
+ !_lxc.rootfs.join('etc/chef/client.pem').exist?
313
+ end
313
314
  end
314
-
315
- if(new_resource.chef_enabled)
316
- ruby_block "lxc start[#{new_resource.name}]" do
317
- block do
318
- new_resource._lxc.start
315
+
316
+ #### Have commands for the container? Run them now
317
+ ruby_block "lxc container_commands[#{new_resource.name}]" do
318
+ block do
319
+ new_resource.container_commands.each do |cmd|
320
+ _lxc.container_command(cmd, 2)
319
321
  end
320
- action :nothing
321
- subscribes :create, resources(:execute => "lxc clone[#{new_resource.base_container} -> #{new_resource.name}]"), :immediately
322
322
  end
323
+ not_if do
324
+ new_resource.container_commands.empty?
325
+ end
326
+ end
323
327
 
324
- ruby_block "lxc run_chef[#{new_resource.name}]" do
325
- block do
326
- new_resource._lxc.container_command(
327
- "chef-client -K /etc/chef/validator.pem -c /etc/chef/client.rb -j /etc/chef/first_run.json", 3
328
- )
329
- end
330
- action :nothing
331
- subscribes :create, resources(:execute => "lxc clone[#{new_resource.base_container} -> #{new_resource.name}]"), :immediately
328
+ # NOTE: If the container was not running before we started, make
329
+ # sure we leave it in a stopped state
330
+ ruby_block "lxc shutdown[#{new_resource.name}]" do
331
+ block do
332
+ _lxc.shutdown
332
333
  end
333
-
334
- ruby_block "lxc shutdown[#{new_resource.name}]" do
335
- block do
336
- new_resource._lxc.shutdown
337
- end
338
- action :nothing
339
- subscribes :create, resources(:execute => "lxc clone[#{new_resource.base_container} -> #{new_resource.name}]"), :immediately
334
+ only_if do
335
+ stopped_end_state && _lxc.running?
340
336
  end
341
337
  end
338
+
339
+ #### Clean up after chef if it's enabled
340
+ file @lxc.rootfs.join('etc/chef/first_run.json').to_path do
341
+ action :delete
342
+ end
343
+
344
+ file @lxc.rootfs.join('etc/chef/validator.pem').to_path do
345
+ action :delete
346
+ end
347
+
348
+ end
349
+
350
+ action :delete do
351
+ lxc new_resource.name do
352
+ action :delete
353
+ end
342
354
  end