testlab 0.9.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/README.md +26 -20
  2. data/bin/tl +2 -3
  3. data/features/support/Labfile.local +11 -1
  4. data/features/support/Labfile.vagrant +7 -1
  5. data/lib/commands/container.rb +3 -3
  6. data/lib/commands/network.rb +2 -2
  7. data/lib/commands/testlab.rb +15 -15
  8. data/lib/testlab/container/actions.rb +9 -1
  9. data/lib/testlab/container/io.rb +20 -7
  10. data/lib/testlab/container/lifecycle.rb +20 -37
  11. data/lib/testlab/container/lxc.rb +2 -2
  12. data/lib/testlab/container/status.rb +2 -2
  13. data/lib/testlab/container.rb +4 -2
  14. data/lib/testlab/labfile.rb +1 -1
  15. data/lib/testlab/network/actions.rb +40 -4
  16. data/lib/testlab/network/lifecycle.rb +14 -31
  17. data/lib/testlab/network/status.rb +22 -2
  18. data/lib/testlab/node/actions.rb +8 -0
  19. data/lib/testlab/node/lifecycle.rb +14 -35
  20. data/lib/testlab/providers/local.rb +2 -2
  21. data/lib/testlab/providers/vagrant.rb +0 -2
  22. data/lib/testlab/provisioners/apt.rb +2 -2
  23. data/lib/testlab/provisioners/apt_cacher_ng.rb +12 -4
  24. data/lib/testlab/provisioners/bind.rb +23 -11
  25. data/lib/testlab/provisioners/chef/omni_bus.rb +4 -4
  26. data/lib/testlab/provisioners/chef/omni_truck.rb +2 -2
  27. data/lib/testlab/provisioners/chef/ruby_gem_client.rb +4 -4
  28. data/lib/testlab/provisioners/chef/ruby_gem_server.rb +2 -2
  29. data/lib/testlab/provisioners/raring.rb +2 -2
  30. data/lib/testlab/provisioners/resolv.rb +7 -5
  31. data/lib/testlab/provisioners/route.rb +4 -4
  32. data/lib/testlab/provisioners/shell.rb +2 -2
  33. data/lib/testlab/provisioners/templates/apt/bootstrap.erb +2 -2
  34. data/lib/testlab/provisioners/templates/apt_cacher_ng/bootstrap.erb +0 -2
  35. data/lib/testlab/provisioners/templates/apt_cacher_ng/security.conf.erb +1 -0
  36. data/lib/testlab/provisioners/templates/bind/bind-db.erb +1 -1
  37. data/lib/testlab/provisioners/templates/chef/omni_bus.erb +1 -1
  38. data/lib/testlab/provisioners/templates/chef/omni_truck.erb +1 -1
  39. data/lib/testlab/provisioners/templates/chef/ruby_gem_client.erb +1 -1
  40. data/lib/testlab/provisioners/templates/chef/ruby_gem_server.erb +1 -1
  41. data/lib/testlab/provisioners/templates/raring/bootstrap.erb +2 -2
  42. data/lib/testlab/user/lifecycle.rb +2 -2
  43. data/lib/testlab/utility/gli.rb +10 -10
  44. data/lib/testlab/utility/misc.rb +11 -0
  45. data/lib/testlab/version.rb +1 -1
  46. data/lib/testlab.rb +12 -12
  47. data/spec/container_spec.rb +14 -14
  48. data/spec/network_spec.rb +10 -8
  49. data/spec/node_spec.rb +10 -10
  50. data/spec/provisioners/shell_spec.rb +3 -3
  51. data/spec/testlab_spec.rb +12 -12
  52. metadata +5 -4
