cucumber-chef 2.1.0.rc.2 → 2.1.0.rc.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,9 +46,9 @@ Gem::Specification.new do |s|
46
46
  s.add_dependency("rspec", ">= 2.10.0")
47
47
 
48
48
  # Support
49
- s.add_dependency("thor", ">= 0.15.2")
50
49
  s.add_dependency("mixlib-config", ">= 1.1.2")
51
50
  s.add_dependency("rake", ">= 0.9.2")
51
+ s.add_dependency("thor", ">= 0.15.2")
52
52
  s.add_dependency("ubuntu_ami", ">= 0.4.0")
53
53
  s.add_dependency("ztk", ">= 0.0.15")
54
54
 
data/lib/cucumber/chef.rb CHANGED
@@ -19,10 +19,11 @@
19
19
  #
20
20
  ################################################################################
21
21
 
22
- require 'drb/drb'
22
+ require 'drb'
23
23
  require 'readline'
24
24
  require 'socket'
25
25
  require 'stringio'
26
+ require 'benchmark'
26
27
 
27
28
  ################################################################################
28
29
 
@@ -46,7 +47,6 @@ module Cucumber
46
47
 
47
48
  class Error < StandardError; end
48
49
 
49
- autoload :Bootstrap, 'cucumber/chef/bootstrap'
50
50
  autoload :Config, 'cucumber/chef/config'
51
51
  autoload :Provider, 'cucumber/chef/provider'
52
52
  autoload :Provisioner, 'cucumber/chef/provisioner'
@@ -162,27 +162,35 @@ module Cucumber
162
162
 
163
163
  ################################################################################
164
164
 
165
- mode :user
166
- prerelease (Cucumber::Chef.is_rc? ? true : false)
165
+ mode :user
166
+ prerelease (Cucumber::Chef.is_rc? ? true : false)
167
167
 
168
- provider :vagrant
169
- librarian_chef false
168
+ provider :vagrant
169
+ librarian_chef false
170
170
 
171
- user (ENV['OPSCODE_USER'] || ENV['USER'])
171
+ user (ENV['OPSCODE_USER'] || ENV['USER'])
172
172
 
173
- artifacts ({"chef-client-log" => "/var/log/chef/client.log",
174
- "chef-client-stacktrace" => "/var/chef/cache/chef-stacktrace.out"})
173
+ artifacts ({"chef-client-log" => "/var/log/chef/client.log",
174
+ "chef-client-stacktrace" => "/var/chef/cache/chef-stacktrace.out"})
175
175
 
176
- aws ({:lab_user => "ubuntu",
177
- :lxc_user => "root",
178
- :ubuntu_release => "precise",
179
- :aws_instance_arch => "i386",
180
- :aws_instance_disk_store => "ebs",
181
- :aws_instance_type => "m1.small",
182
- :aws_security_group => "cucumber-chef"})
176
+ aws ({:lab_user => "ubuntu",
177
+ :lxc_user => "root",
178
+ :ubuntu_release => "precise",
179
+ :aws_instance_arch => "i386",
180
+ :aws_instance_disk_store => "ebs",
181
+ :aws_instance_type => "m1.small",
182
+ :aws_security_group => "cucumber-chef"})
183
183
 
184
- vagrant ({:lab_user => "vagrant",
185
- :lxc_user => "root"})
184
+ vagrant ({:lab_user => "vagrant",
185
+ :lxc_user => "root"})
186
+
187
+ chef ({:amqp_password => "p@ssw0rd1",
188
+ :admin_password => "p@ssw0rd1"})
189
+
190
+ test_lab ({:hostname => "cucumber-chef",
191
+ :tld => "test-lab"})
192
+
193
+ command_timeout (60 * 30)
186
194
 
187
195
  ################################################################################
188
196
 
@@ -26,8 +26,6 @@ module Cucumber
26
26
  # definitions.
27
27
  module Helpers
28
28
 
29
- require 'benchmark'
30
-
31
29
  require 'cucumber/chef/helpers/chef_client'
32
30
  require 'cucumber/chef/helpers/chef_server'
33
31
  require 'cucumber/chef/helpers/command'
@@ -33,7 +33,7 @@ module Cucumber::Chef::Helpers::ChefClient
33
33
  :ssl_verify_mode => :verify_none,
34
34
  :environment => nil # use default; i.e. set no value
