testlab 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/README.md +1 -1
  2. data/bin/tl +5 -3
  3. data/features/support/Labfile.local +2 -8
  4. data/features/support/Labfile.vagrant +2 -5
  5. data/lib/testlab/container/actions.rb +1 -41
  6. data/lib/testlab/container/clone.rb +87 -0
  7. data/lib/testlab/container/configuration.rb +67 -0
  8. data/lib/testlab/container/io.rb +8 -8
  9. data/lib/testlab/container/lifecycle.rb +0 -40
  10. data/lib/testlab/container/lxc.rb +0 -143
  11. data/lib/testlab/container/provision.rb +49 -0
  12. data/lib/testlab/container/support.rb +47 -0
  13. data/lib/testlab/container.rb +10 -0
  14. data/lib/testlab/network/actions.rb +4 -4
  15. data/lib/testlab/network/lifecycle.rb +0 -28
  16. data/lib/testlab/network/provision.rb +37 -0
  17. data/lib/testlab/network/status.rb +2 -2
  18. data/lib/testlab/network.rb +2 -0
  19. data/lib/testlab/node/lifecycle.rb +0 -26
  20. data/lib/testlab/node/lxc.rb +1 -13
  21. data/lib/testlab/node/provision.rb +34 -0
  22. data/lib/testlab/node.rb +4 -0
  23. data/lib/testlab/provisioners/apt.rb +1 -0
  24. data/lib/testlab/provisioners/apt_cacher_ng.rb +5 -5
  25. data/lib/testlab/provisioners/bind.rb +35 -18
  26. data/lib/testlab/provisioners/chef/omni_bus.rb +3 -3
  27. data/lib/testlab/provisioners/chef/ruby_gem_client.rb +3 -3
  28. data/lib/testlab/provisioners/resolv.rb +14 -6
  29. data/lib/testlab/provisioners/route.rb +5 -2
  30. data/lib/testlab/provisioners/templates/apt/provision.erb +3 -0
  31. data/lib/testlab/provisioners/templates/bind/bind.erb +5 -2
  32. data/lib/testlab/provisioners/templates/raring/provision.erb +13 -10
  33. data/lib/testlab/provisioners/templates/resolv/resolv.conf.erb +4 -2
  34. data/lib/testlab/support/execution.rb +46 -0
  35. data/lib/testlab/support.rb +17 -0
  36. data/lib/testlab/user/lifecycle.rb +6 -6
  37. data/lib/testlab/utility/gli.rb +3 -3
  38. data/lib/testlab/utility/misc.rb +8 -0
  39. data/lib/testlab/version.rb +1 -1
  40. data/lib/testlab.rb +1 -0
  41. metadata +10 -8
data/README.md CHANGED
@@ -209,7 +209,7 @@ Calling `TestLab.new` without a `:labfile` option will, by default, attempt to r
209
209
  There are several easy accessors available to grab the first container and execute the command `uptime` on it via and SSH connection:
210
210
 
211
211
  container = @testlab.containers.first
212
- container.ssh.exec(%(uptime))
212
+ container.exec(%(uptime))
213
213
 
214
214
  We can also execute this command via `lxc-attach`:
215
215
 
data/bin/tl CHANGED
@@ -101,9 +101,11 @@ end
101
101
  post do |global,command,options,args|
102
102
  testlab_run_time = (Time.now.utc - @testlab_start_time)
103
103
 
104
- message = format_message("TestLab v#{TestLab::VERSION} Finished (%0.4f seconds)".black.bold % testlab_run_time)
105
- @testlab.ui.stdout.puts(message)
106
- @testlab.ui.logger.info { message }
104
+ if !@ui.quiet?
105
+ message = format_message("TestLab v#{TestLab::VERSION} Finished (%0.4f seconds)".black.bold % testlab_run_time)
106
+ @testlab.ui.stdout.puts(message)
107
+ @testlab.ui.logger.info { message }
108
+ end
107
109
 
108
110
  true
109
111
  end