data/README.md CHANGED
@@ -4,11 +4,17 @@
4
4
  [![Coverage Status](https://coveralls.io/repos/zpatten/testlab/badge.png?branch=master)](https://coveralls.io/r/zpatten/testlab)
5
5
  [![Code Climate](https://codeclimate.com/github/zpatten/testlab.png)](https://codeclimate.com/github/zpatten/testlab)
6
6
 
7
+ # A Quick Note on Versioning
8
+
9
+ I attempt to keep TestLab in line with Semantic Versioning when incrementing version numbers. I am human so I may screw this up on, hopefully rare, occasion. Semantic Versioning is delicious and everyone should be following this schema, especially when it comes to Ruby Gems which have a habit of pushing your projects into "dependency hell".
10
+
11
+ * http://semver.org/
12
+
7
13
  # TestLab
8
14
 
9
15
  A toolkit for building virtual computer labs.
10
16
 
11
- What is TestLab? TestLab lets you iterate virtual infrastructure quickly. Using a `Labfile` you can define how you want your virtual infrastructure laid out. You can define multiple network segments and containers (i.e. boxen). TestLab will then setup and tear down this virtual infrastructure as you have dictated in the `Labfile`.
17
+ What is TestLab? TestLab lets you iterate virtual infrastructure quickly. Using a `Labfile` you can define how you want your virtual infrastructure laid out. You can define multiple network segments and containers (i.e. boxen). TestLab will then build and demolish this virtual infrastructure as you have dictated in the `Labfile`.
12
18
 
13
19
  TestLab can also import and export containers, making it easy to share them. TestLab supports the latest LXC versions, allowing for ephemeral cloning operations, furthering your ability to iterate quickly. TestLab can be used for many other applications, including infrastructure unit and integration testing, allowing for vastly more complex configurations and more effective resource sharing than traditional VM solutions.
14
20
 
@@ -26,11 +32,11 @@ The TestLab command-line program `tl` follows in the style of git:
26
32
  tl [global options] command [command options] [arguments...]
27
33
 
28
34
  VERSION
29
- 0.8.1
35
+ 0.9.1
30
36
 
31
37
  GLOBAL OPTIONS
32
38
  -l, --labfile=path/to/file - Path to Labfile: ${REPO}/Labfile (default: none)
33
- -r, --repo=path/to/directory - Path to Repository directory: ${PWD} (default: /home/zpatten/code/personal/testlab-repo)
39
+ -r, --repo=path/to/directory - Path to Repository directory: ${PWD} (default: /home/zpatten/code/chef-repo)
34
40
  -c, --config=path/to/directory - Path to Configuration directory: ${REPO}/.testlab-$(hostname -s) (default: none)
35
41
  --version - Display the program version
36
42
  -v, --[no-]verbose - Show verbose output
@@ -38,19 +44,19 @@ The TestLab command-line program `tl` follows in the style of git:
38
44
  --help - Show this message
39
45
 
40
46
  COMMANDS
41
- help - Shows a list of commands or help for one command
42
- container - Manage lab containers
43
- network - Manage lab networks
44
- node - Manage lab nodes
45
- create - Create the lab components
46
- destroy - Destroy the lab components
47
- up - On-line the lab components
48
- down - Off-line the lab components
49
- setup - Provision the lab components
50
- teardown - De-provision the lab components
51
- build - Build the lab
52
- demolish - Demolish the lab
53
- status - Display the lab status
47
+ help - Shows a list of commands or help for one command
48
+ container - Manage lab containers
49
+ network - Manage lab networks
50
+ node - Manage lab nodes
51
+ create - Create the lab components
52
+ destroy - Destroy the lab components
53
+ up - On-line the lab components
54
+ down - Off-line the lab components
55
+ provision - Provision the lab components
56
+ deprovision - De-provision the lab components
57
+ build - Build the lab
58
+ demolish - Demolish the lab
59
+ status - Display the lab status
54
60
 
55
61
  You stand up your lab with the following command:
56
62
 
@@ -107,8 +113,8 @@ You can individually online, offline, create or destroy containers:
107
113
 
108
114
  tl container down -n server-www-1
109
115
  tl container up -n server-www-1
110
- tl container setup -n server-www-1
111
- tl container teardown -n server-www-1
116
+ tl container provision -n server-www-1
117
+ tl container deprovision -n server-www-1
112
118
 
113
119
  You can recycle a container, effectively destroying then creating it again, provisioning it back to a "pristine" condition.
114
120
 
@@ -159,9 +165,9 @@ We can even recycle it while it is in a cloned state:
159
165
 
160
166
  $ tl container recycle -n server-www-1
161
167
 
162
- We can run setup against a clone as well (note: running `build`, calls `up`, which would revert us back to a non-cloned container and we would not want this to happen):
168
+ We can run provision against a clone as well (note: running `build`, calls `up`, which would revert us back to a non-cloned container and we would not want this to happen):
163
169
 
164
- $ tl container setup -n server-www-1
170
+ $ tl container provision -n server-www-1
165
171
 
166
172
  ## Network Routes
167
173
 
data/bin/tl CHANGED
@@ -109,9 +109,6 @@ post do |global,command,options,args|
109
109
  end
110
110
 
111
111
  on_error do |exception|
112
- testlab_run_time = (Time.now.utc - @testlab_start_time)
113
-
114
- @ui.stderr.puts
115
112
  @ui.stderr.puts(format_message(["ERROR:".red, exception.inspect.red.bold].join(' ')))
116
113
 
117
114
  case exception
@@ -124,6 +121,8 @@ on_error do |exception|
124
121
 
125
122
  false
126
123
  else
124
+ testlab_run_time = (Time.now.utc - @testlab_start_time)
125
+
127
126
  @logger.fatal { exception.inspect }
128
127
  exception.backtrace.each do |line|
129
128
  @logger.logdev.write("#{line}\n")
@@ -5,7 +5,12 @@ node 'vagrant' do
5
5
 
6
6
  provider TestLab::Provider::Local
7
7
 
8
- provisioners [TestLab::Provisioner::Raring]
8
+ provisioners [
9
+ TestLab::Provisioner::Raring,
10
+ TestLab::Provisioner::AptCacherNG,
11
+ TestLab::Provisioner::Bind,
12
+ TestLab::Provisioner::Resolv
13
+ ]
9
14
 
10
15
  config ({
11
16
  :bind => {
@@ -14,6 +19,10 @@ node 'vagrant' do
14
19
  })
15
20
 
16
21
  network 'labnet' do
22
+ provisioners [
23
+ TestLab::Provisioner::Bind
24
+ ]
25
+
17
26
  address '10.128.0.1/16'
18
27
  bridge :br_test
19
28
  end
@@ -23,6 +32,7 @@ node 'vagrant' do
23
32
  release "precise"
24
33
 
25
34
  provisioners [
35
+ TestLab::Provisioner::Resolv,
26
36
  TestLab::Provisioner::AptCacherNG,
27
37
  TestLab::Provisioner::Apt
28
38
  ]
@@ -7,7 +7,9 @@ node 'vagrant' do
7
7
 
8
8
  provisioners [
9
9
  TestLab::Provisioner::Raring,
10
- TestLab::Provisioner::Bind
10
+ TestLab::Provisioner::AptCacherNG,
11
+ TestLab::Provisioner::Bind,
12
+ TestLab::Provisioner::Resolv
11
13
  ]
12
14
 
13
15
  config ({
@@ -25,6 +27,10 @@ node 'vagrant' do
25
27
  })
26
28
 
27
29
  network 'labnet' do
30
+ provisioners [
31
+ TestLab::Provisioner::Bind
32
+ ]
33
+
28
34
  address '10.128.0.1/16'
29
35
  bridge :br0
30
36
  end
@@ -107,18 +107,18 @@ Recycles a container. The container is taken through a series of state changes
107
107
 
108
108
  The container is cycled in this order:
109
109
 
110
- Teardown -> Down -> Destroy -> Create -> Up -> Setup
110
+ Deprovision -> Down -> Destroy -> Create -> Up -> Provision
111
111
  EOF
112
112
  c.command :recycle do |recycle|
113
113
  recycle.action do |global_options, options, args|
114
114
  iterate_objects_by_name(options[:name], TestLab::Container) do |container|
115
- container.teardown
115
+ container.deprovision
116
116
  container.down
117
117
  container.destroy
118
118
 
119
119
  container.create
120
120
  container.up
121
- container.setup
121
+ container.provision
122
122
  end
123
123
  end
124
124
  end
@@ -54,7 +54,7 @@ EOF
54
54
  add.action do |global_options,options,args|
55
55
  iterate_objects_by_name(options[:name], TestLab::Network) do |network|
56
56
  p = TestLab::Provisioner::Route.new({}, @ui)
57
- p.on_network_setup(network)
57
+ p.on_network_provision(network)
58
58
  @testlab.ui.stdout.puts("Added routes successfully!".green.bold)
59
59
  @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.node.ip}').strip
60
60
  end
@@ -68,7 +68,7 @@ EOF
68
68
  del.action do |global_options,options,args|
69
69
  iterate_objects_by_name(options[:name], TestLab::Network) do |network|
70
70
  p = TestLab::Provisioner::Route.new({}, @ui)
71
- p.on_network_teardown(network)
71
+ p.on_network_deprovision(network)
72
72
  @testlab.ui.stdout.puts("Deleted routes successfully!".red.bold)
73
73
  @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.node.ip}').strip
74
74
  end
@@ -82,35 +82,35 @@ command :down do |down|
82
82
  end
83
83
  end
84
84
 
85
- # LAB SETUP
86
- ############
85
+ # LAB PROVISION
86
+ ################
87
87
  desc 'Provision the lab components'
88
88
  long_desc <<-EOF
89
- Attempts to setup the defined lab components.
89
+ Attempts to provision the defined lab components.
90
90
 
91
- The components are set up in the following order:
91
+ The components are provisioned in the following order:
92
92
 
93
93
  Nodes -> Networks -> Containers
94
94
  EOF
95
- command :setup do |setup|
96
- setup.action do |global_options,options,args|
97
- @testlab.setup
95
+ command :provision do |provision|
96
+ provision.action do |global_options,options,args|
97
+ @testlab.provision
98
98
  end
99
99
  end
100
100
 
101
- # LAB TEARDOWN
102
- ###############
101
+ # LAB DEPROVISION
102
+ ##################
103
103
  desc 'De-provision the lab components'
104
104
  long_desc <<-EOF
105
- Attempts to teardown the defined lab components.
105
+ Attempts to deprovision the defined lab components.
106
106
 
107
107
  The components are torndown in the following order:
108
108
 
109
109
  Containers -> Networks -> Nodes
110
110
  EOF
111
- command :teardown do |teardown|
112
- teardown.action do |global_options,options,args|
113
- @testlab.teardown
111
+ command :deprovision do |deprovision|
112
+ deprovision.action do |global_options,options,args|
113
+ @testlab.deprovision
114
114
  end
115
115
  end
116
116
 
@@ -126,7 +126,7 @@ Nodes -> Networks -> Containers
126
126
 
127
127
  TestLab will then attempt to build the components, executing the following tasks for each:
128
128
 
129
- Create -> Up -> Setup
129
+ Create -> Up -> Provision
130
130
  EOF
131
131
  command :build do |build|
132
132
  build.action do |global_options,options,args|
@@ -146,7 +146,7 @@ Containers -> Networks -> Nodes
146
146
 
147
147
  TestLab will then attempt to demolish the components, executing the following tasks for each:
148
148
 
149
- Teardown -> Down -> Destroy
149
+ Deprovision -> Down -> Destroy
150
150
  EOF
151
151
  command :demolish do |demolish|
152
152
  demolish.action do |global_options,options,args|
@@ -19,6 +19,8 @@ class TestLab
19
19
  configure
20
20
 
21
21
  self.lxc.create(*create_args)
22
+
23
+ do_provisioner_callbacks(self, :create, @ui)
22
24
  end
23
25
 
24
26
  true
@@ -38,6 +40,8 @@ class TestLab
38
40
  please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
39
41
  self.lxc.destroy(%(-f))
40
42
  self.lxc_clone.destroy(%(-f))
43
+
44
+ do_provisioner_callbacks(self, :destroy, @ui)
41
45
  end
42
46
 
43
47
  true
@@ -65,10 +69,12 @@ class TestLab
65
69
  (self.lxc.state != :running) and raise ContainerError, "The container failed to online!"
66
70
 
67
71
  self.users.each do |user|
68
- user.setup
72
+ user.provision
69
73
  end
70
74
 
71
75
  self.ssh.exec(%(sudo hostname #{self.fqdn}))
76
+
77
+ do_provisioner_callbacks(self, :up, @ui)
72
78
  end
73
79
 
74
80
  true
@@ -89,6 +95,8 @@ class TestLab
89
95
  self.lxc.stop
90
96
 
91
97
  (self.lxc.state == :running) and raise ContainerError, "The container failed to offline!"
98
+
99
+ do_provisioner_callbacks(self, :down, @ui)
92
100
  end
93
101
 
94
102
  true
@@ -101,20 +101,33 @@ EOF
101
101
  # Duplicates this container under another container definition.
102
102
  #
103
103
  # @return [Boolean] True if successful.
104
- def copy(to_name)
104
+ def copy(target_name)
105
105
  @ui.logger.debug { "Container Copy: #{self.id}" }
106
106
 
107
- to_container = self.node.containers.select{ |c| c.id.to_sym == to_name.to_sym }.first
108
- to_container.nil? and raise ContainerError, "We could not locate the target container!"
107
+ target_name.nil? and raise ContainerError, "You must supply a destination container!"
109
108
 
110
- to_container.demolish
111
- to_container.create
109
+ target_container = self.node.containers.select{ |c| c.id.to_sym == target_name.to_sym }.first
110
+ target_container.nil? and raise ContainerError, "We could not locate the target container!"
112
111
 
112
+ source_state = self.state
113
+ target_state = target_container.state
114
+
115
+ target_container.demolish
116
+ target_container.create
117
+
118
+ self.down
113
119
  please_wait(:ui => @ui, :message => format_object_action(self, 'Copy', :yellow)) do
114
- self.node.ssh.exec(%(sudo rm -rf #{to_container.lxc.fs_root}))
115
- self.node.ssh.exec(%(sudo rsync -a #{self.lxc.fs_root} #{to_container.lxc.container_root}))
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')}))
116
123
  end
117
124
 
125
+ # bring the source container back online if it was running before the copy operation
126
+ (source_state == :running) and self.up
127
+
128
+ # bring the target container back online if it was running before the copy operation
129
+ (target_state == :running) and target_container.up
130
+
118
131
  true
119
132
  end
120
133
 
@@ -3,53 +3,41 @@ class TestLab
3
3
 
4
4
  module Lifecycle
5
5
 
6
- # Setup the container
6
+ # Provision the container
7
7
  #
8
- # Attempts to setup the container. We first create the container, then
9
- # attempt to bring it online. Afterwards the containers provisioner is
10
- # called.
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
11
  #
12
12
  # @return [Boolean] True if successful.
13
- def setup
14
- @ui.logger.debug { "Container Setup: #{self.id} " }
13
+ def provision
14
+ @ui.logger.debug { "Container Provision: #{self.id} " }
15
15
 
16
16
  (self.node.state != :running) and return false
17
- (self.lxc.state == :not_created) and return false
18
-
19
- please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
20
-
21
- self.container_provisioners.each do |provisioner|
22
- @ui.logger.info { ">>>>> CONTAINER PROVISIONER SETUP: #{provisioner} (#{self.id}) <<<<<" }
23
- p = provisioner.new(self.config, @ui)
24
- p.respond_to?(:on_container_setup) and p.on_container_setup(self)
25
- end
17
+ (self.state != :running) and return false
26
18
 
19
+ please_wait(:ui => @ui, :message => format_object_action(self, :provision, :green)) do
20
+ do_provisioner_callbacks(self, :provision, @ui)
27
21
  end
28
22
 
29
23
  true
30
24
  end
31
25
 
32
- # Teardown the container
26
+ # Deprovision the container
33
27
  #
34
- # Attempts to teardown the container. We first call the provisioner
35
- # teardown method defined for the container, if any. Next we attempt to
36
- # offline the container. Afterwards the container is destroy.
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.
37
31
  #
38
32
  # @return [Boolean] True if successful.
39
- def teardown
40
- @ui.logger.debug { "Container Teardown: #{self.id} " }
33
+ def deprovision
34
+ @ui.logger.debug { "Container Deprovision: #{self.id} " }
41
35
 
42
36
  (self.node.state != :running) and return false
43
- (self.lxc.state == :not_created) and return false
44
-
45
- please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
46
-
47
- self.container_provisioners.each do |provisioner|
48
- @ui.logger.info { ">>>>> CONTAINER PROVISIONER TEARDOWN: #{provisioner} (#{self.id}) <<<<<" }
49
- p = provisioner.new(self.config, @ui)
50
- p.respond_to?(:on_container_teardown) and p.on_container_teardown(self)
51
- end
37
+ (self.state != :running) and return false
52
38
 
39
+ please_wait(:ui => @ui, :message => format_object_action(self, :deprovision, :red)) do
40
+ do_provisioner_callbacks(self, :deprovision, @ui)
53
41
  end
54
42
 
55
43
  true
@@ -59,25 +47,20 @@ class TestLab
59
47
  def build
60
48
  self.create
61
49
  self.up
62
- self.setup
50
+ self.provision
63
51
 
64
52
  true
65
53
  end
66
54
 
67
55
  # Demolish the container
68
56
  def demolish
69
- self.teardown
57
+ self.deprovision
70
58
  self.down
71
59
  self.destroy
72
60
 
73
61
  true
74
62
  end
75
63
 
76
- # Returns all defined provisioners for this container's networks and the container iteself.
77
- def container_provisioners
78
- [self.interfaces.map(&:network).map(&:provisioners), self.provisioners].flatten.compact.uniq
79
- end
80
-
81
64
  end
82
65
 
83
66
  end
@@ -17,9 +17,9 @@ class TestLab
17
17
  # @param [String] content The content to render on the container and
18
18
  # execute. This is generally a bash script of some sort for example.
19
19
  # @return [String] The output of *lxc-attach*.
20
- def bootstrap(content)
20
+ def bootstrap(content, options={})
21
21
  if self.lxc_clone.exists?
22
- self.ssh.bootstrap(content)
22
+ self.ssh.bootstrap(content, options)
23
23
  else
24
24
  self.lxc.bootstrap(content)
25
25
  end
@@ -14,11 +14,11 @@ class TestLab
14
14
 
15
15
  # Container CIDR
16
16
  #
17
- # Returns the CIDR of the container
17
+ # Returns the CIDR of the container.
18
18
  #
19
19
  # @return [Integer] The containers CIDR address.
20
20
  def cidr
21
- TestLab::Utility.cidr(self.primary_interface.address).to_i
21
+ TestLab::Utility.cidr(self.primary_interface.address)
22
22
  end
23
23
 
24
24
  # Container BIND PTR Record
@@ -14,7 +14,8 @@ class TestLab
14
14
  # distro "ubuntu"
15
15
  # release "precise"
16
16
  #
17
- # user "deployer" do
17
+ # user do
18
+ # username "deployer"
18
19
  # password "deployer"
19
20
  # uid 2600
20
21
  # gid 2600
@@ -33,7 +34,8 @@ class TestLab
33
34
  # distro "ubuntu"
34
35
  # release "precise"
35
36
  #
36
- # user "deployer" do
37
+ # user do
38
+ # username "deployer"
37
39
  # password "deployer"
38
40
  # uid 2600
39
41
  # gid 2600
@@ -7,9 +7,9 @@ class TestLab
7
7
  #
8
8
  # @author Zachary Patten <zachary AT jovelabs DOT com>
9
9
  class Labfile < ZTK::DSL::Base
10
- attribute :testlab
11
10
  has_many :nodes, :class_name => 'TestLab::Node'
12
11
 
12
+ attribute :testlab
13
13
  attribute :config, :default => Hash.new
14
14
 
15
15
  def config_dir
@@ -11,7 +11,27 @@ class TestLab
11
11
  (self.state != :not_created) and return false
12
12
 
13
13
  please_wait(:ui => @ui, :message => format_object_action(self, 'Create', :green)) do
14
- self.node.ssh.exec(%(sudo brctl addbr #{self.bridge}), :silence => true, :ignore_exit_status => true)
14
+ self.node.ssh.bootstrap(<<-EOF, :ignore_exit_status => true)
15
+ set -x
16
+ grep '#{def_tag}' /etc/network/interfaces && exit 0
17
+ cat <<EOI | tee -a /etc/network/interfaces
18
+ #{def_tag}
19
+ auto br0
20
+ iface #{self.bridge} inet static
21
+ bridge_ports none
22
+ bridge_stp off
23
+ bridge_fd 0
24
+ address #{self.ip}
25
+ broadcast #{self.broadcast}
26
+ netmask #{self.netmask}
27
+ #{end_tag}
28
+ EOI
29
+ brctl addbr #{self.bridge}
30
+ brctl stp #{self.bridge} off
31
+ brctl setfd #{self.bridge} 0
32
+ EOF
33
+
34
+ do_provisioner_callbacks(self, :create, @ui)
15
35
  end
16
36
 
17
37
  true
@@ -25,7 +45,13 @@ class TestLab
25
45
  (self.state == :not_created) and return false
26
46
 
27
47
  please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
28
- self.node.ssh.exec(%(sudo brctl delbr #{self.bridge}), :silence => true, :ignore_exit_status => true)
48
+ self.node.ssh.bootstrap(<<-EOF, :ignore_exit_status => true)
49
+ set -x
50
+ sed -i '/#{def_tag}/,/#{end_tag}/d' /etc/network/interfaces
51
+ brctl delbr #{self.bridge}
52
+ EOF
53
+
54
+ do_provisioner_callbacks(self, :destroy, @ui)
29
55
  end
30
56
 
31
57
  true
@@ -39,7 +65,12 @@ class TestLab
39
65
  (self.state == :running) and return false
40
66
 
41
67
  please_wait(:ui => @ui, :message => format_object_action(self, 'Up', :green)) do
42
- self.node.ssh.exec(%(sudo ifconfig #{self.bridge} #{self.ip} netmask #{self.netmask} up), :silence => true, :ignore_exit_status => true)
68
+ self.node.ssh.bootstrap(<<-EOF, :ignore_exit_status => true)
69
+ set -x
70
+ ifconfig #{self.bridge} #{self.ip} netmask #{self.netmask} broadcast #{self.broadcast} up
71
+ EOF
72
+
73
+ do_provisioner_callbacks(self, :up, @ui)
43
74
  end
44
75
 
45
76
  true
@@ -53,7 +84,12 @@ class TestLab
53
84
  (self.state != :running) and return false
54
85
 
55
86
  please_wait(:ui => @ui, :message => format_object_action(self, 'Down', :red)) do
56
- self.node.ssh.exec(%(sudo ifconfig #{self.bridge} down), :silence => true, :ignore_exit_status => true)
87
+ self.node.ssh.bootstrap(<<-EOF, :ignore_exit_status => true)
88
+ set -x
89
+ ifconfig #{self.bridge} down
90
+ EOF
91
+
92
+ do_provisioner_callbacks(self, :down, @ui)
57
93
  end
58
94
 
59
95
  true
@@ -3,41 +3,29 @@ class TestLab
3
3
 
4
4
  module Lifecycle
5
5
 
6
- # Network Setup
7
- def setup
8
- @ui.logger.debug { "Network Setup: #{self.id} " }
6
+ # Network Provision
7
+ def provision
8
+ @ui.logger.debug { "Network Provision: #{self.id} " }
9
9
 
10
10
  (self.node.state != :running) and return false
11
- (self.state == :not_created) and return false
12
-
13
- please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
14
-
15
- self.network_provisioners.each do |provisioner|
16
- @ui.logger.info { ">>>>> NETWORK PROVISIONER SETUP: #{provisioner} (#{self.bridge}) <<<<<" }
17
- p = provisioner.new(self.config, @ui)
18
- p.respond_to?(:on_network_setup) and p.on_network_setup(self)
19
- end
11
+ (self.state != :running) and return false
20
12
 
13
+ please_wait(:ui => @ui, :message => format_object_action(self, 'Provision', :green)) do
14
+ do_provisioner_callbacks(self, :provision, @ui)
21
15
  end
22
16
 
23
17
  true
24
18
  end
25
19
 
26
- # Network Teardown
27
- def teardown
28
- @ui.logger.debug { "Network Teardown: #{self.id} " }
20
+ # Network Deprovision
21
+ def deprovision
22
+ @ui.logger.debug { "Network Deprovision: #{self.id} " }
29
23
 
30
24
  (self.node.state != :running) and return false
31
- (self.state == :not_created) and return false
32
-
33
- please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
34
-
35
- self.network_provisioners.each do |provisioner|
36
- @ui.logger.info { ">>>>> NETWORK PROVISIONER TEARDOWN: #{provisioner} (#{self.bridge}) <<<<<" }
37
- p = provisioner.new(self.config, @ui)
38
- p.respond_to?(:on_network_teardown) and p.on_network_teardown(self)
39
- end
25
+ (self.state != :running) and return false
40
26
 
27
+ please_wait(:ui => @ui, :message => format_object_action(self, 'Deprovision', :red)) do
28
+ do_provisioner_callbacks(self, :deprovision, @ui)
41
29
  end
42
30
 
43
31
  true
@@ -47,25 +35,20 @@ class TestLab
47
35
  def build
48
36
  self.create
49
37
  self.up
50
- self.setup
38
+ self.provision
51
39
 
52
40
  true
53
41
  end
54
42
 
55
43
  # Demolish the network
56
44
  def demolish
57
- self.teardown
45
+ self.deprovision
58
46
  self.down
59
47
  self.destroy
60
48
 
61
49
  true
62
50
  end
63
51
 
64
- # Returns all defined provisioners for this network's containers and the network iteself.
65
- def network_provisioners
66
- [self.provisioners, self.interfaces.map(&:container).map(&:provisioners)].flatten.compact.uniq
67
- end
68
-
69
52
  end
70
53
 
71
54
  end