kitchen-lxc 0.0.1.beta1 → 0.0.1.beta2
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.
- data/README.md +86 -48
- data/kitchen-lxc.gemspec +3 -2
- data/lib/kitchen/driver/lxc.rb +29 -22
- data/test/lxc_driver_tests.rb +8 -5
- metadata +20 -4
data/README.md
CHANGED
|
@@ -1,79 +1,109 @@
|
|
|
1
1
|
# Kitchen LXC
|
|
2
2
|
|
|
3
|
-
The LXC driver for the Chef convergence integration test harness,
|
|
3
|
+
The LXC driver for the Chef convergence integration test harness,
|
|
4
|
+
[Test Kitchen](https://github.com/opscode/test-kitchen/tree/1.0).
|
|
5
|
+
|
|
6
|
+
Kitchen LXC creates a clone of a "base" LXC container to run a test
|
|
7
|
+
suite.
|
|
4
8
|
|
|
5
9
|
## Installation
|
|
6
10
|
|
|
7
|
-
Add this line to your Chef
|
|
11
|
+
Add this line to your Chef cookbook's Gemfile:
|
|
8
12
|
|
|
9
13
|
gem 'kitchen-lxc'
|
|
10
14
|
|
|
11
15
|
And then execute:
|
|
12
16
|
|
|
13
|
-
$ bundle
|
|
14
|
-
|
|
15
|
-
Or install it yourself as:
|
|
16
|
-
|
|
17
|
-
$ gem install kitchen-lxc
|
|
17
|
+
$ bundle install
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
21
|
### Configuration
|
|
22
22
|
|
|
23
|
+
#### base_container
|
|
24
|
+
The base LXC container to be cloned for each Test Kitchen suite.
|
|
25
|
+
|
|
26
|
+
#### username
|
|
27
|
+
The username used to login to the container.
|
|
28
|
+
|
|
29
|
+
Defaults to "root".
|
|
30
|
+
|
|
31
|
+
#### password
|
|
32
|
+
The password used to login to the container.
|
|
33
|
+
|
|
34
|
+
Defaults to "root".
|
|
35
|
+
|
|
36
|
+
#### dhcp_lease_file
|
|
37
|
+
The DHCP lease file used to determine the container IP address.
|
|
38
|
+
|
|
39
|
+
Defaults to the first match for "/var/lib/misc/dnsmasq*leases".
|
|
40
|
+
|
|
41
|
+
#### ipaddress
|
|
42
|
+
You may specify an IP address for the container, within the
|
|
43
|
+
10.0.3.0/24 subnet, instead of using DHCP.
|
|
44
|
+
|
|
45
|
+
#### port
|
|
46
|
+
The SSH port used to login to the container.
|
|
47
|
+
|
|
48
|
+
Defaults to 22.
|
|
49
|
+
|
|
50
|
+
#### overlay
|
|
51
|
+
The directory to use for the rootfs overlay.
|
|
52
|
+
|
|
53
|
+
Defaults to "/tmp".
|
|
54
|
+
|
|
55
|
+
#### device
|
|
56
|
+
The size (MB) of the block device for the rootfs overlay.
|
|
57
|
+
|
|
58
|
+
### Example
|
|
59
|
+
|
|
23
60
|
`.kitchen.local.yml`
|
|
24
61
|
|
|
25
62
|
```
|
|
63
|
+
---
|
|
26
64
|
driver_plugin: lxc
|
|
27
65
|
|
|
28
66
|
platforms:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
67
|
+
- name: ubuntu_1204
|
|
68
|
+
driver_config:
|
|
69
|
+
base_container: ubuntu_1204 # your base container name
|
|
70
|
+
username: kitchen # defaults to "root"
|
|
71
|
+
password: kitchen # defaults to "root"
|
|
34
72
|
```
|
|
35
73
|
|
|
36
|
-
### Example
|
|
37
|
-
|
|
38
74
|
```
|
|
39
|
-
$ kitchen create
|
|
75
|
+
$ bundle exec kitchen create
|
|
40
76
|
-----> Starting Kitchen
|
|
41
77
|
-----> Creating <default-ubuntu>
|
|
42
|
-
[lxc command] BEGIN (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
[lxc command]
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
[lxc command]
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
[lxc command] END (0m0.02s)
|
|
62
|
-
[lxc command] BEGIN (sudo lxc-wait -n default-centos-58fced -s RUNNING)
|
|
63
|
-
[lxc command] END (0m1.05s)
|
|
64
|
-
Finished creating <default-centos> (0m13.92s).
|
|
65
|
-
-----> Kitchen is finished. (0m21.45s)
|
|
66
|
-
$ kitchen destroy
|
|
78
|
+
[kitchen::driver::lxc command] BEGIN (lxc-awesome-ephemeral -d -o tk-ubuntu-1204 -n default-ubuntu-a0c75e)
|
|
79
|
+
Setting up ephemeral container...
|
|
80
|
+
Starting up the container...
|
|
81
|
+
default-ubuntu-a0c75e is running
|
|
82
|
+
You connect with the command:
|
|
83
|
+
sudo lxc-console -n default-ubuntu-a0c75e
|
|
84
|
+
[kitchen::driver::lxc command] END (0m1.92s)
|
|
85
|
+
Finished creating <default-ubuntu> (0m4.98s).
|
|
86
|
+
-----> Creating <stack-ubuntu>
|
|
87
|
+
[kitchen::driver::lxc command] BEGIN (lxc-awesome-ephemeral -d -o tk-ubuntu-1204 -n stack-ubuntu-cb87c2)
|
|
88
|
+
Setting up ephemeral container...
|
|
89
|
+
Starting up the container...
|
|
90
|
+
stack-ubuntu-cb87c2 is running
|
|
91
|
+
You connect with the command:
|
|
92
|
+
sudo lxc-console -n stack-ubuntu-cb87c2
|
|
93
|
+
[kitchen::driver::lxc command] END (0m1.91s)
|
|
94
|
+
Finished creating <stack-ubuntu> (0m4.99s).
|
|
95
|
+
-----> Kitchen is finished. (0m9.99s)
|
|
96
|
+
$ bundle exec kitchen destroy
|
|
67
97
|
-----> Starting Kitchen
|
|
68
98
|
-----> Destroying <default-ubuntu>
|
|
69
|
-
[lxc command] BEGIN (
|
|
70
|
-
[lxc command] END (
|
|
71
|
-
Finished destroying <default-ubuntu> (
|
|
72
|
-
-----> Destroying <
|
|
73
|
-
[lxc command] BEGIN (
|
|
74
|
-
[lxc command] END (
|
|
75
|
-
Finished destroying <
|
|
76
|
-
-----> Kitchen is finished. (
|
|
99
|
+
[kitchen::driver::lxc command] BEGIN (lxc-awesome-ephemeral -c -o tk-ubuntu-1204 -n default-ubuntu-a0c75e)
|
|
100
|
+
[kitchen::driver::lxc command] END (0m3.41s)
|
|
101
|
+
Finished destroying <default-ubuntu> (0m3.48s).
|
|
102
|
+
-----> Destroying <stack-ubuntu>
|
|
103
|
+
[kitchen::driver::lxc command] BEGIN (lxc-awesome-ephemeral -c -o tk-ubuntu-1204 -n stack-ubuntu-cb87c2)
|
|
104
|
+
[kitchen::driver::lxc command] END (0m3.44s)
|
|
105
|
+
Finished destroying <stack-ubuntu> (0m3.52s).
|
|
106
|
+
-----> Kitchen is finished. (0m7.03s)
|
|
77
107
|
```
|
|
78
108
|
|
|
79
109
|
## Contributing
|
|
@@ -83,3 +113,11 @@ $ kitchen destroy
|
|
|
83
113
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
84
114
|
4. Push to the branch (`git push origin my-new-feature`)
|
|
85
115
|
5. Create new Pull Request
|
|
116
|
+
|
|
117
|
+
## Authors
|
|
118
|
+
|
|
119
|
+
Author:: Sean Porter (<portertech@gmail.com>)
|
|
120
|
+
|
|
121
|
+
Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
|
|
122
|
+
|
|
123
|
+
See LICENSE.txt for licensing details
|
data/kitchen-lxc.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |gem|
|
|
2
2
|
gem.name = "kitchen-lxc"
|
|
3
|
-
gem.version = "0.0.1.
|
|
3
|
+
gem.version = "0.0.1.beta2"
|
|
4
4
|
gem.authors = ["Sean Porter"]
|
|
5
5
|
gem.email = ["portertech@gmail.com"]
|
|
6
6
|
gem.description = "LXC driver for Test Kitchen"
|
|
@@ -9,7 +9,8 @@ Gem::Specification.new do |gem|
|
|
|
9
9
|
gem.license = "MIT"
|
|
10
10
|
gem.has_rdoc = false
|
|
11
11
|
|
|
12
|
-
gem.add_dependency("test-kitchen", ">= 1.0.0.alpha.
|
|
12
|
+
gem.add_dependency("test-kitchen", ">= 1.0.0.alpha.6")
|
|
13
|
+
gem.add_dependency("lxc-awesome-ephemeral", ">= 0.0.1.beta1")
|
|
13
14
|
|
|
14
15
|
gem.add_development_dependency("rake")
|
|
15
16
|
|
data/lib/kitchen/driver/lxc.rb
CHANGED
|
@@ -7,62 +7,69 @@ module Kitchen
|
|
|
7
7
|
|
|
8
8
|
class Lxc < Kitchen::Driver::SSHBase
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
no_parallel_for :create
|
|
11
|
+
|
|
12
|
+
default_config :use_sudo, false
|
|
13
|
+
default_config :dhcp_lease_file, Dir["/var/lib/misc/dnsmasq*leases"][0]
|
|
12
14
|
default_config :port, "22"
|
|
13
15
|
default_config :username, "root" # most LXC templates use this
|
|
14
16
|
default_config :password, "root" # most LXC templates use this
|
|
15
17
|
|
|
16
18
|
def create(state)
|
|
17
19
|
state[:container_id] = instance.name + "-" + ::SecureRandom.hex(3)
|
|
18
|
-
|
|
20
|
+
state[:overlay] = config[:overlay] if config[:overlay]
|
|
19
21
|
start_container(state)
|
|
20
22
|
state[:hostname] = container_ip(state)
|
|
21
23
|
wait_for_sshd(state[:hostname])
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def destroy(state)
|
|
25
|
-
if state[:container_id]
|
|
26
|
-
destroy_container(state)
|
|
27
|
-
end
|
|
27
|
+
destroy_container(state) if state[:container_id]
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
protected
|
|
31
31
|
|
|
32
|
-
def clone_container(state)
|
|
33
|
-
run_command("lxc-clone -o #{config[:base_container]} -n #{state[:container_id]}")
|
|
34
|
-
end
|
|
35
|
-
|
|
36
32
|
def start_container(state)
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
cmd = "lxc-awesome-ephemeral -d -o #{config[:base_container]} -n #{state[:container_id]}"
|
|
34
|
+
[:device, :ipaddress, :netmask, :gateway, :key].each do |opt|
|
|
35
|
+
unless config[opt].nil?
|
|
36
|
+
cmd << " --#{opt} #{config[opt]}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
cmd << " -z #{state[:overlay]}" if state[:overlay]
|
|
40
|
+
run_command(cmd)
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
def destroy_container(state)
|
|
42
|
-
|
|
44
|
+
cmd = "lxc-awesome-ephemeral -c -o #{config[:base_container]} -n #{state[:container_id]}"
|
|
45
|
+
cmd << " -z #{state[:overlay]}" if state[:overlay]
|
|
46
|
+
run_command(cmd)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def dhcp_lease_file
|
|
50
|
+
unless ::File.exists?(config[:dhcp_lease_file])
|
|
51
|
+
raise ActionFailed, "LXC DHCP lease file does not exist '#{config[:dhcp_lease_file]}'"
|
|
52
|
+
end
|
|
53
|
+
config[:dhcp_lease_file]
|
|
43
54
|
end
|
|
44
55
|
|
|
45
56
|
def container_ip(state)
|
|
46
|
-
if
|
|
57
|
+
if config[:ipaddress]
|
|
58
|
+
return config[:ipaddress]
|
|
59
|
+
else
|
|
47
60
|
30.times do
|
|
48
|
-
leases = ::File.readlines(
|
|
61
|
+
leases = ::File.readlines(dhcp_lease_file).map { |line| line.split(" ") }
|
|
49
62
|
leases.each do |lease|
|
|
50
|
-
if lease.include?(state[:container_id])
|
|
51
|
-
return lease[2]
|
|
52
|
-
end
|
|
63
|
+
return lease[2] if lease.include?(state[:container_id])
|
|
53
64
|
end
|
|
54
65
|
sleep 3
|
|
55
66
|
end
|
|
56
|
-
else
|
|
57
|
-
raise ActionFailed, "LXC DHCP lease file does not exist '#{config[:dhcp_lease_file]}'"
|
|
58
67
|
end
|
|
59
68
|
raise ActionFailed, "Could not determine IP address for LXC container '#{state[:container_id]}'"
|
|
60
69
|
end
|
|
61
|
-
|
|
62
70
|
end
|
|
63
71
|
|
|
64
72
|
class LXC < Lxc; end
|
|
65
73
|
|
|
66
74
|
end
|
|
67
|
-
|
|
68
75
|
end
|
data/test/lxc_driver_tests.rb
CHANGED
|
@@ -7,15 +7,17 @@ require File.join(File.dirname(__FILE__), "..", "lib", "kitchen", "driver", "lxc
|
|
|
7
7
|
describe Kitchen::Driver::Lxc do
|
|
8
8
|
|
|
9
9
|
before do
|
|
10
|
-
@
|
|
10
|
+
@base_container = ENV["BASE_CONTAINER"]
|
|
11
|
+
raise "You must set BASE_CONTAINER" unless @base_container
|
|
11
12
|
driver_options = {
|
|
12
13
|
:kitchen_root => File.dirname(__FILE__),
|
|
13
|
-
:base_container =>
|
|
14
|
+
:base_container => @base_container
|
|
14
15
|
}
|
|
16
|
+
@logger_output = StringIO.new
|
|
15
17
|
instance_options = {
|
|
16
18
|
:logger => Kitchen::Logger.new(:stdout => @logger_output),
|
|
17
19
|
:suite => Kitchen::Suite.new(:name => "test", :run_list => Array.new),
|
|
18
|
-
:platform => Kitchen::Platform.new(:name =>
|
|
20
|
+
:platform => Kitchen::Platform.new(:name => @base_container),
|
|
19
21
|
:driver => Kitchen::Driver::Lxc.new(driver_options)
|
|
20
22
|
}
|
|
21
23
|
@instance = Kitchen::Instance.new(instance_options)
|
|
@@ -23,9 +25,10 @@ describe Kitchen::Driver::Lxc do
|
|
|
23
25
|
|
|
24
26
|
it "can clone a base lxc container" do
|
|
25
27
|
@instance.create
|
|
26
|
-
|
|
28
|
+
container_name = "test-#{@base_container}"
|
|
29
|
+
@logger_output.string.must_match(/Finished creating <#{container_name}>/i)
|
|
27
30
|
@instance.destroy
|
|
28
|
-
@logger_output.string.must_match(/Finished destroying
|
|
31
|
+
@logger_output.string.must_match(/Finished destroying <#{container_name}>/i)
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
end
|
metadata
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
name: kitchen-lxc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: 6
|
|
5
|
-
version: 0.0.1.
|
|
5
|
+
version: 0.0.1.beta2
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Sean Porter
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
12
|
+
date: 2013-05-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
type: :runtime
|
|
@@ -18,15 +18,31 @@ dependencies:
|
|
|
18
18
|
requirements:
|
|
19
19
|
- - ! '>='
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.0.0.alpha.
|
|
21
|
+
version: 1.0.0.alpha.6
|
|
22
22
|
prerelease: false
|
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
24
|
none: false
|
|
25
25
|
requirements:
|
|
26
26
|
- - ! '>='
|
|
27
27
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: 1.0.0.alpha.
|
|
28
|
+
version: 1.0.0.alpha.6
|
|
29
29
|
name: test-kitchen
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
type: :runtime
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ! '>='
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: 0.0.1.beta1
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
none: false
|
|
41
|
+
requirements:
|
|
42
|
+
- - ! '>='
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: 0.0.1.beta1
|
|
45
|
+
name: lxc-awesome-ephemeral
|
|
30
46
|
- !ruby/object:Gem::Dependency
|
|
31
47
|
type: :development
|
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|