vagrant-lxc-2.1-patch 1.4.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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +31 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +10 -0
  5. data/.vimrc +1 -0
  6. data/BOXES.md +47 -0
  7. data/CHANGELOG.md +510 -0
  8. data/CONTRIBUTING.md +24 -0
  9. data/Gemfile +24 -0
  10. data/Guardfile +7 -0
  11. data/LICENSE.txt +22 -0
  12. data/README.md +187 -0
  13. data/Rakefile +3 -0
  14. data/lib/vagrant-lxc.rb +10 -0
  15. data/lib/vagrant-lxc/action.rb +234 -0
  16. data/lib/vagrant-lxc/action/boot.rb +42 -0
  17. data/lib/vagrant-lxc/action/clear_forwarded_ports.rb +56 -0
  18. data/lib/vagrant-lxc/action/compress_rootfs.rb +30 -0
  19. data/lib/vagrant-lxc/action/create.rb +57 -0
  20. data/lib/vagrant-lxc/action/destroy.rb +18 -0
  21. data/lib/vagrant-lxc/action/destroy_confirm.rb +17 -0
  22. data/lib/vagrant-lxc/action/fetch_ip_with_lxc_info.rb +43 -0
  23. data/lib/vagrant-lxc/action/forced_halt.rb +20 -0
  24. data/lib/vagrant-lxc/action/forward_ports.rb +121 -0
  25. data/lib/vagrant-lxc/action/gc_private_network_bridges.rb +47 -0
  26. data/lib/vagrant-lxc/action/handle_box_metadata.rb +94 -0
  27. data/lib/vagrant-lxc/action/prepare_nfs_settings.rb +64 -0
  28. data/lib/vagrant-lxc/action/prepare_nfs_valid_ids.rb +19 -0
  29. data/lib/vagrant-lxc/action/private_networks.rb +46 -0
  30. data/lib/vagrant-lxc/action/setup_package_files.rb +60 -0
  31. data/lib/vagrant-lxc/action/warn_networks.rb +25 -0
  32. data/lib/vagrant-lxc/command/root.rb +58 -0
  33. data/lib/vagrant-lxc/command/sudoers.rb +97 -0
  34. data/lib/vagrant-lxc/config.rb +73 -0
  35. data/lib/vagrant-lxc/driver.rb +288 -0
  36. data/lib/vagrant-lxc/driver/cli.rb +166 -0
  37. data/lib/vagrant-lxc/errors.rb +62 -0
  38. data/lib/vagrant-lxc/plugin.rb +51 -0
  39. data/lib/vagrant-lxc/provider.rb +101 -0
  40. data/lib/vagrant-lxc/provider/cap/public_address.rb +17 -0
  41. data/lib/vagrant-lxc/sudo_wrapper.rb +104 -0
  42. data/lib/vagrant-lxc/synced_folder.rb +72 -0
  43. data/lib/vagrant-lxc/version.rb +5 -0
  44. data/locales/en.yml +82 -0
  45. data/scripts/lxc-template +171 -0
  46. data/scripts/pipework +422 -0
  47. data/spec/Vagrantfile +26 -0
  48. data/spec/fixtures/sample-ip-addr-output +2 -0
  49. data/spec/spec_helper.rb +35 -0
  50. data/spec/support/.gitkeep +0 -0
  51. data/spec/unit/action/clear_forwarded_ports_spec.rb +43 -0
  52. data/spec/unit/action/compress_rootfs_spec.rb +29 -0
  53. data/spec/unit/action/forward_ports_spec.rb +117 -0
  54. data/spec/unit/action/handle_box_metadata_spec.rb +126 -0
  55. data/spec/unit/action/setup_package_files_spec.rb +83 -0
  56. data/spec/unit/driver/cli_spec.rb +263 -0
  57. data/spec/unit/driver_spec.rb +268 -0
  58. data/spec/unit/support/unit_example_group.rb +38 -0
  59. data/spec/unit_helper.rb +17 -0
  60. data/tasks/spec.rake +40 -0
  61. data/templates/sudoers.rb.erb +129 -0
  62. data/vagrant-lxc.gemspec +20 -0
  63. data/vagrant-spec.config.rb +24 -0
  64. metadata +119 -0
