vagrant-lxc 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.vimrc +1 -1
  4. data/CHANGELOG.md +22 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +10 -9
  7. data/README.md +43 -29
  8. data/boxes/quantal64/download-ubuntu +21 -20
  9. data/boxes/quantal64/lxc-template +11 -11
  10. data/boxes/quantal64/metadata.json +1 -1
  11. data/development/Vagrantfile +8 -4
  12. data/example/Vagrantfile +3 -15
  13. data/lib/vagrant-lxc.rb +0 -2
  14. data/lib/vagrant-lxc/action.rb +1 -14
  15. data/lib/vagrant-lxc/action/boot.rb +8 -9
  16. data/lib/vagrant-lxc/action/check_created.rb +6 -2
  17. data/lib/vagrant-lxc/action/check_running.rb +6 -2
  18. data/lib/vagrant-lxc/action/compress_rootfs.rb +1 -1
  19. data/lib/vagrant-lxc/action/create.rb +15 -7
  20. data/lib/vagrant-lxc/action/created.rb +6 -2
  21. data/lib/vagrant-lxc/action/destroy.rb +6 -2
  22. data/lib/vagrant-lxc/action/disconnect.rb +5 -1
  23. data/lib/vagrant-lxc/action/forced_halt.rb +3 -3
  24. data/lib/vagrant-lxc/action/forward_ports.rb +2 -2
  25. data/lib/vagrant-lxc/action/handle_box_metadata.rb +38 -27
  26. data/lib/vagrant-lxc/action/is_running.rb +6 -2
  27. data/lib/vagrant-lxc/action/share_folders.rb +8 -8
  28. data/lib/vagrant-lxc/config.rb +20 -10
  29. data/lib/vagrant-lxc/driver.rb +162 -0
  30. data/lib/vagrant-lxc/driver/builder.rb +21 -0
  31. data/lib/vagrant-lxc/{container → driver}/cli.rb +16 -11
  32. data/lib/vagrant-lxc/driver/fetch_ip_from_dnsmasq.rb +41 -0
  33. data/lib/vagrant-lxc/driver/fetch_ip_with_attach.rb +29 -0
  34. data/lib/vagrant-lxc/errors.rb +10 -0
  35. data/lib/vagrant-lxc/plugin.rb +4 -0
  36. data/lib/vagrant-lxc/provider.rb +14 -11
  37. data/lib/vagrant-lxc/version.rb +1 -1
  38. data/spec/fixtures/sample-ip-addr-output +2 -0
  39. data/spec/spec_helper.rb +1 -0
  40. data/spec/unit/action/compress_rootfs_spec.rb +4 -4
  41. data/spec/unit/action/forward_ports_spec.rb +3 -3
  42. data/spec/unit/action/handle_box_metadata_spec.rb +52 -26
  43. data/spec/unit/{container → driver}/cli_spec.rb +17 -19
  44. data/spec/unit/driver_spec.rb +173 -0
  45. data/tasks/boxes.rake +3 -3
  46. metadata +13 -15
  47. data/lib/vagrant-lxc/action/base_action.rb +0 -11
  48. data/lib/vagrant-lxc/action/network.rb +0 -21
  49. data/lib/vagrant-lxc/container.rb +0 -141
  50. data/lib/vagrant-lxc/machine_state.rb +0 -25
  51. data/spec/fixtures/sample-ifconfig-output +0 -18
  52. data/spec/unit/container_spec.rb +0 -147
  53. data/spec/unit/machine_state_spec.rb +0 -39
@@ -10,8 +10,8 @@ describe Vagrant::LXC::Action::ForwardPorts do
10
10
  let(:networks) { [[:other_config, {}], [:forwarded_port, {guest: guest_port, host: host_port}]] }
11
11
  let(:host_port) { 8080 }
12
12
  let(:guest_port) { 80 }