@@ -12,19 +12,13 @@ node 'vagrant' do
12
12
  TestLab::Provisioner::Resolv
13
13
  ]
14
14
 
15
- config ({
16
- :bind => {
17
- :domain => "default.zone"
18
- }
19
- })
20
-
21
15
  network 'labnet' do
22
16
  provisioners [
23
17
  TestLab::Provisioner::Bind
24
18
  ]
25
19
 
26
20
  address '10.128.0.1/16'
27
- bridge :br_test
21
+ bridge 'br_test'
28
22
  end
29
23
 
30
24
  container "test-server" do
@@ -48,7 +42,7 @@ node 'vagrant' do
48
42
 
49
43
  interface do
50
44
  network_id 'labnet'
51
- name :eth0
45
+ name 'eth0'
52
46
  address '10.128.0.254/16'
53
47
  mac '00:00:5e:63:b5:9f'
54
48
  end
@@ -20,9 +20,6 @@ node 'vagrant' do
20
20
  :box => 'raring64',
21
21
  :box_url => 'https://dl.dropboxusercontent.com/u/22904185/boxes/raring64.box',
22
22
  :file => File.dirname(__FILE__)
23
- },
24
- :bind => {
25
- :domain => "default.zone"
26
23
  }
27
24
  })
28
25
 
@@ -32,7 +29,7 @@ node 'vagrant' do
32
29
  ]
33
30
 
34
31
  address '10.128.0.1/16'
35
- bridge :br0
32
+ bridge 'br0'
36
33
  end
37
34
 
38
35
  container "test-server" do
@@ -56,7 +53,7 @@ node 'vagrant' do
56
53
 
57
54
  interface do
58
55
  network_id 'labnet'
59
- name :eth0
56
+ name 'eth0'
60
57
  address '10.128.0.254/16'
61
58
  mac '00:00:5e:63:b5:9f'
62
59
  end
@@ -72,7 +72,7 @@ class TestLab
72
72
  user.provision
73
73
  end
74
74
 