@@ -0,0 +1,26 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.require_plugin 'vagrant-lxc'
5
+ Vagrant.require_plugin 'vagrant-cachier'
6
+
7
+ ENV['BOX_NAME'] ||= 'quantal64'
8
+ puts "Running vagrant commands using #{ENV['BOX_NAME']} box"
9
+
10
+ Vagrant.configure("2") do |config|
11
+ config.vm.box = ENV['BOX_NAME']
12
+ config.vm.hostname = 'lxc-test-box'
13
+ config.vm.box_url = ENV['BOX_URL']
14
+ config.vm.network :forwarded_port, guest: 80, host: 8080
15
+
16
+ config.cache.auto_detect = true
17
+
18
+ config.vm.provision :shell,
19
+ inline: 'mkdir -p /vagrant/tmp && echo -n "Provisioned" > /vagrant/tmp/provisioning'
20
+
21
+ config.vm.provision :shell,
22
+ inline: 'apt-get install apache2 -y'
23
+
24
+ config.vm.provision :shell, privileged: false,
25
+ inline: "if ! [ -f $HOME/original-box ]; then echo '#{ENV['BOX_NAME']}' > $HOME/original-box; fi"
26
+ end
@@ -0,0 +1,2 @@
1
+ 49: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
2
+ inet 10.0.254.137/24 brd 10.0.254.255 scope global eth0
@@ -0,0 +1,35 @@
1
+ if ENV['COVERAGE']
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.start { add_filter '/spec/' }
6
+ SimpleCov.merge_timeout 300
7
+ end
8
+
9
+ require 'bundler/setup'
10
+
11
+ require 'i18n'
12
+
13
+ require 'vagrant-lxc'
14
+
15
+ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each { |f| require f }
16
+
17
+ RSpec.configure do |config|
18
+ config.treat_symbols_as_metadata_keys_with_true_values = true
19
+ config.run_all_when_everything_filtered = true
20
+ config.filter_run :focus
21
+
22
+ # Run specs in random order to surface order dependencies. If you find an
23
+ # order dependency and want to debug it, you can fix the order by providing
24
+ # the seed, which is printed after each run.
25
+ # --seed 1234
26
+ config.order = 'random'
27
+
28
+ config.mock_with :rspec do |c|
29
+ c.yield_receiver_to_any_instance_implementation_blocks = true
30
+ end
31
+ config.expect_with :rspec do |c|
32
+ c.syntax = :expect
33
+ end
34
+ config.raise_errors_for_deprecations!
35
+ end
File without changes
@@ -0,0 +1,43 @@
1
+ require 'unit_helper'
2
+
3
+ require 'tmpdir'
4
+ require 'vagrant-lxc/action/clear_forwarded_ports'
5
+
6
+ describe Vagrant::LXC::Action::ClearForwardedPorts do
7
+ let(:app) { double(:app, call: true) }
8
+ let(:env) { {machine: machine, ui: double(info: true)} }
9
+ let(:machine) { double(:machine, data_dir: data_dir) }
10
+ let!(:data_dir) { Pathname.new(Dir.mktmpdir) }
11
+ let(:pids_dir) { data_dir.join('pids') }
12
+ let(:pid) { 'a-pid' }
13
+ let(:pid_cmd) { 'redir' }
14
+
15
+ subject { described_class.new(app, env) }
16
+
17
+ before do
18
+ pids_dir.mkdir
19
+ pids_dir.join('redir_1234.pid').open('w') { |f| f.write(pid) }
20
+ subject.stub(system: true, :` => pid_cmd)
21
+ subject.call(env)
22
+ end
23
+
24
+ after { FileUtils.rm_rf data_dir.to_s }
25
+
26
+ it 'removes all files under pid directory' do
27
+ expect(Dir[pids_dir.to_s + "/redir_*.pid"]).to be_empty
28
+ end
29
+
30
+ context 'with a valid redir pid' do
31
+ it 'kills known processes' do
32
+ expect(subject).to have_received(:system).with("pkill -TERM -P #{pid}")
33
+ end
34
+ end
35
+
36
+ context 'with an invalid pid' do
37
+ let(:pid_cmd) { 'sudo ls' }
38
+
39
+ it 'does not kill the process' do
40
+ expect(subject).not_to have_received(:system).with("pkill -TERM -P #{pid}")
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ require 'unit_helper'
2
+
3
+ require 'vagrant-lxc/plugin'
4
+ require 'vagrant-lxc/provider'
5
+ require 'vagrant-lxc/action/compress_rootfs'
6
+
7
+ describe Vagrant::LXC::Action::CompressRootFS do
8
+ let(:app) { double(:app, call: true) }
9
+ let(:env) { {machine: machine, ui: double(info: true)} }
10
+ let(:machine) { double(Vagrant::Machine, provider: provider) }
11
+ let(:provider) { double(Vagrant::LXC::Provider, driver: driver) }
12
+ let(:driver) { double(Vagrant::LXC::Driver, compress_rootfs: compressed_rootfs_path) }
13
+ let(:compressed_rootfs_path) { '/path/to/rootfs.tar.gz' }
14
+
15
+ subject { described_class.new(app, env) }
16
+
17
+ before do
18
+ provider.stub_chain(:state, :id).and_return(:stopped)
19
+ subject.call(env)
20
+ end
21
+
22
+ it "asks the driver to compress container's rootfs" do
23
+ expect(driver).to have_received(:compress_rootfs)
24
+ end
25
+
26
+ it 'sets export.temp_dir on action env' do
27
+ expect(env['package.rootfs']).to eq(compressed_rootfs_path)
28
+ end
29
+ end
@@ -0,0 +1,117 @@
1
+ require 'unit_helper'
2
+
3
+ require 'tmpdir'
4
+ require 'vagrant-lxc/provider'
5
+ require 'vagrant-lxc/action/forward_ports'
6
+
7
+ describe Vagrant::LXC::Action::ForwardPorts do
8
+ let(:app) { double(:app, call: true) }
9
+ let(:env) { {machine: machine, ui: double(info: true, warn: true)} }
10
+ let(:machine) { double(:machine) }
11
+ let!(:data_dir) { Pathname.new(Dir.mktmpdir) }
12
+ let(:provider) { double(Vagrant::LXC::Provider, ssh_info: {host: container_ip}) }
13
+ let(:host_ip) { '127.0.0.1' }
14
+ let(:host_port) { 8080 }
15
+ let(:guest_port) { 80 }
16
+ let(:container_ip) { '10.0.1.234' }
17
+ let(:pid) { 'a-pid' }
18
+ let(:forward_conf) { {guest: guest_port, host: host_port, host_ip: host_ip} }
19
+ let(:networks) { [[:other_config, {}], [:forwarded_port, forward_conf]] }
20
+
21
+ subject { described_class.new(app, env) }
22
+
23
+ before do
24
+ machine.stub_chain(:config, :vm, :networks).and_return(networks)
25
+ machine.stub(provider: provider, data_dir: data_dir)
26
+
27
+ subject.stub(redir_version: 3)
28
+ subject.stub(exec: true)
29
+ subject.stub(spawn: pid)
30
+ end
31
+
32
+ after { FileUtils.rm_rf data_dir.to_s }
33
+
34
+ it 'forwards ports using redir' do
35
+ subject.stub(system: true)
36
+ subject.call(env)
37
+ expect(subject).to have_received(:spawn).with(
38
+ "redir #{host_ip}:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
39
+ )
40
+ end
41
+
42
+ it 'Uses 127.0.0.1 as default if host_ip is nil' do
43
+ forward_conf.delete(:host_ip)
44
+ subject.stub(system: true)
45
+ subject.call(env)
46
+ expect(subject).to have_received(:spawn).with(
47
+ "redir 127.0.0.1:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
48
+ )
49
+ end
50
+
51
+ it 'Uses 127.0.0.1 by default if host_ip is a blank string' do
52
+ forward_conf[:host_ip] = ' '
53
+ subject.stub(system: true)
54
+ subject.call(env)
55
+ expect(subject).to have_received(:spawn).with(
56
+ "redir 127.0.0.1:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
57
+ )
58
+ end
59
+
60
+ it "stores redir pids on machine's data dir" do
61
+ subject.stub(system: true)
62
+ subject.call(env)
63
+ pid_file = data_dir.join('pids', "redir_#{host_port}.pid").read
64
+ expect(pid_file).to eq(pid)
65
+ end
66
+
67
+ it 'allows disabling a previously forwarded port' do
68
+ forward_conf[:disabled] = true
69
+ subject.stub(system: true)
70
+ subject.call(env)
71
+ expect(subject).not_to have_received(:spawn)
72
+ end
73
+
74
+ it 'uses redir 2.x command line interface' do
75
+ subject.stub(system: true)
76
+ subject.stub(redir_version: 2)
77
+ subject.call(env)
78
+ expect(subject).to have_received(:spawn).with(
79
+ "redir --laddr=#{host_ip} --lport=#{host_port} --caddr=#{container_ip} --cport=#{guest_port} 2>/dev/null"
80
+ )
81
+ end
82
+
83
+ it 'raises RedirNotInstalled error if `redir` is not installed' do
84
+ subject.stub(system: false)
85
+ expect { subject.call(env) }.to raise_error(Vagrant::LXC::Errors::RedirNotInstalled)
86
+ end
87
+
88
+ context 'when a privileged port is used' do
89
+ let(:host_port) { 80 }
90
+
91
+ it 'forwards ports using redir' do
92
+ subject.stub(system: true)
93
+ subject.call(env)
94
+ expect(subject).to have_received(:spawn).with(
95
+ "sudo redir #{host_ip}:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
96
+ )
97
+ end
98
+
99
+ it 'Uses 127.0.0.1 by default if host_ip is nil' do
100
+ forward_conf.delete(:host_ip)
101
+ subject.stub(system: true)
102
+ subject.call(env)
103
+ expect(subject).to have_received(:spawn).with(
104
+ "sudo redir 127.0.0.1:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
105
+ )
106
+ end
107
+
108
+ it 'Uses 127.0.0.1 by default if host_ip is a blank string' do
109
+ forward_conf[:host_ip] = ' '
110
+ subject.stub(system: true)
111
+ subject.call(env)
112
+ expect(subject).to have_received(:spawn).with(
113
+ "sudo redir 127.0.0.1:#{host_port} #{container_ip}:#{guest_port} 2>/dev/null"
114
+ )
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,126 @@
1
+ require 'unit_helper'
2
+
3
+ require 'vagrant'
4
+ require 'vagrant-lxc/errors'
5
+ require 'vagrant-lxc/action/handle_box_metadata'
6
+
7
+ describe Vagrant::LXC::Action::HandleBoxMetadata do
8
+ let(:app) { double(:app, call: true) }
9
+ let(:env) { {machine: machine, ui: double(info: true, warn: true)} }
10
+ let(:machine) { double(:machine, box: box) }
11
+ let(:box) { double(: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 }
16
+
17
+ subject { described_class.new(app, env) }
18
+
19
+ context 'with 1.0.0 box' do
20
+ let(:version) { '1.0.0' }
21
+
22
+ before do
23
+ File.stub(exists?: true)
24
+ # REFACTOR: This is pretty bad
25
+ subject.stub_chain(:template_config_file, :exist?).and_return(true)
26
+ subject.stub_chain(:template_config_file, :to_s).and_return(box_directory.join('lxc-config').to_s)
27
+ subject.call(env)
28
+ end
29
+
30
+ it 'sets the tarball argument for the template' do
31
+ expect(env[:lxc_template_opts]).to include(
32
+ '--tarball' => box_directory.join('rootfs.tar.gz').to_s
33
+ )
34
+ end
35
+
36
+ it 'sets the template --config parameter' do
37
+ expect(env[:lxc_template_opts]).to include(
38
+ '--config' => box_directory.join('lxc-config').to_s
39
+ )
40
+ end
41
+
42
+ it 'does not set the auth key argument for the template' do
43
+ expect(env[:lxc_template_opts]).not_to include(
44
+ '--auth-key' => vagrant_key
45
+ )
46
+ end
47
+
48
+ it 'sets the template options from metadata on env hash' do
49
+ expect(env[:lxc_template_opts]).to include(metadata['template-opts'])
50
+ end
51
+
52
+ xit 'sets the template source path on env hash' do
53
+ expect(env[:lxc_template_src]).to eq(box_directory.join('lxc-template').to_s)
54
+ end
55
+
56
+ it 'does not warn about deprecation' do
57
+ expect(env[:ui]).not_to have_received(:warn)
58
+ end
59
+ end
60
+
61
+ context 'with valid pre 1.0.0 box' do
62
+ before do
63
+ File.stub(exists?: true)
64
+ # REFACTOR: This is pretty bad
65
+ subject.stub_chain(:old_template_config_file, :exist?).and_return(true)
66
+ subject.stub_chain(:old_template_config_file, :to_s).and_return(box_directory.join('lxc.conf').to_s)
67
+ subject.call(env)
68
+ end
69
+
70
+ it 'sets the tarball argument for the template' do
71
+ expect(env[:lxc_template_opts]).to include(
72
+ '--tarball' => box_directory.join('rootfs.tar.gz').to_s
73
+ )
74
+ end
75
+
76
+ it 'sets the auth key argument for the template' do
77
+ expect(env[:lxc_template_opts]).to include(
78
+ '--auth-key' => vagrant_key
79
+ )
80
+ end
81
+
82
+ it 'sets the lxc config file parameter' do
83
+ expect(env[:lxc_template_config]).to eq(box_directory.join('lxc.conf').to_s)
84
+ end
85
+
86
+ it 'sets the template options from metadata on env hash' do
87
+ expect(env[:lxc_template_opts]).to include(metadata['template-opts'])
88
+ end
89
+
90
+ xit 'sets the template source path on env hash' do
91
+ expect(env[:lxc_template_src]).to eq(box_directory.join('lxc-template').to_s)
92
+ end
93
+
94
+ it 'warns about deprecation' do
95
+ expect(env[:ui]).to have_received(:warn)
96
+ end
97
+ end
98
+
99
+ describe 'with invalid contents' do
100
+ before { File.stub(exists?: true) }
101
+
102
+ it 'validates box versions' do
103
+ %w( 2 3 1.0.0 ).each do |v|
104
+ metadata['version'] = v
105
+ expect { subject.call(env) }.to_not raise_error
106
+ end
107
+
108
+ metadata['version'] = '1'
109
+ expect { subject.call(env) }.to raise_error
110
+ end
111
+
112
+ it 'raises an error if the rootfs tarball cant be found' do
113
+ allow(File).to receive(:exists?).with(box_directory.join('rootfs.tar.gz').to_s).and_return(false)
114
+ expect {
115
+ subject.call(env)
116
+ }.to raise_error(Vagrant::LXC::Errors::RootFSTarballMissing)
117
+ end
118
+
119
+ it 'does not raise an error if the lxc-template script cant be found' do
120
+ allow(File).to receive(:exists?).with(box_directory.join('lxc-template').to_s).and_return(false)
121
+ expect {
122
+ subject.call(env)
123
+ }.to_not raise_error
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,83 @@
1
+ require 'unit_helper'
2
+
3
+ require 'vagrant-lxc/action/setup_package_files'
4
+
5
+ describe Vagrant::LXC::Action::SetupPackageFiles do
6
+ let(:app) { double(:app, call: true) }
7
+ let(:env) { {machine: machine, tmp_path: tmp_path, ui: double(info: true), 'package.rootfs' => rootfs_path} }
8
+ let(:machine) { double(Vagrant::Machine, box: box) }
9
+ let!(:tmp_path) { Pathname.new(Dir.mktmpdir) }
10
+ let(:box) { double(Vagrant::Box, directory: tmp_path.join('box')) }
11
+ let(:rootfs_path) { tmp_path.join('rootfs-amd64.tar.gz') }
12
+
13
+ subject { described_class.new(app, env) }
14
+
15
+ before do
16
+ box.directory.mkdir
17
+ files = %w( lxc-template metadata.json lxc.conf lxc-config ).map { |f| box.directory.join(f) }
18
+ (files + [rootfs_path]).each do |file|
19
+ file.open('w') { |f| f.puts file.to_s }
20
+ end
21
+
22
+ subject.stub(recover: true) # Prevents files from being removed on specs
23
+ end
24
+
25
+ after do
26
+ FileUtils.rm_rf(tmp_path.to_s)
27
+ end
28
+
29
+ context 'when all files exist' do
30
+ before { subject.call(env) }
31
+
32
+ it 'copies box lxc-template to package directory' do
33
+ expect(env['package.directory'].join('lxc-template')).to be_file
34
+ end
35
+
36
+ it 'copies metadata.json to package directory' do
37
+ expect(env['package.directory'].join('metadata.json')).to be_file
38
+ end
39
+
40
+ it 'copies box lxc.conf to package directory' do
41
+ expect(env['package.directory'].join('lxc-template')).to be_file
42
+ end
43
+
44
+ it 'copies box lxc-config to package directory' do
45
+ expect(env['package.directory'].join('lxc-config')).to be_file
46
+ end
47
+
48
+ it 'moves the compressed rootfs to package directory' do
49
+ expect(env['package.directory'].join(rootfs_path.basename)).to be_file
50
+ expect(env['package.rootfs']).not_to be_file
51
+ end
52
+ end
53
+
54
+ context 'when lxc-template file is not present' do
55
+ before do
56
+ box.directory.join('lxc-template').delete
57
+ end
58
+
59
+ it 'does not blow up' do
60
+ expect { subject.call(env) }.to_not raise_error
61
+ end
62
+ end
63
+
64
+ context 'when lxc.conf file is not present' do
65
+ before do
66
+ box.directory.join('lxc.conf').delete
67
+ end
68
+
69
+ it 'does not blow up' do
70
+ expect { subject.call(env) }.to_not raise_error
71
+ end
72
+ end
73
+
74
+ context 'when lxc-config file is not present' do
75
+ before do
76
+ box.directory.join('lxc-config').delete
77
+ end
78
+
79
+ it 'does not blow up' do
80
+ expect { subject.call(env) }.to_not raise_error
81
+ end
82
+ end
83
+ end