13
- let(:provider) { fire_double('Vagrant::LXC::Provider', container: container) }
14
- let(:container) { fire_double('Vagrant::LXC::Container', assigned_ip: container_ip) }
13
+ let(:provider) { fire_double('Vagrant::LXC::Provider', driver: driver) }
14
+ let(:driver) { fire_double('Vagrant::LXC::Driver', assigned_ip: container_ip) }
15
15
  let(:container_ip) { '10.0.1.234' }
16
16
  let(:pid) { 'a-pid' }
17
17
 
@@ -30,7 +30,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
30
30
 
31
31
  it 'forwards ports using redir' do
32
32
  subject.should have_received(:exec).with(
33
- "sudo redir --laddr=127.0.0.1 --lport=#{host_port} --cport=#{guest_port} --caddr=#{container_ip}"
33
+ "sudo redir --laddr=127.0.0.1 --lport=#{host_port} --cport=#{guest_port} --caddr=#{container_ip} 2>/dev/null"
34
34
  )
35
35
  end
36
36
 
@@ -1,44 +1,70 @@
1
1
  require 'unit_helper'
2
2
 
3
- require 'vagrant-lxc/action/base_action'
3
+ require 'vagrant'
4
+ require 'vagrant-lxc/errors'
4
5
  require 'vagrant-lxc/action/handle_box_metadata'
5
6
 
6
7
  describe Vagrant::LXC::Action::HandleBoxMetadata do
7
- let(:metadata) { {'template-opts' => {'--foo' => 'bar'}} }
8
- let(:box) { mock(:box, name: 'box-name', metadata: metadata, directory: box_directory) }
9
- let(:box_directory) { Pathname.new('/path/to/box') }
10
- let(:machine) { mock(:machine, box: box) }
11
8
  let(:app) { mock(:app, call: true) }
12
9
  let(:env) { {machine: machine, ui: stub(info: true)} }
13
- let(:tmpdir) { '/tmp/rootfs/dir' }
10
+ let(:machine) { mock(:machine, box: box) }
11
+ let(:box) { mock(:box, name: 'box-name', metadata: metadata, directory: box_directory) }
12
+ let(:box_directory) { Pathname.new('/path/to/box') }
13
+ let(:version) { '2' }
14
+ let(:metadata) { {'template-opts' => {'--foo' => 'bar'}, 'version' => version} }
15
+ let(:vagrant_key) { Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s }
14
16
 
15
17
  subject { described_class.new(app, env) }
16
18
 
17
- before do
18
- Dir.stub(mktmpdir: tmpdir)
19
- File.stub(exists?: true)
20
- subject.stub(:system)
21
- subject.call(env)
22
- end
19
+ context 'with valid contents' do
20
+ before do
21
+ File.stub(exists?: true)
22
+ subject.call(env)
23
+ end
23
24
 
24
- it 'creates a tmp directory to store rootfs-cache-path' do
25
- metadata['rootfs-cache-path'].should == tmpdir
26
- end
25
+ it 'sets the tarball argument for the template' do
26
+ env[:lxc_template_opts].should include(
27
+ '--tarball' => box_directory.join('rootfs.tar.gz').to_s
28
+ )
29
+ end
27
30
 
28
- it 'prepends vagrant and box name to template-name' do
29
- metadata['template-name'].should == "vagrant-#{box.name}"
30
- end
31
+ it 'sets the auth key argument for the template' do
32
+ env[:lxc_template_opts].should include(
33
+ '--auth-key' => vagrant_key
34
+ )
35
+ end
31
36
 
32
- it 'copies box template file to the right folder' do
33
- src = box_directory.join('lxc-template').to_s
34
- dest = "/usr/share/lxc/templates/lxc-#{metadata['template-name']}"
37
+ it 'sets the template options from metadata on env hash' do
38
+ env[:lxc_template_opts].should include(metadata['template-opts'])
39
+ end
35
40
 
36
- subject.should have_received(:system).
37
- with("sudo su root -c \"cp #{src} #{dest}\"")
41
+ it 'sets the template source path on env hash' do
42
+ env[:lxc_template_src].should == box_directory.join('lxc-template').to_s
43
+ end
38
44
  end
