testlab 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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