35
35
  }).merge(config)
36
- log("setting chef client config $#{@chef_client_config.inspect}$")
36
+ logger.info { "Setting chef client config '#{@chef_client_config.inspect}'." }
37
37
 
38
38
  true
39
39
  end
@@ -42,27 +42,33 @@ module Cucumber::Chef::Helpers::ChefClient
42
42
 
43
43
  # call this before chef_run_client
44
44
  def chef_set_client_attributes(name, attributes={})
45
- @servers[name] ||= Hash.new
46
- @servers[name][:chef_client] = (@servers[name][:chef_client] || {}).merge(attributes) { |k,o,n| (k = (o + n).uniq) }
47
- log("setting chef client attributes to $#{@servers[name][:chef_client].inspect}$ for container $#{name}$")
45
+ @containers[name] ||= Hash.new
46
+ @containers[name][:chef_client] = (@containers[name][:chef_client] || {}).merge(attributes) { |k,o,n| (k = (o + n).uniq) }
47
+ logger.info { "Setting chef client attributes to '#{@containers[name][:chef_client].inspect}' for container '#{name}'." }
48
48
 
49
49
  true
50
50
  end
51
51
 
52
52
  ################################################################################
53
53
 
54
- def chef_run_client(name,*args)
54
+ def chef_run_client(name, *args)
55
55
  chef_config_client(name)