39
45
 
40
- it 'extracts rootfs into a tmp folder' do
41
- subject.should have_received(:system).
42
- with(%Q[sudo su root -c "cd #{box_directory} && tar xfz rootfs.tar.gz -C #{tmpdir} 2>/dev/null"])
46
+ describe 'with invalid contents' do
47
+ before { File.stub(exists?: true) }
48
+
49
+ it 'raises an error if the version is != 2' do
50
+ metadata['version'] = '1'
51
+ expect {
52
+ subject.call(env)
53
+ }.to raise_error(Vagrant::LXC::Errors::InvalidBoxVersion)
54
+ end
55
+
56
+ it 'raises an error if the rootfs tarball cant be found' do
57
+ File.stub(:exists?).with(box_directory.join('rootfs.tar.gz').to_s).and_return(false)
58
+ expect {
59
+ subject.call(env)
60
+ }.to raise_error(Vagrant::LXC::Errors::RootFSTarballMissing)
61
+ end
62
+
63
+ it 'raises an error if the lxc-template script cant be found' do
64
+ File.stub(:exists?).with(box_directory.join('lxc-template').to_s).and_return(false)
65
+ expect {
66
+ subject.call(env)
67
+ }.to raise_error(Vagrant::LXC::Errors::TemplateFileMissing)
68
+ end
43
69
  end
44
70
  end
@@ -1,12 +1,10 @@
1
1
  require 'unit_helper'
2
2
 
3
- require 'vagrant'
4
- require 'vagrant-lxc/container/cli'
3
+ require 'vagrant-lxc/driver/cli'
5
4
 
6
- describe Vagrant::LXC::Container::CLI do
5
+ describe Vagrant::LXC::Driver::CLI do
7
6
  describe 'list' do
8
7
  let(:lxc_ls_out) { "dup-container\na-container dup-container" }
9
- let(:exec_args) { @exec_args }
10
8
  let(:result) { @result }
11
9
 
12
10
  before do
@@ -25,6 +23,18 @@ describe Vagrant::LXC::Container::CLI do
25
23
  end
26
24
  end
27
25
 
26
+ describe 'version' do
27
+ let(:lxc_version_out) { "lxc version: 0.x.y-rc1\n" }
28
+
29
+ before do
30
+ subject.stub(:run).with(:version).and_return(lxc_version_out)
31
+ end
32
+
33
+ it 'parses the version from the output' do
34
+ subject.version.should == '0.x.y-rc1'
35
+ end
36
+ end
37
+
28
38
  describe 'create' do
29
39
  let(:template) { 'quantal-64' }
30
40
  let(:name) { 'quantal-container' }
@@ -34,12 +44,9 @@ describe Vagrant::LXC::Container::CLI do
34
44
 
35
45
  before do
36
46
  subject.stub(:run) { |*args| @run_args = args }
37
- subject.create(template, rootfs, template_args)
47
+ subject.create(template, template_args)
38
48
  end
39
49
 
40
- context 'when no rootfs is passed' do
41
- let(:rootfs) { nil }
42
-
43
50
  it 'issues a lxc-create with provided template, container name and hash of arguments' do
44
51
  subject.should have_received(:run).with(
45
52
  :create,
@@ -50,15 +57,6 @@ describe Vagrant::LXC::Container::CLI do
50
57
  '--other', 'value'
51
58
  )
52
59
  end
53
- end
54
-
55
- context 'when the rootfs is passed' do
56
- let(:rootfs) { 'rootfs_path' }
57
-
58
- it 'issues a lxc-create with the right rootfs arguments' do
59
- @run_args.join(' ').should =~ /-B dir --dir #{rootfs}/
60
- end
61
- end
62
60
  end
63
61
 
64
62
  describe 'destroy' do
@@ -93,8 +91,8 @@ describe Vagrant::LXC::Container::CLI do
93
91
  )
94
92
  end
95
93
 