75
- self.ssh.exec(%(sudo hostname #{self.fqdn}))
75
+ self.exec(%(sudo hostname #{self.fqdn}))
76
76
 
77
77
  do_provisioner_callbacks(self, :up, @ui)
78
78
  end
@@ -102,46 +102,6 @@ class TestLab
102
102
  true
103
103
  end
104
104
 
105
- # Clone the container
106
- #
107
- # Prepares the container, if needed, for ephemeral cloning and clones it.
108
- #
109
- # @return [Boolean] True if successful.
110
- def clone
111
- @ui.logger.debug { "Container Clone: #{self.id}" }
112
-
113
- please_wait(:ui => @ui, :message => format_object_action(self, 'Clone', :yellow)) do
114
-
115
- # ensure our container is in "ephemeral" mode
116
- self.to_ephemeral
117
-
118
- self.node.ssh.exec(%(sudo arp --verbose --delete #{self.ip}), :ignore_exit_status => true)
119
-
120
- ephemeral_arguments = Array.new
121
- ephemeral_arguments << %W(-o #{self.lxc_clone.name} -n #{self.lxc.name} -d)
122
- ephemeral_arguments << %W(--keep-data) if self.persist
123
- ephemeral_arguments.flatten!.compact!
124
-
125
- self.lxc_clone.start_ephemeral(ephemeral_arguments)
126
- end
127
-
128
- true
129
- end
130
-
131
- # Configure the container
132
- #
133
- # Configures the LXC subsystem for the container.
134
- #
135
- # @return [Boolean] True if successful.
136
- def configure
137
- self.domain ||= self.node.domain
138
- self.arch ||= detect_arch
139
-
140
- build_lxc_config(self.lxc.config)
141
-
142
- true
143
- end
144
-
145
105
  end
146
106
 
147
107
  end
@@ -0,0 +1,87 @@
1
+ class TestLab
2
+ class Container
3
+
4
+ module Clone
5
+
6
+ # Clone the container
7
+ #
8
+ # Prepares the container, if needed, for ephemeral cloning and clones it.
9
+ #
10
+ # @return [Boolean] True if successful.
11
+ def clone
12
+ @ui.logger.debug { "Container Clone: #{self.id}" }
13
+
14
+ please_wait(:ui => @ui, :message => format_object_action(self, 'Clone', :yellow)) do
15
+
16
+ # ensure our container is in "ephemeral" mode
17
+ self.to_ephemeral
18
+
19
+ self.node.exec(%(sudo arp --verbose --delete #{self.ip}), :ignore_exit_status => true)
20
+
21
+ self.lxc_clone.start_ephemeral(clone_args)
22
+ end
23
+
24
+ true
25
+ end
26
+
27
+ # LXC::Container object
28
+ #
29
+ # Returns a *LXC::Container* class instance configured for the clone of
30
+ # this container.
31
+ #
32
+ # @return [LXC] An instance of LXC::Container configured for the clone of
33
+ # this container.
34
+ def lxc_clone
35
+ @lxc_clone ||= self.node.lxc.container("#{self.id}-master")
36
+ end
37
+
38
+ # Convert to Static Container
39
+ #
40
+ # If the current container is operating as an ephemeral container, this
41
+ # will convert it back to a static container, otherwise no changes will
42
+ # occur.
43
+ #
44
+ # @return [Boolean] Returns true if successful.
45
+ def to_static
46
+ if self.lxc_clone.exists?
47
+ self.lxc.stop
48
+ self.lxc.destroy(%(-f))
49
+
50
+ self.lxc_clone.stop
51
+ self.lxc_clone.clone(%W(-o #{self.lxc_clone.name} -n #{self.lxc.name}))
52
+ self.lxc_clone.destroy(%(-f))
53
+
54
+ build_lxc_config(self.lxc.config)
55
+ end
56
+
57
+ true
58
+ end
59
+
60
+ # Convert to Ephemeral Container
61
+ #
62
+ # If the current container is operating as a static container, this will
63
+ # convert it to a ephemeral container, otherwise no changes will occur.
64
+ #
65
+ # @return [Boolean] Returns true if successful.
66
+ def to_ephemeral
67
+ if (self.lxc.exists? && !self.lxc_clone.exists?)
68
+ self.lxc_clone.stop
69
+ self.lxc_clone.destroy(%(-f))
70
+
71
+ self.lxc.stop
72
+ self.lxc.clone(%W(-o #{self.lxc.name} -n #{self.lxc_clone.name}))
73
+ self.lxc.destroy(%(-f))
74
+
75
+ build_lxc_config(self.lxc_clone.config)
76
+ else
77
+ self.lxc.stop
78
+ self.persist and self.lxc.destroy(%(-f))
79
+ end
80
+
81
+ true
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,67 @@
1
+ class TestLab
2
+ class Container
3
+
4
+ module Configuration
5
+
6
+ # Configure the container
7
+ #
8
+ # Configures the LXC subsystem for the container.
9
+ #
10
+ # @return [Boolean] True if successful.
11
+ def configure
12
+ self.domain ||= self.node.domain
13
+ self.arch ||= detect_arch
14
+
15
+ build_lxc_config(self.lxc.config)
16
+
17
+ true
18
+ end
19
+
20
+ # LXC Container Configuration
21
+ #
22
+ # Builds the LXC container configuration data.
23
+ #
24
+ # @return [Boolean] True if successful.
25
+ def build_lxc_config(lxc_config)
26
+ lxc_config.clear
27
+
28
+ lxc_config['lxc.arch'] = self.arch
29
+ lxc_config['lxc.utsname'] = self.fqdn
30
+ lxc_config.networks = build_lxc_network_conf(self.interfaces)
31
+
32
+ lxc_config.save
33
+
34
+ true
35
+ end
36
+
37
+ # LXC Network Configuration
38
+ #
39
+ # Builds an array of hashes containing the lxc configuration options for
40
+ # our network interfaces.
41
+ #
42
+ # @return [Array<Hash>] An array of hashes defining the containers
43
+ # interfaces for use in configuring LXC.
44
+ def build_lxc_network_conf(interfaces)
45
+ networks = Array.new
46
+
47
+ interfaces.each do |interface|
48
+ networks << Hash[
49
+ 'lxc.network.type' => :veth,
50
+ 'lxc.network.flags' => :up,
51
+ 'lxc.network.link' => interface.network.bridge,
52
+ 'lxc.network.name' => interface.name,
53
+ 'lxc.network.hwaddr' => interface.mac,
54
+ 'lxc.network.ipv4' => "#{interface.ip}/#{interface.cidr} #{interface.netmask}"
55
+ ]
56
+ if (interface.primary == true) || (interfaces.count == 1)
57
+ networks.last.merge!('lxc.network.ipv4.gateway' => :auto)
58
+ end
59
+ end
60
+
61
+ networks
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+ end
@@ -25,7 +25,7 @@ class TestLab
25
25
  root_fs_path = self.lxc.fs_root.split(File::SEPARATOR).last
26
26
 
27
27
  please_wait(:ui => @ui, :message => format_object_action(self, 'Compress', :cyan)) do
28
- self.node.ssh.bootstrap(<<-EOF)
28
+ self.node.bootstrap(<<-EOF)
29
29
  set -x
30
30
  set -e
31
31
 
@@ -41,7 +41,7 @@ EOF
41
41
 
42
42
  please_wait(:ui => @ui, :message => format_object_action(self, 'Export', :cyan)) do
43
43
  File.exists?(local_file) and FileUtils.rm_f(local_file)
44
- self.node.ssh.download(remote_file, local_file)
44
+ self.node.download(remote_file, local_file)
45
45
  end
46
46
 
47
47
  @ui.stdout.puts
@@ -70,12 +70,12 @@ EOF
70
70
  root_fs_path = self.lxc.fs_root.split(File::SEPARATOR).last
71
71
 
72
72
  please_wait(:ui => @ui, :message => format_object_action(self, 'Import', :cyan)) do
73
- self.node.ssh.exec(%(sudo rm -fv #{remote_file}), :silence => true, :ignore_exit_status => true)
74
- self.node.ssh.upload(local_file, remote_file)
73
+ self.node.exec(%(sudo rm -fv #{remote_file}), :silence => true, :ignore_exit_status => true)
74
+ self.node.upload(local_file, remote_file)
75
75
  end
76
76
 
77
77
  please_wait(:ui => @ui, :message => format_object_action(self, 'Expand', :cyan)) do
78
- self.node.ssh.bootstrap(<<-EOF)
78
+ self.node.bootstrap(<<-EOF)
79
79
  set -x
80
80
  set -e
81
81
 
@@ -117,9 +117,9 @@ EOF
117
117
 
118
118
  self.down
119
119
  please_wait(:ui => @ui, :message => format_object_action(self, 'Copy', :yellow)) do
120
- self.node.ssh.exec(%(sudo rm -rf #{target_container.lxc.fs_root}))
121
- self.node.ssh.exec(%(sudo rsync -a #{self.lxc.fs_root} #{target_container.lxc.container_root}))
122
- self.node.ssh.exec(%(sudo rm -fv #{File.join(self.lxc.fs_root, '.*provision')}))
120
+ self.node.exec(%(sudo rm -rf #{target_container.lxc.fs_root}))
121
+ self.node.exec(%(sudo rsync -a #{self.lxc.fs_root} #{target_container.lxc.container_root}))
122
+ self.node.exec(%(sudo rm -fv #{File.join(self.lxc.fs_root, '.*provision')}))
123
123
  end
124
124
 
125
125
  # bring the source container back online if it was running before the copy operation
@@ -3,46 +3,6 @@ class TestLab
3
3
 
4
4
  module Lifecycle
5
5
 
6
- # Provision the container
7
- #
8
- # Attempts to provision the container. We first create the container,
9
- # then attempt to bring it online. Afterwards the containers provisioner
10
- # is called.
11
- #
12
- # @return [Boolean] True if successful.
13
- def provision
14
- @ui.logger.debug { "Container Provision: #{self.id} " }
15
-
16
- (self.node.state != :running) and return false
17
- (self.state != :running) and return false
18
-
19
- please_wait(:ui => @ui, :message => format_object_action(self, :provision, :green)) do
20
- do_provisioner_callbacks(self, :provision, @ui)
21
- end
22
-
23
- true
24
- end
25
-
26
- # Deprovision the container
27
- #
28
- # Attempts to deprovision the container. We first call the provisioner
29
- # deprovision method defined for the container, if any. Next we attempt
30
- # to offline the container. Afterwards the container is destroy.
31
- #
32
- # @return [Boolean] True if successful.
33
- def deprovision
34
- @ui.logger.debug { "Container Deprovision: #{self.id} " }
35
-
36
- (self.node.state != :running) and return false
37
- (self.state != :running) and return false
38
-
39
- please_wait(:ui => @ui, :message => format_object_action(self, :deprovision, :red)) do
40
- do_provisioner_callbacks(self, :deprovision, @ui)
41
- end
42
-
43
- true
44
- end
45
-
46
6
  # Build the container
47
7
  def build
48
8
  self.create
@@ -3,22 +3,6 @@ class TestLab
3
3
 
4
4
  module LXC
5
5
 
6
- # Container Bootstrap
7
- #
8
- # Renders the supplied content into a file on the container and proceeds
9
- # to execute it on the container as root.
10
- #
11
- # @param [String] content The content to render on the container and
12
- # execute. This is generally a bash script of some sort for example.
13
- # @return [String] The output of respective SSH/LXC bootstrap.
14
- def bootstrap(content, options={})
15
- if self.lxc_clone.exists?
16
- self.ssh.bootstrap(content, options)
17
- else
18
- self.lxc.bootstrap(content)
19
- end
20
- end
21
-
22
6
  # Container Console
23
7
  #
24
8
  # Opens an LXC console into the container.
@@ -41,63 +25,6 @@ class TestLab
41
25
  @lxc ||= self.node.lxc.container(self.id)
42
26
  end
43
27
 
44
- # LXC::Container object
45
- #
46
- # Returns a *LXC::Container* class instance configured for the clone of
47
- # this container.
48
- #
49
- # @return [LXC] An instance of LXC::Container configured for the clone of
50
- # this container.
51
- def lxc_clone
52
- @lxc_clone ||= self.node.lxc.container("#{self.id}-master")
53
- end
54
-
55
- # Convert to Static Container
56
- #
57
- # If the current container is operating as an ephemeral container, this
58
- # will convert it back to a static container, otherwise no changes will
59
- # occur.
60
- #
61
- # @return [Boolean] Returns true if successful.
62
- def to_static
63
- if self.lxc_clone.exists?
64
- self.lxc.stop
65
- self.lxc.destroy(%(-f))
66
-
67
- self.lxc_clone.stop
68
- self.lxc_clone.clone(%W(-o #{self.lxc_clone.name} -n #{self.lxc.name}))
69
- self.lxc_clone.destroy(%(-f))
70
-
71
- build_lxc_config(self.lxc.config)
72
- end
73
-
74
- true
75
- end
76
-
77
- # Convert to Ephemeral Container
78
- #
79
- # If the current container is operating as a static container, this will
80
- # convert it to a ephemeral container, otherwise no changes will occur.
81
- #
82
- # @return [Boolean] Returns true if successful.
83
- def to_ephemeral
84
- if (self.lxc.exists? && !self.lxc_clone.exists?)
85
- self.lxc_clone.stop
86
- self.lxc_clone.destroy(%(-f))
87
-
88
- self.lxc.stop
89
- self.lxc.clone(%W(-o #{self.lxc.name} -n #{self.lxc_clone.name}))
90
- self.lxc.destroy(%(-f))
91
-
92
- build_lxc_config(self.lxc_clone.config)
93
- else
94
- self.lxc.stop
95
- self.persist and self.lxc.destroy(%(-f))
96
- end
97
-
98
- true
99
- end
100
-
101
28
  # Does the container exist?
102
29
  #
103
30
  # @return [Boolean] True if the containers exists, false otherwise.
@@ -114,76 +41,6 @@ class TestLab
114
41
  self.lxc.fs_root(self.lxc_clone.exists?)
115
42
  end
116
43
 
117
- # Returns arguments for lxc-create based on our distro
118
- #
119
- # @return [Array<String>] An array of arguments for lxc-create
120
- def create_args
121
- case self.distro.downcase
122
- when "ubuntu" then
123
- %W(-f /etc/lxc/#{self.id} -t #{self.distro} -- --release #{self.release} --arch #{self.arch})
124
- when "fedora" then
125
- %W(-f /etc/lxc/#{self.id} -t #{self.distro} -- --release #{self.release})
126
- end
127
- end
128
-
129
- # Attempt to detect the architecture of the node. The value returned is
130
- # respective to the container distro.
131
- #
132
- # @return [String] The arch of the node in the context of the container
133
- # distro
134
- def detect_arch
135
- case self.distro.downcase
136
- when "ubuntu" then
137
- ((self.node.arch =~ /x86_64/) ? "amd64" : "i386")
138
- when "fedora" then
139
- ((self.node.arch =~ /x86_64/) ? "amd64" : "i686")
140
- end
141
- end
142
-
143
- # LXC Container Configuration
144
- #
145
- # Builds the LXC container configuration data.
146
- #
147
- # @return [Boolean] True if successful.
148
- def build_lxc_config(lxc_config)
149
- lxc_config.clear
150
-
151
- lxc_config['lxc.arch'] = self.arch
152
- lxc_config['lxc.utsname'] = self.fqdn
153
- lxc_config.networks = build_lxc_network_conf(self.interfaces)
154
-
155
- lxc_config.save
156
-
157
- true
158
- end
159
-
160
- # LXC Network Configuration
161
- #
162
- # Builds an array of hashes containing the lxc configuration options for
163
- # our network interfaces.
164
- #
165
- # @return [Array<Hash>] An array of hashes defining the containers
166
- # interfaces for use in configuring LXC.
167
- def build_lxc_network_conf(interfaces)
168
- networks = Array.new
169
-
170
- interfaces.each do |interface|
171
- networks << Hash[
172
- 'lxc.network.type' => :veth,
173
- 'lxc.network.flags' => :up,
174
- 'lxc.network.link' => interface.network.bridge,
175
- 'lxc.network.name' => interface.name,
176
- 'lxc.network.hwaddr' => interface.mac,
177
- 'lxc.network.ipv4' => "#{interface.ip}/#{interface.cidr} #{interface.netmask}"
178
- ]
179
- if (interface.primary == true) || (interfaces.count == 1)
180
- networks.last.merge!('lxc.network.ipv4.gateway' => :auto)
181
- end
182
- end
183
-
184
- networks
185
- end
186
-
187
44
  end
188
45
 
189
46
  end
@@ -0,0 +1,49 @@
1
+ class TestLab
2
+ class Container
3
+
4
+ module Provision
5
+
6
+ # Provision the container
7
+ #
8
+ # Attempts to provision the container. We first create the container,
9
+ # then attempt to bring it online. Afterwards the containers provisioner
10
+ # is called.
11
+ #
12
+ # @return [Boolean] True if successful.
13
+ def provision
14
+ @ui.logger.debug { "Container Provision: #{self.id} " }
15
+
16
+ (self.node.state != :running) and return false
17
+ (self.state != :running) and return false
18
+
19
+ please_wait(:ui => @ui, :message => format_object_action(self, :provision, :green)) do
20
+ do_provisioner_callbacks(self, :provision, @ui)
21
+ end
22
+
23
+ true
24
+ end
25
+
26
+ # Deprovision the container
27
+ #
28
+ # Attempts to deprovision the container. We first call the provisioner
29
+ # deprovision method defined for the container, if any. Next we attempt
30
+ # to offline the container. Afterwards the container is destroy.
31
+ #
32
+ # @return [Boolean] True if successful.
33
+ def deprovision
34
+ @ui.logger.debug { "Container Deprovision: #{self.id} " }
35
+
36
+ (self.node.state != :running) and return false
37
+ (self.state != :running) and return false
38
+
39
+ please_wait(:ui => @ui, :message => format_object_action(self, :deprovision, :red)) do
40
+ do_provisioner_callbacks(self, :deprovision, @ui)
41
+ end
42
+
43
+ true
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,47 @@
1
+ class TestLab
2
+ class Container
3
+
4
+ module Support
5
+
6
+ # Returns arguments for lxc-create based on our distro
7
+ #
8
+ # @return [Array<String>] An array of arguments for lxc-create
9
+ def create_args
10
+ case self.distro.downcase
11
+ when "ubuntu" then
12
+ %W(-f /etc/lxc/#{self.id} -t #{self.distro} -- --release #{self.release} --arch #{self.arch})
13
+ when "fedora" then
14
+ %W(-f /etc/lxc/#{self.id} -t #{self.distro} -- --release #{self.release})
15
+ end
16
+ end
17
+
18
+ # Returns arguments for lxc-start-ephemeral
19
+ #
20
+ # @return [Array<String>] An array of arguments for lxc-start-ephemeral
21
+ def clone_args
22
+ arguments = Array.new
23
+
24
+ arguments << %W(-o #{self.lxc_clone.name} -n #{self.lxc.name} -d)
25
+ arguments << %W(--keep-data) if self.persist
26
+
27
+ arguments.flatten.compact
28
+ end
29
+
30
+ # Attempt to detect the architecture of the node. The value returned is
31
+ # respective to the container distro.
32
+ #
33
+ # @return [String] The arch of the node in the context of the container
34
+ # distro
35
+ def detect_arch
36
+ case self.distro.downcase
37
+ when "ubuntu" then
38
+ ((self.node.arch =~ /x86_64/) ? "amd64" : "i386")
39
+ when "fedora" then
40
+ ((self.node.arch =~ /x86_64/) ? "amd64" : "i686")
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
@@ -77,29 +77,39 @@ class TestLab
77
77
  # Sub-Modules
78
78
  autoload :Actions, 'testlab/container/actions'
79
79
  autoload :ClassMethods, 'testlab/container/class_methods'
80
+ autoload :Clone, 'testlab/container/clone'
81
+ autoload :Configuration, 'testlab/container/configuration'
80
82
  autoload :Generators, 'testlab/container/generators'
81
83
  autoload :Interface, 'testlab/container/interface'
82
84
  autoload :IO, 'testlab/container/io'
83
85
  autoload :Lifecycle, 'testlab/container/lifecycle'
84
86
  autoload :LXC, 'testlab/container/lxc'
85
87
  autoload :MethodMissing, 'testlab/container/method_missing'
88
+ autoload :Provision, 'testlab/container/provision'
86
89
  autoload :SSH, 'testlab/container/ssh'
87
90
  autoload :Status, 'testlab/container/status'
91
+ autoload :Support, 'testlab/container/support'
88
92
  autoload :User, 'testlab/container/user'
89
93
 
90
94
  include TestLab::Container::Actions
95
+ include TestLab::Container::Clone
96
+ include TestLab::Container::Configuration
91
97
  include TestLab::Container::Generators
92
98
  include TestLab::Container::Interface
93
99
  include TestLab::Container::IO
94
100
  include TestLab::Container::Lifecycle
95
101
  include TestLab::Container::LXC
96
102
  include TestLab::Container::MethodMissing
103
+ include TestLab::Container::Provision
97
104
  include TestLab::Container::SSH
98
105
  include TestLab::Container::Status
106
+ include TestLab::Container::Support
99
107
  include TestLab::Container::User
100
108
 
101
109
  extend TestLab::Container::ClassMethods
102
110
 
111
+ include TestLab::Support::Execution
112
+
103
113
  include TestLab::Utility::Misc
104
114
 
105
115
  # Associations and Attributes