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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.vimrc +1 -1
- data/CHANGELOG.md +22 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +10 -9
- data/README.md +43 -29
- data/boxes/quantal64/download-ubuntu +21 -20
- data/boxes/quantal64/lxc-template +11 -11
- data/boxes/quantal64/metadata.json +1 -1
- data/development/Vagrantfile +8 -4
- data/example/Vagrantfile +3 -15
- data/lib/vagrant-lxc.rb +0 -2
- data/lib/vagrant-lxc/action.rb +1 -14
- data/lib/vagrant-lxc/action/boot.rb +8 -9
- data/lib/vagrant-lxc/action/check_created.rb +6 -2
- data/lib/vagrant-lxc/action/check_running.rb +6 -2
- data/lib/vagrant-lxc/action/compress_rootfs.rb +1 -1
- data/lib/vagrant-lxc/action/create.rb +15 -7
- data/lib/vagrant-lxc/action/created.rb +6 -2
- data/lib/vagrant-lxc/action/destroy.rb +6 -2
- data/lib/vagrant-lxc/action/disconnect.rb +5 -1
- data/lib/vagrant-lxc/action/forced_halt.rb +3 -3
- data/lib/vagrant-lxc/action/forward_ports.rb +2 -2
- data/lib/vagrant-lxc/action/handle_box_metadata.rb +38 -27
- data/lib/vagrant-lxc/action/is_running.rb +6 -2
- data/lib/vagrant-lxc/action/share_folders.rb +8 -8
- data/lib/vagrant-lxc/config.rb +20 -10
- data/lib/vagrant-lxc/driver.rb +162 -0
- data/lib/vagrant-lxc/driver/builder.rb +21 -0
- data/lib/vagrant-lxc/{container → driver}/cli.rb +16 -11
- data/lib/vagrant-lxc/driver/fetch_ip_from_dnsmasq.rb +41 -0
- data/lib/vagrant-lxc/driver/fetch_ip_with_attach.rb +29 -0
- data/lib/vagrant-lxc/errors.rb +10 -0
- data/lib/vagrant-lxc/plugin.rb +4 -0
- data/lib/vagrant-lxc/provider.rb +14 -11
- data/lib/vagrant-lxc/version.rb +1 -1
- data/spec/fixtures/sample-ip-addr-output +2 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/action/compress_rootfs_spec.rb +4 -4
- data/spec/unit/action/forward_ports_spec.rb +3 -3
- data/spec/unit/action/handle_box_metadata_spec.rb +52 -26
- data/spec/unit/{container → driver}/cli_spec.rb +17 -19
- data/spec/unit/driver_spec.rb +173 -0
- data/tasks/boxes.rake +3 -3
- metadata +13 -15
- data/lib/vagrant-lxc/action/base_action.rb +0 -11
- data/lib/vagrant-lxc/action/network.rb +0 -21
- data/lib/vagrant-lxc/container.rb +0 -141
- data/lib/vagrant-lxc/machine_state.rb +0 -25
- data/spec/fixtures/sample-ifconfig-output +0 -18
- data/spec/unit/container_spec.rb +0 -147
- data/spec/unit/machine_state_spec.rb +0 -39
data/example/Vagrantfile
CHANGED
@@ -1,34 +1,22 @@
|
|
1
1
|
# -*- mode: ruby -*-
|
2
2
|
# vi: set ft=ruby :
|
3
3
|
|
4
|
-
def local_cache(box_name)
|
5
|
-
cache_dir = File.join(File.expand_path(Vagrant::Environment::DEFAULT_HOME),
|
6
|
-
'cache',
|
7
|
-
'apt',
|
8
|
-
box_name)
|
9
|
-
partial_dir = File.join(cache_dir, 'partial')
|
10
|
-
FileUtils.mkdir_p(partial_dir) unless File.exists? partial_dir
|
11
|
-
cache_dir
|
12
|
-
end
|
13
|
-
|
14
4
|
# Not really needed, but useful while developing so that vagrant picks it up
|
15
5
|
Vagrant.require_plugin 'vagrant-lxc'
|
16
6
|
|
17
7
|
Vagrant.configure("2") do |config|
|
18
8
|
config.vm.box = "quantal64"
|
19
|
-
config.vm.box_url = 'http://dl.dropbox.com/u/13510779/lxc-quantal64-2013-
|
9
|
+
config.vm.box_url = 'http://dl.dropbox.com/u/13510779/lxc-quantal64-2013-04-10.box'
|
20
10
|
# Uncomment if you want to try out a box built locally
|
21
11
|
# config.vm.box_url = '../boxes/output/lxc-quantal64.box'
|
22
12
|
config.vm.hostname = 'lxc-quantal64-example'
|
23
13
|
|
24
14
|
config.vm.synced_folder "/tmp", "/vagrant_data"
|
25
15
|
|
26
|
-
cache_dir = local_cache(config.vm.box)
|
27
|
-
config.vm.synced_folder cache_dir, "/var/cache/apt/archives"
|
28
16
|
|
29
17
|
config.vm.provider :lxc do |lxc|
|
30
|
-
lxc.
|
31
|
-
lxc.
|
18
|
+
lxc.customize 'cgroup.memory.limit_in_bytes', '400M'
|
19
|
+
lxc.customize 'cgroup.memory.memsw.limit_in_bytes', '500M'
|
32
20
|
end
|
33
21
|
|
34
22
|
config.vm.provision :shell, :inline => <<-SCRIPT
|
data/lib/vagrant-lxc.rb
CHANGED
data/lib/vagrant-lxc/action.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
# TODO: Remove base action
|
2
|
-
require 'vagrant-lxc/action/base_action'
|
3
|
-
|
4
|
-
# TODO: Use require_relative
|
5
1
|
require 'vagrant-lxc/action/boot'
|
6
2
|
require 'vagrant-lxc/action/check_created'
|
7
3
|
require 'vagrant-lxc/action/check_running'
|
@@ -15,7 +11,6 @@ require 'vagrant-lxc/action/forced_halt'
|
|
15
11
|
require 'vagrant-lxc/action/forward_ports'
|
16
12
|
require 'vagrant-lxc/action/handle_box_metadata'
|
17
13
|
require 'vagrant-lxc/action/is_running'
|
18
|
-
require 'vagrant-lxc/action/network'
|
19
14
|
require 'vagrant-lxc/action/setup_package_files'
|
20
15
|
require 'vagrant-lxc/action/share_folders'
|
21
16
|
|
@@ -42,11 +37,6 @@ module Vagrant
|
|
42
37
|
end
|
43
38
|
end
|
44
39
|
|
45
|
-
# We could do this here as VirtualBox does, but at least for now its better
|
46
|
-
# to be explicit and have the full constant name in order to easily spot
|
47
|
-
# what we implemented and what is builtin on Vagrant.
|
48
|
-
#
|
49
|
-
# include Vagrant::Action::Builtin
|
50
40
|
|
51
41
|
# This action boots the VM, assuming the VM is in a state that requires
|
52
42
|
# a bootup (i.e. not saved).
|
@@ -56,11 +46,8 @@ module Vagrant
|
|
56
46
|
b.use Vagrant::Action::Builtin::Provision
|
57
47
|
b.use Vagrant::Action::Builtin::EnvSet, :port_collision_repair => true
|
58
48
|
# b.use PrepareForwardedPortCollisionParams
|
59
|
-
# b.use ClearSharedFolders
|
60
49
|
b.use ShareFolders
|
61
|
-
b.use Network
|
62
50
|
b.use Vagrant::Action::Builtin::SetHostname
|
63
|
-
# b.use Customize
|
64
51
|
b.use ForwardPorts
|
65
52
|
b.use Boot
|
66
53
|
end
|
@@ -135,7 +122,7 @@ module Vagrant
|
|
135
122
|
b2.use Disconnect
|
136
123
|
b2.use ClearForwardedPorts
|
137
124
|
b2.use Vagrant::Action::Builtin::Call, Vagrant::Action::Builtin::GracefulHalt, :stopped, :running do |env2, b3|
|
138
|
-
if !env2[:result]
|
125
|
+
if !env2[:result]
|
139
126
|
b3.use ForcedHalt
|
140
127
|
end
|
141
128
|
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
|
-
class Boot
|
4
|
+
class Boot
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(env)
|
6
10
|
@env = env
|
7
11
|
|
8
12
|
config = env[:machine].provider_config
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
unless env[:machine].state.running?
|
14
|
-
env[:ui].info I18n.t("vagrant.actions.vm.boot.booting")
|
15
|
-
env[:machine].provider.container.start(config)
|
16
|
-
raise Vagrant::Errors::VMFailedToBoot if !wait_for_boot
|
17
|
-
end
|
14
|
+
env[:ui].info I18n.t("vagrant.actions.vm.boot.booting")
|
15
|
+
env[:machine].provider.driver.start(config.customizations)
|
16
|
+
raise Vagrant::Errors::VMFailedToBoot if !wait_for_boot
|
18
17
|
|
19
18
|
@app.call env
|
20
19
|
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
|
-
class CheckCreated
|
4
|
+
class CheckCreated
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(env)
|
6
|
-
|
10
|
+
if env[:machine].state.id == :not_created
|
7
11
|
raise Vagrant::Errors::VMNotCreatedError
|
8
12
|
end
|
9
13
|
|
@@ -1,9 +1,13 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
|
-
class CheckRunning
|
4
|
+
class CheckRunning
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(env)
|
6
|
-
|
10
|
+
if env[:machine].state.id != :running
|
7
11
|
raise Vagrant::Errors::VMNotRunningError
|
8
12
|
end
|
9
13
|
|
@@ -12,7 +12,7 @@ module Vagrant
|
|
12
12
|
raise Vagrant::Errors::VMPowerOffToPackage if env[:machine].provider.state.id != :stopped
|
13
13
|
|
14
14
|
env[:ui].info I18n.t("vagrant.actions.lxc.compressing_rootfs")
|
15
|
-
@rootfs = env['package.rootfs'] = env[:machine].provider.
|
15
|
+
@rootfs = env['package.rootfs'] = env[:machine].provider.driver.compress_rootfs
|
16
16
|
|
17
17
|
@app.call env
|
18
18
|
|
@@ -1,16 +1,24 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
|
-
class Create
|
4
|
+
class Create
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(env)
|
6
|
-
|
7
|
-
|
10
|
+
container_name = env[:root_path].basename.to_s
|
11
|
+
container_name.gsub!(/[^-a-z0-9_]/i, "")
|
12
|
+
container_name << "-#{Time.now.to_i}"
|
13
|
+
|
14
|
+
env[:machine].provider.driver.create(
|
15
|
+
container_name,
|
16
|
+
env[:lxc_template_src],
|
17
|
+
env[:lxc_template_opts]
|
18
|
+
)
|
8
19
|
|
9
|
-
|
20
|
+
env[:machine].id = container_name
|
10
21
|
|
11
|
-
machine_id = env[:machine].provider.container.create(base_name, target_rootfs_path, env[:machine].box.metadata)
|
12
|
-
env[:machine].id = machine_id
|
13
|
-
env[:just_created] = true
|
14
22
|
@app.call env
|
15
23
|
end
|
16
24
|
end
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
|
-
class Created
|
4
|
+
class Created
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(env)
|
6
10
|
# Set the result to be true if the machine is created.
|
7
|
-
env[:result] = env[:machine].state.
|
11
|
+
env[:result] = env[:machine].state.id != :not_created
|
8
12
|
|
9
13
|
# Call the next if we have one (but we shouldn't, since this
|
10
14
|
# middleware is built to run with the Call-type middlewares)
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
|
-
class Destroy
|
4
|
+
class Destroy
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(env)
|
6
10
|
env[:ui].info I18n.t("vagrant.actions.vm.destroy.destroying")
|
7
|
-
env[:machine].provider.
|
11
|
+
env[:machine].provider.driver.destroy
|
8
12
|
env[:machine].id = nil
|
9
13
|
@app.call env
|
10
14
|
end
|
@@ -7,11 +7,11 @@ module Vagrant
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def call(env)
|
10
|
-
if env[:machine].provider.state.running
|
10
|
+
if env[:machine].provider.state.id == :running
|
11
11
|
env[:ui].info I18n.t("vagrant.actions.vm.halt.force")
|
12
|
-
# TODO:
|
12
|
+
# TODO: Driver#halt is kinda graceful as well, if it doesn't
|
13
13
|
# work we can issue a lxc-stop.
|
14
|
-
env[:machine].provider.
|
14
|
+
env[:machine].provider.driver.halt
|
15
15
|
end
|
16
16
|
|
17
17
|
@app.call(env)
|
@@ -29,7 +29,7 @@ module Vagrant
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def forward_ports
|
32
|
-
@container_ip = @env[:machine].provider.
|
32
|
+
@container_ip = @env[:machine].provider.driver.assigned_ip
|
33
33
|
|
34
34
|
@env[:forwarded_ports].each do |fp|
|
35
35
|
message_attributes = {
|
@@ -63,7 +63,7 @@ module Vagrant
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def redirect_port(host, guest)
|
66
|
-
redir_cmd = "sudo redir --laddr=127.0.0.1 --lport=#{host} --cport=#{guest} --caddr=#{@container_ip}"
|
66
|
+
redir_cmd = "sudo redir --laddr=127.0.0.1 --lport=#{host} --cport=#{guest} --caddr=#{@container_ip} 2>/dev/null"
|
67
67
|
|
68
68
|
@logger.debug "Forwarding port with `#{redir_cmd}`"
|
69
69
|
fork { exec redir_cmd }
|
@@ -2,45 +2,56 @@ module Vagrant
|
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
4
|
# Prepare arguments to be used for lxc-create
|
5
|
-
class HandleBoxMetadata
|
6
|
-
LXC_TEMPLATES_PATH = Pathname.new("/usr/share/lxc/templates")
|
7
|
-
TEMP_PREFIX = "vagrant-lxc-rootfs-temp-"
|
8
|
-
|
5
|
+
class HandleBoxMetadata
|
9
6
|
def initialize(app, env)
|
10
|
-
|
7
|
+
@app = app
|
11
8
|
@logger = Log4r::Logger.new("vagrant::lxc::action::handle_box_metadata")
|
12
9
|
end
|
13
10
|
|
14
11
|
def call(env)
|
15
|
-
env
|
16
|
-
|
12
|
+
@env = env
|
13
|
+
@box = @env[:machine].box
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
template_name = "vagrant-#{box.name}"
|
15
|
+
@env[:ui].info I18n.t("vagrant.actions.vm.import.importing",
|
16
|
+
:name => @env[:machine].box.name)
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
unless File.exists?(lxc_template_src)
|
25
|
-
raise Errors::TemplateFileMissing.new name: box.name
|
26
|
-
end
|
27
|
-
dest = LXC_TEMPLATES_PATH.join("lxc-#{template_name}").to_s
|
28
|
-
@logger.debug('Copying LXC template into place')
|
29
|
-
system(%Q[sudo su root -c "cp #{lxc_template_src} #{dest}"])
|
18
|
+
@logger.debug 'Validating box contents'
|
19
|
+
validate_box
|
30
20
|
|
31
|
-
@logger.debug
|
32
|
-
|
33
|
-
|
21
|
+
@logger.debug 'Setting box options on environment'
|
22
|
+
@env[:lxc_template_opts] = template_opts
|
23
|
+
@env[:lxc_template_src] = template_src
|
24
|
+
|
25
|
+
@app.call env
|
26
|
+
end
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
28
|
+
def template_src
|
29
|
+
@template_src ||= @box.directory.join('lxc-template').to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def template_opts
|
33
|
+
@template_opts ||= @box.metadata.fetch('template-opts', {}).dup.merge!(
|
34
|
+
'--tarball' => rootfs_tarball,
|
35
|
+
'--auth-key' => Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s
|
38
36
|
)
|
37
|
+
end
|
39
38
|
|
40
|
-
|
39
|
+
def rootfs_tarball
|
40
|
+
@rootfs_tarball ||= @box.directory.join('rootfs.tar.gz').to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate_box
|
44
|
+
if @box.metadata.fetch('version').to_i != 2
|
45
|
+
raise Errors::InvalidBoxVersion.new name: @box.name
|
46
|
+
end
|
41
47
|
|
42
|
-
|
43
|
-
|
48
|
+
unless File.exists?(template_src)
|
49
|
+
raise Errors::TemplateFileMissing.new name: @box.name
|
50
|
+
end
|
51
|
+
|
52
|
+
unless File.exists?(rootfs_tarball)
|
53
|
+
raise Errors::RootFSTarballMissing.new name: @box.name
|
54
|
+
end
|
44
55
|
end
|
45
56
|
end
|
46
57
|
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
|
-
class IsRunning
|
4
|
+
class IsRunning
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(env)
|
6
|
-
env[:result] = env[:machine].state.running
|
10
|
+
env[:result] = env[:machine].state.id == :running
|
7
11
|
|
8
12
|
# Call the next if we have one (but we shouldn't, since this
|
9
13
|
# middleware is built to run with the Call-type middlewares)
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
module Action
|
4
|
-
class ShareFolders
|
4
|
+
class ShareFolders
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(env)
|
6
10
|
@env = env
|
7
11
|
prepare_folders
|
8
|
-
|
12
|
+
add_override_configs
|
9
13
|
@app.call env
|
10
14
|
end
|
11
15
|
|
@@ -14,9 +18,6 @@ module Vagrant
|
|
14
18
|
def shared_folders
|
15
19
|
{}.tap do |result|
|
16
20
|
@env[:machine].config.vm.synced_folders.each do |id, data|
|
17
|
-
# Ignore NFS shared folders
|
18
|
-
next if data[:nfs]
|
19
|
-
|
20
21
|
# This to prevent overwriting the actual shared folders data
|
21
22
|
result[id] = data.dup
|
22
23
|
end
|
@@ -43,7 +44,7 @@ module Vagrant
|
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
|
-
def
|
47
|
+
def add_override_configs
|
47
48
|
@env[:ui].info I18n.t("vagrant.actions.lxc.share_folders.preparing")
|
48
49
|
|
49
50
|
folders = []
|
@@ -56,8 +57,7 @@ module Vagrant
|
|
56
57
|
@env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
|
57
58
|
:guest_path => data[:guestpath]))
|
58
59
|
end
|
59
|
-
|
60
|
-
@env[:machine].provider.container.share_folders(folders, config)
|
60
|
+
@env[:machine].provider.driver.share_folders(folders)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
data/lib/vagrant-lxc/config.rb
CHANGED
@@ -1,21 +1,31 @@
|
|
1
1
|
module Vagrant
|
2
2
|
module LXC
|
3
3
|
class Config < Vagrant.plugin("2", :config)
|
4
|
-
# An array of
|
4
|
+
# An array of container's configuration overrides to be provided to `lxc-start`.
|
5
5
|
#
|
6
6
|
# @return [Array]
|
7
|
-
attr_reader :
|
8
|
-
|
9
|
-
# Base directory to store container's rootfs
|
10
|
-
#
|
11
|
-
# Defaults to nil, which means it will be stored wherever the lxc template
|
12
|
-
# tells it to be stored
|
13
|
-
attr_accessor :target_rootfs_path
|
7
|
+
attr_reader :customizations
|
14
8
|
|
15
9
|
def initialize
|
16
|
-
@
|
17
|
-
|
10
|
+
@customizations = []
|
11
|
+
end
|
12
|
+
|
13
|
+
# Customize the container by calling `lxc-start` with the given
|
14
|
+
# configuration overrides.
|
15
|
+
#
|
16
|
+
# For example, if you want to set the memory limit, you can use it
|
17
|
+
# like: config.customize 'cgroup.memory.limit_in_bytes', '400M'
|
18
|
+
#
|
19
|
+
# When `lxc-start`ing the container, vagrant-lxc will pass in
|
20
|
+
# "-s lxc.cgroup.memory.limit_in_bytes=400M" to it.
|
21
|
+
#
|
22
|
+
# @param [String] key Configuration key to override
|
23
|
+
# @param [String] value Configuration value to override
|
24
|
+
def customize(key, value)
|
25
|
+
@customizations << [key, value]
|
18
26
|
end
|
27
|
+
|
28
|
+
# TODO: At some point in the future it would be nice to validate these options
|
19
29
|
end
|
20
30
|
end
|
21
31
|
end
|