96
- it 'uses provided hash to configure the container' do
97
- subject.start(['lxc.config=value', 'lxc.other=value'])
94
+ it 'uses provided array to override container configs' do
95
+ subject.start([['config', 'value'], ['other', 'value']])
98
96
  subject.should have_received(:run).with(:start, '-d', '--name', name,
99
97
  '-s', 'lxc.config=value',
100
98
  '-s', 'lxc.other=value'
@@ -0,0 +1,173 @@
1
+ require 'unit_helper'
2
+
3
+ require 'vagrant'
4
+ require 'vagrant-lxc/driver'
5
+
6
+ describe Vagrant::LXC::Driver do
7
+ describe 'container name validation' do
8
+ let(:unknown_container) { described_class.new('unknown', cli) }
9
+ let(:valid_container) { described_class.new('valid', cli) }
10
+ let(:new_container) { described_class.new(nil) }
11
+ let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', list: ['valid']) }
12
+
13
+ it 'raises a ContainerNotFound error if an unknown container name gets provided' do
14
+ expect {
15
+ unknown_container.validate!
16
+ }.to raise_error(Vagrant::LXC::Driver::ContainerNotFound)
17
+ end
18
+
19
+ it 'does not raise a ContainerNotFound error if a valid container name gets provided' do
20
+ expect {
21
+ valid_container.validate!
22
+ }.to_not raise_error(Vagrant::LXC::Driver::ContainerNotFound)
23
+ end
24
+
25
+ it 'does not raise a ContainerNotFound error if nil is provider as name' do
26
+ expect {
27
+ new_container.validate!
28
+ }.to_not raise_error(Vagrant::LXC::Driver::ContainerNotFound)
29
+ end
30
+ end
31
+
32
+ describe 'creation' do
33
+ let(:name) { 'container-name' }
34
+ let(:template_name) { 'auto-assigned-template-id' }
35
+ let(:template_path) { '/path/to/lxc-template-from-box' }
36
+ let(:template_opts) { {'--some' => 'random-option'} }
37
+ let(:rootfs_tarball) { '/path/to/cache/rootfs.tar.gz' }
38
+ let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', :create => true, :name= => true) }
39
+
40
+ subject { described_class.new(nil, cli) }
41
+
42
+ before do
43
+ subject.stub(:import_template).and_yield(template_name)
44
+ subject.create name, template_path, template_opts
45
+ end
46
+
47
+ it 'sets the cli object container name' do
48
+ cli.should have_received(:name=).with(name)
49
+ end
50
+
51
+ it 'creates container with the right arguments' do
52
+ cli.should have_received(:create).with(
53
+ template_name,
54
+ template_opts
55
+ )
56
+ end
57
+ end
58
+
59
+ describe 'destruction' do
60
+ let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', destroy: true) }
61
+
62
+ subject { described_class.new('name', cli) }
63
+
64
+ before { subject.destroy }
65
+
66
+ it 'delegates to cli object' do
67
+ cli.should have_received(:destroy)
68
+ end
69
+ end
70
+
71
+ describe 'start' do
72
+ let(:customizations) { [['a', '1'], ['b', '2']] }
73
+ let(:internal_customization) { ['internal', 'customization'] }
74
+ let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', start: true) }
75
+
76
+ subject { described_class.new('name', cli) }
77
+
78
+ before do
79
+ cli.stub(:transition_to).and_yield(cli)
80
+ subject.customizations << internal_customization
81
+ subject.start(customizations)
82
+ end
83
+
84
+ it 'starts container with configured customizations' do
85
+ cli.should have_received(:start).with(customizations + [internal_customization], nil)
86
+ end
87
+
88
+ it 'expects a transition to running state to take place' do
89
+ cli.should have_received(:transition_to).with(:running)
90
+ end
91
+ end
92
+
93
+ describe 'halt' do
94
+ let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', shutdown: true) }
95
+
96
+ subject { described_class.new('name', cli) }
97
+
98
+ before do
99
+ cli.stub(:transition_to).and_yield(cli)
100
+ end
101
+
102
+ it 'delegates to cli shutdown' do
103
+ cli.should_receive(:shutdown)
104
+ subject.halt
105
+ end
106
+
107
+ it 'expects a transition to running state to take place' do
108
+ cli.should_receive(:transition_to).with(:stopped)
109
+ subject.halt
110
+ end
111
+ end
112
+
113
+ describe 'state' do
114
+ let(:cli_state) { :something }
115
+ let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', state: cli_state) }
116
+
117
+ subject { described_class.new('name', cli) }
118
+
119
+ it 'delegates to cli' do
120
+ subject.state.should == cli_state
121
+ end
122
+ end
123
+
124
+ pending 'assigned ip' do
125
+ # This ip is set on the sample-ip-addr-output fixture
126
+ let(:ip) { "10.0.254.137" }
127
+ let(:ifconfig_output) { File.read('spec/fixtures/sample-ip-addr-output') }
128
+ let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', :attach => ifconfig_output) }
129
+
130
+ subject { described_class.new('name', cli) }
131
+
132
+ context 'when ip for eth0 gets returned from lxc-attach call' do
133
+ it 'gets parsed from `ip addr` output' do
134
+ subject.assigned_ip.should == ip
135
+ cli.should have_received(:attach).with(
136
+ '/sbin/ip',
137
+ '-4',
138
+ 'addr',
139
+ 'show',
140
+ 'scope',
141
+ 'global',
142
+ 'eth0',
143
+ namespaces: 'network'
144
+ )
145
+ end
146
+ end
147
+ end
148
+
149
+ describe 'folder sharing' do
150
+ let(:shared_folder) { {guestpath: '/vagrant', hostpath: '/path/to/host/dir'} }
151
+ let(:folders) { [shared_folder] }
152
+ let(:rootfs_path) { Pathname('/path/to/rootfs') }
153
+ let(:expected_guest_path) { "#{rootfs_path}/vagrant" }
154
+
155
+ subject { described_class.new('name') }
156
+
157
+ before do
158
+ subject.stub(rootfs_path: rootfs_path, system: true)
159
+ subject.share_folders(folders)
160
+ end
161
+
162
+ it "creates guest folder under container's rootfs" do
163
+ subject.should have_received(:system).with("sudo mkdir -p #{expected_guest_path}")
164
+ end
165
+
166
+ it 'adds a mount.entry to its local customizations' do
167
+ subject.customizations.should include [
168
+ 'mount.entry',
169
+ "#{shared_folder[:hostpath]} #{expected_guest_path} none bind 0 0"
170
+ ]
171
+ end
172
+ end
173
+ end
data/tasks/boxes.rake CHANGED
@@ -10,9 +10,9 @@ namespace :boxes do
10
10
  sh 'mkdir -p boxes/output'
11
11
  sh 'cd boxes/quantal64 && sudo ./download-ubuntu'
12
12
  sh 'rm -f boxes/quantal64/rootfs.tar.gz'
13
- sh 'cd boxes/quantal64 && sudo tar --numeric-owner -czf rootfs.tar.gz ./rootfs-amd64/*'
14
- sh "cd boxes/quantal64 && sudo chown #{ENV['USER']}:#{ENV['USER']} rootfs.tar.gz && tar -czf ../output/lxc-quantal64.box ./* --exclude=rootfs-amd64 --exclude=download-ubuntu"
15
- sh 'cd boxes/quantal64 && sudo rm -rf rootfs-amd64'
13
+ sh 'cd boxes/quantal64 && sudo tar --numeric-owner -czf rootfs.tar.gz ./rootfs/*'
14
+ sh 'cd boxes/quantal64 && sudo rm -rf rootfs'
15
+ sh "cd boxes/quantal64 && sudo chown #{ENV['USER']}:#{ENV['USER']} rootfs.tar.gz && tar -czf ../output/lxc-quantal64.box ./* --exclude=download-ubuntu"
16
16
  end
17
17
  end
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-lxc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Rehm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-31 00:00:00.000000000 Z
11
+ date: 2013-04-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Linux Containers provider for Vagrant
14
14
  email:
@@ -42,7 +42,6 @@ files:
42
42
  - example/puppet/modules/hello_world/manifests/init.pp
43
43
  - lib/vagrant-lxc.rb
44
44
  - lib/vagrant-lxc/action.rb
45
- - lib/vagrant-lxc/action/base_action.rb
46
45
  - lib/vagrant-lxc/action/boot.rb
47
46
  - lib/vagrant-lxc/action/check_created.rb
48
47
  - lib/vagrant-lxc/action/check_running.rb
@@ -56,19 +55,20 @@ files:
56
55
  - lib/vagrant-lxc/action/forward_ports.rb
57
56
  - lib/vagrant-lxc/action/handle_box_metadata.rb
58
57
  - lib/vagrant-lxc/action/is_running.rb
59
- - lib/vagrant-lxc/action/network.rb
60
58
  - lib/vagrant-lxc/action/setup_package_files.rb
61
59
  - lib/vagrant-lxc/action/share_folders.rb
62
60
  - lib/vagrant-lxc/config.rb
63
- - lib/vagrant-lxc/container.rb
64
- - lib/vagrant-lxc/container/cli.rb
61
+ - lib/vagrant-lxc/driver.rb
62
+ - lib/vagrant-lxc/driver/builder.rb
63
+ - lib/vagrant-lxc/driver/cli.rb
64
+ - lib/vagrant-lxc/driver/fetch_ip_from_dnsmasq.rb
65
+ - lib/vagrant-lxc/driver/fetch_ip_with_attach.rb
65
66
  - lib/vagrant-lxc/errors.rb
66
- - lib/vagrant-lxc/machine_state.rb
67
67
  - lib/vagrant-lxc/plugin.rb
68
68
  - lib/vagrant-lxc/provider.rb
69
69
  - lib/vagrant-lxc/version.rb
70
70
  - locales/en.yml
71
- - spec/fixtures/sample-ifconfig-output
71
+ - spec/fixtures/sample-ip-addr-output
72
72
  - spec/spec_helper.rb
73
73
  - spec/support/unit_example_group.rb
74
74
  - spec/unit/action/clear_forwarded_ports_spec.rb
@@ -76,9 +76,8 @@ files:
76
76
  - spec/unit/action/forward_ports_spec.rb
77
77
  - spec/unit/action/handle_box_metadata_spec.rb
78
78
  - spec/unit/action/setup_package_files_spec.rb
79
- - spec/unit/container/cli_spec.rb
80
- - spec/unit/container_spec.rb
81
- - spec/unit/machine_state_spec.rb
79
+ - spec/unit/driver/cli_spec.rb
80
+ - spec/unit/driver_spec.rb
82
81
  - spec/unit_helper.rb
83
82
  - tasks/boxes.rake
84
83
  - tasks/spec.rake
@@ -107,7 +106,7 @@ signing_key:
107
106
  specification_version: 4
108
107
  summary: Linux Containers provider for Vagrant
109
108
  test_files:
110
- - spec/fixtures/sample-ifconfig-output
109
+ - spec/fixtures/sample-ip-addr-output
111
110
  - spec/spec_helper.rb
112
111
  - spec/support/unit_example_group.rb
113
112
  - spec/unit/action/clear_forwarded_ports_spec.rb
@@ -115,7 +114,6 @@ test_files:
115
114
  - spec/unit/action/forward_ports_spec.rb
116
115
  - spec/unit/action/handle_box_metadata_spec.rb
117
116
  - spec/unit/action/setup_package_files_spec.rb
118
- - spec/unit/container/cli_spec.rb
119
- - spec/unit/container_spec.rb
120
- - spec/unit/machine_state_spec.rb
117
+ - spec/unit/driver/cli_spec.rb
118
+ - spec/unit/driver_spec.rb
121
119
  - spec/unit_helper.rb