56
- log("removing artifacts #{Cucumber::Chef::Config[:artifacts].values.collect{|z| "$#{z}$" }.join(' ')}")
57
- (command_run_remote(name, "/bin/rm -fv #{Cucumber::Chef::Config[:artifacts].values.join(' ')}") rescue nil)
58
56
 
59
- log("running chef client on container $#{name}$")
57
+ logger.info { "Removing artifacts #{Cucumber::Chef::Config[:artifacts].values.collect{|z| "'#{z}'" }.join(' ')}." }
58
+ (command_run_chroot(name, "/bin/rm -fv #{Cucumber::Chef::Config[:artifacts].values.join(' ')}") rescue nil)
59
+
60
+ logger.info { "Running chef client on container '#{name}'." }
61
+
62
+ arguments = {
63
+ "--json-attributes" => File.join("/etc", "chef", "attributes.json").to_s,
64
+ "--log_level" => (ENV['LOG_LEVEL'] || "INFO").downcase
65
+ }.reject{ |k,v| v.nil? }.sort
60
66
 
61
67
  output = nil
62
68
  bm = ::Benchmark.realtime do
63
- output = command_run_remote(name, ["/usr/bin/chef-client --json-attributes /etc/chef/attributes.json --node-name #{name}", args].flatten.join(" "))
69
+ output = command_run_chroot(name, ["/usr/bin/chef-client", arguments, args].flatten.join(" "))
64
70
  end
65
- log("chef client run on container $#{name}$ took %0.4f seconds" % bm)
71
+ logger.info { "Chef client run on container '#{name}' took %0.4f seconds." % bm }
66
72
 
67
73
  output
68
74
  end
@@ -90,7 +96,7 @@ module Cucumber::Chef::Helpers::ChefClient
90
96
  attributes_json = File.join("/", container_root(name), "etc", "chef", "attributes.json")
91
97
  FileUtils.mkdir_p(File.dirname(attributes_json))
92
98
  File.open(attributes_json, 'w') do |f|
93
- f.puts((@servers[name][:chef_client] || {}).to_json)
99
+ f.puts((@containers[name][:chef_client] || {}).to_json)
94
100
  end
95
101
 
96
102
  # make sure our log location is there
@@ -108,16 +114,7 @@ module Cucumber::Chef::Helpers::ChefClient
108
114
  # this is messy and needs to be refactored into a more configurable
109
115
  # solution; but for now this should do the trick
110
116
 
111
- ssh = ZTK::SSH.new
112
-
113
- ssh.config.proxy_host_name = $test_lab.ip
114
- ssh.config.proxy_port = $test_lab.port
115
- ssh.config.proxy_user = Cucumber::Chef.lab_user
116
- ssh.config.proxy_keys = Cucumber::Chef.lab_identity
117
-
118
- ssh.config.host_name = name
119
- ssh.config.user = Cucumber::Chef.lxc_user
120
- ssh.config.keys = Cucumber::Chef.lxc_identity
117
+ ssh = $test_lab.proxy_ssh(name)
121
118
 
122
119
  feature_file = $scenario.file_colon_line.split(":").first
123
120
  feature_line = $scenario.file_colon_line.split(":").last
@@ -129,9 +126,9 @@ module Cucumber::Chef::Helpers::ChefClient
129
126
  Cucumber::Chef::Config[:artifacts].each do |label, remote_path|
130
127
  result = ssh.exec("/bin/bash -c '[[ -f #{remote_path} ]] ; echo $?'", :silence => true)
131
128
  if (result.output =~ /0/)
132
- log("retrieving artifact $#{remote_path}$ from container $#{name}$")
129
+ logger.info { "Retrieving artifact '#{remote_path}' from container '#{name}'." }
133
130
 
134
- local_path = File.join(Cucumber::Chef.locate(:directory, ".cucumber-chef"), "artifacts", feature_dir, "#{feature_name}.txt")
131
+ local_path = File.join(Cucumber::Chef.artifacts_dir, feature_dir, "#{feature_name}.txt")
135
132
  tmp_path = File.join("/tmp", label)
136
133
 
137
134
  FileUtils.mkdir_p(File.dirname(local_path))
@@ -25,14 +25,14 @@ module Cucumber::Chef::Helpers::ChefServer
25
25
 
26
26
  def chef_server_node_destroy(name)
27
27
  (::Chef::Node.load(name).destroy rescue nil)
28
- log("destroyed chef node $#{name}$")
28
+ logger.info { "Destroyed chef node '#{name}'." }
29
29
  end
30
30
 
31
31
  ################################################################################
32
32
 
33
33
  def chef_server_client_destroy(name)
34
34
  (::Chef::ApiClient.load(name).destroy rescue nil)
35
- log("destroyed chef client $#{name}$")
35
+ logger.info { "Destroyed chef client '#{name}'." }
36
36
  end
37
37
 
38
38
  ################################################################################
@@ -45,7 +45,7 @@ module Cucumber::Chef::Helpers::ChefServer
45
45
  cookbook_repo.each do |name, cbook|
46
46
  next if name != cookbook
47
47
  ::Chef::CookbookUploader.new(cbook, cookbook_path, :force => true).upload_cookbooks
48
- log("uploaded chef cookbook $#{cookbook}$ from $#{cookbook_path}$")
48
+ logger.info { "Uploaded chef cookbook '#{cookbook}' from '#{cookbook_path}'." }
49
49
  end
50
50
  end
51
51
 
@@ -59,7 +59,7 @@ module Cucumber::Chef::Helpers::ChefServer
59
59
  ::Chef::Config[:role_path] = expanded_role_path
60
60
  role = ::Chef::Role.from_disk(role)
61
61
  role.save
62
- log("updated chef role $#{role}$ from $#{role_path}$")
62
+ logger.info { "Updated chef role '#{role}' from '#{role_path}'." }
63
63
  end
64
64
 
65
65
  ################################################################################
@@ -100,7 +100,7 @@ module Cucumber::Chef::Helpers::ChefServer
100
100
  items.each do |item|
101
101
  next if File.directory?(item)
102
102
 
103
- item_name = %w( json rb ).collect{ |ext| (item =~ /#{ext}/ ? File.basename(item, ".#{ext}") : nil) }.compact.first
103
+ item_name = %w(json rb).collect{ |ext| (item =~ /#{ext}/ ? File.basename(item, ".#{ext}") : nil) }.compact.first
104
104
  item_path = File.basename(item)
105
105
  databag_item_path = File.expand_path(File.join(databag_path, item_path))
106
106
 
@@ -113,10 +113,10 @@ module Cucumber::Chef::Helpers::ChefServer
113
113
  loop do
114
114
  chef_data = ::Chef::DataBagItem.load(databag, item_name).raw_data
115
115
  break if chef_data == raw_data
116
- log("waiting on chef data bag to update")
116
+ logger.info { "Waiting on chef data bag to update; sleeping 1 second." }
117
117
  sleep(1)
118
118
  end
119
- log("updated chef data bag item $#{databag}/#{item_path}$ from $#{databag_path}$")
119
+ logger.info { "Updated chef data bag item '#{databag}/#{item_path}' from '#{databag_path}'." }
120
120
  end
121
121
  end
122
122
 
@@ -23,47 +23,34 @@ module Cucumber::Chef::Helpers::Command
23
23
 
24
24
  ################################################################################
25
25
 
26
- def command_run_remote(name, command, expected_exit_code=0)
27
- command = %Q(ssh -i #{File.join(Cucumber::Chef.lab_user_home_dir, ".ssh", "id_rsa")} #{name} #{command} 2>&1)
28
- logger.info { "command_run_remote(#{command})" }
29
- output = %x(#{command})
30
- if !expected_exit_code.nil? && ($? != expected_exit_code)
31
- message = "command_run_remote(#{command}) failed (code=#{$?},output='#{output.chomp}')"
32
- logger.fatal { message }
33
- logger.fatal { "output(#{output.chomp})" }
34
- raise message
35
- end
36
- output
26
+ def command_run_remote(name, command, options={})
27
+ expected_exit_code = (options[:expected_exit_code] || 0)
28
+ options.reject!{ |k,v| k == :expected_exit_code }
29
+
30
+ identity_file = File.join(Cucumber::Chef.lab_user_home_dir, ".ssh", "id_rsa")
31
+
32
+ command = %W(/usr/bin/ssh #{ENV['LOG_LEVEL'] == 'DEBUG' ? "-v" : nil} -i #{identity_file} #{name} #{command})
33
+ ::ZTK::Command.new({:timeout => Cucumber::Chef::Config.command_timeout}.merge(options)).exec(command.compact.join(" "), :silence => true, :exit_code => expected_exit_code)
37
34
  end
38
35
 
39
36
  ################################################################################
40
37
 
41
- def command_run_chroot(name, command, expected_exit_code=0)
42
- command = %Q(chroot #{container_root(name)} /bin/bash -c '#{command.gsub("'", '"')}' 2>&1)
43
- logger.info { "command_run_chroot(#{command})" }
44
- output = %x(#{command})
45
- if !expected_exit_code.nil? && ($? != expected_exit_code)
46
- message = "command_run_chroot(#{command}) failed (#{$?})"
47
- logger.fatal { message }
48
- logger.fatal { "output(#{output.chomp})" }
49
- raise message
50
- end
51
- output
38
+ def command_run_chroot(name, command, options={})
39
+ expected_exit_code = (options[:expected_exit_code] || 0)
40
+ options.reject!{ |k,v| k == :expected_exit_code }
41
+
42
+ command = %Q(/usr/sbin/chroot #{container_root(name)} /bin/bash -c '#{command.gsub("'", '"')}')
43
+ ::ZTK::Command.new({:timeout => Cucumber::Chef::Config.command_timeout}.merge(options)).exec(command, :silence => true, :exit_code => expected_exit_code)
52
44
  end
53
45
 
54
46
  ################################################################################
55
47
 
56
- def command_run_local(command, expected_exit_code=0)
57
- command = %Q(/bin/bash -c '#{command.gsub("'", '"')}' 2>&1)
58
- logger.info { "command_run_local(#{command})" }
59
- output = %x(#{command})
60
- if !expected_exit_code.nil? && ($? != expected_exit_code)
61
- message = "command_run_local(#{command}) failed (#{$?})"
62
- logger.fatal { message }
63
- logger.fatal { "output(#{output.chomp})" }
64
- raise message
65
- end
66
- output
48
+ def command_run_local(command, options={})
49
+ expected_exit_code = (options[:expected_exit_code] || 0)
50
+ options.reject!{ |k,v| k == :expected_exit_code }
51
+
52
+ command = %Q(/bin/bash -c '#{command.gsub("'", '"')}')
53
+ ::ZTK::Command.new({:timeout => Cucumber::Chef::Config.command_timeout}.merge(options)).exec(command, :silence => true, :exit_code => expected_exit_code)
67
54
  end
68
55
 
69
56
  ################################################################################
@@ -21,18 +21,46 @@
21
21
 
22
22
  module Cucumber::Chef::Helpers::Container
23
23
 
24
+ ################################################################################
25
+
26
+ def load_containers
27
+ logger.debug { "Reading '#{Cucumber::Chef.containers_bin}'." }
28
+ @containers = ((Marshal.load(IO.read(Cucumber::Chef.containers_bin)) rescue Hash.new) || Hash.new)
29
+
30
+ logger.info { "-" * 8 }
31
+ @containers.each do |key, value|
32
+ logger.info { "LOAD CONTAINER: #{key.inspect} => #{value.inspect}" }
33
+ end
34
+ end
35
+
36
+ ################################################################################
37
+
38
+ def save_containers
39
+ logger.debug { "Writing '#{Cucumber::Chef.containers_bin}'." }
40
+ logger.info { "-" * 8 }
41
+ @containers.each do |key, value|
42
+ logger.info { "SAVE CONTAINER: #{key.inspect} => #{value.inspect}" }
43
+ end
44
+
45
+ File.open(Cucumber::Chef.containers_bin, 'w') do |f|
46
+ f.puts(Marshal.dump(@containers))
47
+ end
48
+ end
49
+
24
50
  ################################################################################
25
51
 
26
52
  def container_create(name, distro, release, arch)
27
53
  unless container_exists?(name)
28
54
  cache_rootfs = container_cache_root(name, distro, release, arch)
29
55
  if !File.exists?(cache_rootfs)
30
- log("$#{name}$ has triggered building the lxc file cache for $#{distro}$")
31
- log("this one time process per distro can take up to 10 minutes or longer depending on the test lab")
56
+ logger.warn { "'#{name}' has triggered building the lxc file cache for '#{distro}'." }
57
+ logger.warn { "This one time process per distro can take up to 10 minutes or longer depending on the test lab." }
32
58
  end
33
59
 
34
60
  command_run_local(container_create_command(name, distro, release, arch))
35
61
 
62
+ commands = Array.new
63
+
36
64
  # install omnibus into the distro/release file cache if it's not already there
37
65
  omnibus_chef_client = File.join("/", "opt", "chef", "bin", "chef-client")
38
66
  omnibus_cache = File.join(cache_rootfs, omnibus_chef_client)
@@ -40,27 +68,32 @@ module Cucumber::Chef::Helpers::Container
40
68
  if !File.exists?(omnibus_cache)
41
69
  case distro.downcase
42
70
  when "ubuntu" then
43
- command_run_local("chroot #{cache_rootfs} /bin/bash -c 'apt-get -y --force-yes install wget'")
71
+ commands << "chroot #{cache_rootfs} /bin/bash -c 'apt-get -y --force-yes install wget'"
44
72
  when "fedora" then
45
- command_run_local("yum --nogpgcheck --installroot=#{cache_rootfs} -y install wget openssh-server")
73
+ commands << "yum --nogpgcheck --installroot=#{cache_rootfs} -y install wget openssh-server"
46
74
  end
47
- command_run_local("chroot #{cache_rootfs} /bin/bash -c 'wget http://www.opscode.com/chef/install.sh -O - | bash'")
75
+ commands << "chroot #{cache_rootfs} /bin/bash -c 'locale-gen en_US'"
76
+ commands << "chroot #{cache_rootfs} /bin/bash -c 'wget http://www.opscode.com/chef/install.sh -O - | bash'"
48
77
  if distro.downcase == "fedora"
49
- command_run_local("chroot #{cache_rootfs} /bin/bash -c 'rpm -Uvh --nodeps /tmp/*rpm'")
78
+ commands << "chroot #{cache_rootfs} /bin/bash -c 'rpm -Uvh --nodeps /tmp/*rpm'"
50
79
  end
51
- command_run_local("lxc-destroy -n #{name}")
52
- command_run_local(container_create_command(name, distro, release, arch))
80
+ commands << "lxc-destroy -n #{name}"
81
+ commands << container_create_command(name, distro, release, arch)
53
82
  end
54
83
 
55
- command_run_local("mkdir -p #{File.join(container_root(name), Cucumber::Chef.lxc_user_home_dir, ".ssh")}")
56
- command_run_local("chmod 0755 #{File.join(container_root(name), Cucumber::Chef.lxc_user_home_dir, ".ssh")}")
57
- command_run_local("cat #{File.join(Cucumber::Chef.lab_user_home_dir, ".ssh", "id_rsa.pub")} | tee -a #{File.join(container_root(name), Cucumber::Chef.lxc_user_home_dir, ".ssh", "authorized_keys")}")
84
+ commands << <<-EOH
85
+ mkdir -vp #{File.join(container_root(name), Cucumber::Chef.lxc_user_home_dir, ".ssh")}
86
+ chmod 0700 #{File.join(container_root(name), Cucumber::Chef.lxc_user_home_dir, ".ssh")}
87
+ cat #{File.join(Cucumber::Chef.lab_user_home_dir, ".ssh", "id_rsa.pub")} | tee -a #{File.join(container_root(name), Cucumber::Chef.lxc_user_home_dir, ".ssh", "authorized_keys")}
88
+
89
+ rm -vf #{File.join(container_root(name), "etc", "motd")}
90
+ cp -v /etc/motd #{File.join(container_root(name), "etc", "motd")}
91
+ echo ' You are now logged in to the "#{name}" container!\n' | tee -a #{File.join(container_root(name), "etc", "motd")}
92
+ echo '127.0.0.1 #{name}.#{Cucumber::Chef::Config.test_lab[:tld]} #{name}' | tee -a #{File.join(container_root(name), "etc", "hosts")}
93
+ echo '#{name}.test-lab' | tee #{File.join(container_root(name), "etc", "hostname")}
94
+ EOH
58
95
 
59
- command_run_local("rm -f #{container_root(name)}/etc/motd")
60
- command_run_local("cp /etc/motd #{container_root(name)}/etc/motd")
61
- command_run_local("echo ' You are now logged in to the #{name} container!\n' >> #{container_root(name)}/etc/motd")
62
- command_run_local("sed -i 's/localhost #{name}/#{name}.test-lab #{name} localhost/' #{container_root(name)}/etc/hosts")
63
- command_run_local("echo '#{name}.test-lab' | tee #{container_root(name)}/etc/hostname")
96
+ command_run_local(commands.join("\n"))
64
97
  end
65
98
  container_start(name)
66
99
  end
@@ -71,21 +104,21 @@ module Cucumber::Chef::Helpers::Container
71
104
  chef_server_client_destroy(name)
72
105
  container_stop(name)
73
106
  command_run_local("lxc-destroy -n #{name}")
74
- log("destroyed container $#{name}$")
107
+ logger.info { "Destroyed container '#{name}'." }
75
108
  end
76
109
  end
77
110
 
78
111
  ################################################################################
79
112
 
80
113
  def container_start(name)
81
- status = command_run_local("lxc-info -n #{name}")
114
+ status = command_run_local("lxc-info -n #{name}").output
82
115
  if status.include?("STOPPED")
83
116
  command_run_local("lxc-start -d -n #{name}")
84
117
  end
85
118
  end
86
119
 
87
120
  def container_stop(name)
88
- status = command_run_local("lxc-info -n #{name}")
121
+ status = command_run_local("lxc-info -n #{name}").output
89
122
  if status.include?("RUNNING")
90
123
  command_run_local("lxc-stop -n #{name}")
91
124
  end
@@ -94,7 +127,7 @@ module Cucumber::Chef::Helpers::Container
94
127
  ################################################################################
95
128
 
96
129
  def container_running?(name)
97
- status = command_run_local("lxc-info -n #{name}")
130
+ status = command_run_local("lxc-info -n #{name}").output
98
131
  status.include?("RUNNING")
99
132
  end
100
133
 
@@ -109,7 +142,7 @@ module Cucumber::Chef::Helpers::Container
109
142
  f.puts("lxc.network.flags = up")
110
143
  f.puts("lxc.network.link = br0")
111
144
  f.puts("lxc.network.name = eth0")
112
- f.puts("lxc.network.hwaddr = #{@servers[name][:mac]}")
145
+ f.puts("lxc.network.hwaddr = #{@containers[name][:mac]}")
113
146
  f.puts("lxc.network.ipv4 = 0.0.0.0")
114
147
  end
115
148
  end
@@ -140,7 +173,7 @@ module Cucumber::Chef::Helpers::Container
140
173
  def container_create_command(name, distro, release, arch)
141
174
  case distro.downcase
142
175
  when "ubuntu" then
143
- "lxc-create -n #{name} -f /etc/lxc/#{name} -t #{distro} -- --release #{release} --arch #{arch}"
176
+ "DEBIAN_FRONTEND=noninteractive lxc-create -n #{name} -f /etc/lxc/#{name} -t #{distro} -- --release #{release} --arch #{arch}"
144
177
  when "fedora" then
145
178
  "lxc-create -n #{name} -f /etc/lxc/#{name} -t #{distro} -- --release #{release}"
146
179
  end