diff --git a/.gitignore b/.gitignore index 7d98ca1..426172f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,3 @@ doc/ /boxes/**/*.tar.gz /boxes/quantal64/rootfs-amd64/ /boxes/output/ -/development/Vagrantfile diff --git a/CHANGELOG.md b/CHANGELOG.md index 019baae..6615633 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [0.1.1](https://github.com/fgrehm/vagrant-lxc/pull/43) + + - Removed support for development under Vagrant < 1.1 + - Removed rsync from base quantal64 box to speed up containers creation [#40](https://github.com/fgrehm/vagrant-lxc/issues/40) + - Containers are now named after project's root dir [#14](https://github.com/fgrehm/vagrant-lxc/issues/14) + - Skip Vagrant's built in SSH redirect + - Allow setting rootfs from Vagrantfile [#30](https://github.com/fgrehm/vagrant-lxc/issues/30) + ## 0.1.0 - Support for chef added to base quantal64 box diff --git a/Gemfile.lock b/Gemfile.lock index b3ac60e..1814620 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -14,7 +14,7 @@ GIT PATH remote: . specs: - vagrant-lxc (0.1.0) + vagrant-lxc (0.1.1.dev) GEM remote: https://rubygems.org/ diff --git a/README.md b/README.md index a6288f6..435f48d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # vagrant-lxc [![Build Status](https://travis-ci.org/fgrehm/vagrant-lxc.png?branch=master)](https://travis-ci.org/fgrehm/vagrant-lxc) [![Gem Version](https://badge.fury.io/rb/vagrant-lxc.png)](http://badge.fury.io/rb/vagrant-lxc) [![Code Climate](https://codeclimate.com/github/fgrehm/vagrant-lxc.png)](https://codeclimate.com/github/fgrehm/vagrant-lxc) -Experimental Linux Containers support for Vagrant >= 1.1. +Experimental Linux Containers support for Vagrant 1.1+ ## Dependencies -Vagrant >= 1.1.0, `lxc` and `redir` packages and a Kernel [higher than 3.5.0-17.28](#help-im-unable-to-restart-containers), +Vagrant 1.1+ (1.1.4+ recommended), `lxc` and `redir` packages and a Kernel [higher than 3.5.0-17.28](#help-im-unable-to-restart-containers), which on Ubuntu 12.10 means something like: ``` @@ -16,7 +16,7 @@ sudo dpkg -i /tmp/vagrant.deb ``` -## What is currently supported? (v0.1.0) +## What is currently supported? (v0.1.1) * Vagrant's `up`, `halt`, `reload`, `destroy`, and `ssh` commands * Shared folders @@ -43,7 +43,7 @@ for the most up to date list.* ## Usage -Make sure you have [Vagrant 1.1](http://downloads.vagrantup.com/tags/v1.1.0) and run: +Make sure you have [Vagrant 1.1+](http://downloads.vagrantup.com/) and run: ``` vagrant plugin install vagrant-lxc @@ -63,6 +63,8 @@ Vagrant.configure("2") do |config| config.vm.synced_folder "/tmp", "/host_tmp" config.vm.provider :lxc do |lxc| + # Set the folder where container's rootfs will be stored when created + lxc.target_rootfs_path = '/path/to/container/rootfs' # Same as 'customize ["modifyvm", :id, "--memory", "1024"]' for VirtualBox lxc.start_opts << 'lxc.cgroup.memory.limit_in_bytes=400M' # Limits swap size @@ -109,7 +111,6 @@ sudo apt-get install apparmor-utils sudo aa-complain /usr/bin/lxc-start bundle install cd development -ln -s Vagrantfile.1.1 Vagrantfile bundle exec vagrant up lxc --provider=lxc bundle exec vagrant ssh lxc ``` @@ -120,26 +121,16 @@ Keep in mind that you'll probably need to run `sudo aa-complain /usr/bin/lxc-sta on the host whenever you want to hack on it, otherwise you won't be able to start nested containers there to try things out. -### Using VirtualBox and Vagrant 1.1 for development +### Using VirtualBox for development ``` cd development -ln -s Vagrantfile.1.1 Vagrantfile bundle exec vagrant up vbox +# A reload is needed to ensure the updated kernel gets loaded bundle exec vagrant reload vbox bundle exec vagrant ssh vbox ``` -### Using VirtualBox and Vagrant 1.0 for development - -``` -cd development -ln -s Vagrantfile.1.0 Vagrantfile -vagrant up -vagrant reload -vagrant ssh -``` - ## Protips diff --git a/boxes/quantal64/lxc-template b/boxes/quantal64/lxc-template index 4690955..0fdef44 100755 --- a/boxes/quantal64/lxc-template +++ b/boxes/quantal64/lxc-template @@ -161,8 +161,8 @@ copy_ubuntu() # make a local copy of the miniubuntu echo "Copying rootfs to $rootfs ..." - mkdir -p $rootfs - rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1 + mkdir -p $(dirname $rootfs) + mv $cache/rootfs-$arch $rootfs || return 1 return 0 } diff --git a/development/Vagrantfile.1.1 b/development/Vagrantfile similarity index 94% rename from development/Vagrantfile.1.1 rename to development/Vagrantfile index c6690ba..d57e565 100644 --- a/development/Vagrantfile.1.1 +++ b/development/Vagrantfile @@ -50,6 +50,8 @@ Vagrant.configure("2") do |config| config.vm.define :lxc do |lxc_config| lxc_config.vm.hostname = 'lxc-dev-box' + # Uncomment to test boxes built locally: + # lxc_config.vm.box_url = '../boxes/output/lxc-quantal64.box' lxc_config.vm.box_url = 'http://dl.dropbox.com/u/13510779/lxc-quantal64-2013-03-26.box' lxc_config.vm.provider :lxc do |lxc| diff --git a/development/Vagrantfile.1.0 b/development/Vagrantfile.1.0 deleted file mode 100644 index 044de4d..0000000 --- a/development/Vagrantfile.1.0 +++ /dev/null @@ -1,36 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -def local_cache(box_name) - cache_dir = File.join(File.expand_path(Vagrant::Environment::DEFAULT_HOME), - 'cache', - 'apt', - box_name) - partial_dir = File.join(cache_dir, 'partial') - FileUtils.mkdir_p(partial_dir) unless File.exists? partial_dir - cache_dir -end - -Vagrant::Config.run do |config| - config.vm.box = "quantal64" - config.vm.box_url = "https://github.com/downloads/roderik/VagrantQuantal64Box/quantal64.box" - config.vm.host_name = 'lxc-dev-box' - - cache_dir = local_cache(config.vm.box) - config.vm.share_folder "v-root", "/vagrant", "../" - config.vm.share_folder "v-cache", "/var/cache/apt/archives", cache_dir - - if defined? VagrantVbguest::Config - config.vbguest.auto_update = false - config.vbguest.no_remote = true - end - - config.vm.provision :shell, :path => 'shell-provisioning/upgrade-kernel' - - config.vm.provision :puppet do |puppet| - puppet.manifests_path = "." - puppet.manifest_file = "site.pp" - # Pass DEBUG=1 to vagrant commands if you want to make some debugging noise - puppet.options << [ "--verbose", "--debug" ] if ENV["DEBUG"] == '1' - end -end diff --git a/lib/vagrant-lxc/action/create.rb b/lib/vagrant-lxc/action/create.rb index bbb2d63..1cb8e9a 100644 --- a/lib/vagrant-lxc/action/create.rb +++ b/lib/vagrant-lxc/action/create.rb @@ -3,7 +3,12 @@ module Vagrant module Action class Create < BaseAction def call(env) - machine_id = env[:machine].provider.container.create(env[:machine].box.metadata) + base_name = env[:root_path].basename.to_s + base_name.gsub!(/[^-a-z0-9_]/i, "") + + target_rootfs_path = env[:machine].provider_config.target_rootfs_path + + machine_id = env[:machine].provider.container.create(base_name, target_rootfs_path, env[:machine].box.metadata) env[:machine].id = machine_id env[:just_created] = true @app.call env diff --git a/lib/vagrant-lxc/action/forward_ports.rb b/lib/vagrant-lxc/action/forward_ports.rb index 892ae00..fc4bf51 100644 --- a/lib/vagrant-lxc/action/forward_ports.rb +++ b/lib/vagrant-lxc/action/forward_ports.rb @@ -54,7 +54,7 @@ module Vagrant mappings = {} config.vm.networks.each do |type, options| - if type == :forwarded_port + if type == :forwarded_port && options[:id] != 'ssh' mappings[options[:host]] = options end end diff --git a/lib/vagrant-lxc/config.rb b/lib/vagrant-lxc/config.rb index bd923ac..4e5edb4 100644 --- a/lib/vagrant-lxc/config.rb +++ b/lib/vagrant-lxc/config.rb @@ -6,8 +6,15 @@ module Vagrant # @return [Array] attr_reader :start_opts + # Base directory to store container's rootfs + # + # Defaults to nil, which means it will be stored wherever the lxc template + # tells it to be stored + attr_accessor :target_rootfs_path + def initialize - @start_opts = [] + @start_opts = [] + @target_rootfs_path = nil end end end diff --git a/lib/vagrant-lxc/container.rb b/lib/vagrant-lxc/container.rb index 4c6f10e..31df834 100644 --- a/lib/vagrant-lxc/container.rb +++ b/lib/vagrant-lxc/container.rb @@ -12,9 +12,6 @@ module Vagrant # Root folder where containers are stored CONTAINERS_PATH = '/var/lib/lxc' - # Default LXC configs - LXC_DEFAULTS_PATH = '/etc/default/lxc' - # Include this so we can use `Subprocess` more easily. include Vagrant::Util::Retryable @@ -39,13 +36,13 @@ module Vagrant end def rootfs_path - Pathname.new("#{base_path}/rootfs") + Pathname.new(base_path.join('config').read.match(/^lxc\.rootfs\s+=\s+(.+)$/)[1]) end - def create(metadata = {}) + def create(base_name, target_rootfs_path, metadata = {}) @logger.debug('Creating container using lxc-create...') - @name = SecureRandom.hex(6) + @name = "#{base_name}-#{SecureRandom.hex(6)}" public_key = Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s meta_opts = metadata.fetch('template-opts', {}).merge( '--auth-key' => public_key, @@ -53,7 +50,7 @@ module Vagrant ) @cli.name = @name - @cli.create(metadata.fetch('template-name'), meta_opts) + @cli.create(metadata.fetch('template-name'), target_rootfs_path, meta_opts) @name end @@ -107,7 +104,7 @@ module Vagrant retryable(:on => LXC::Errors::ExecuteError, :tries => 10, :sleep => 3) do unless ip = get_container_ip_from_ifconfig # retry - raise LXC::Errors::ExecuteError, :command => ['arp', '-n'].inspect + raise LXC::Errors::ExecuteError, :command => "lxc-attach" end end ip diff --git a/lib/vagrant-lxc/container/cli.rb b/lib/vagrant-lxc/container/cli.rb index e1ceaca..57a3deb 100644 --- a/lib/vagrant-lxc/container/cli.rb +++ b/lib/vagrant-lxc/container/cli.rb @@ -31,15 +31,18 @@ module Vagrant end end - def create(template, template_opts = {}) + def create(template, target_rootfs_path, template_opts = {}) extra = template_opts.to_a.flatten extra.unshift '--' unless extra.empty? + rootfs_args = target_rootfs_path ? + ['-B', 'dir', '--dir', target_rootfs_path] : + [] + run :create, - # lxc-create options '--template', template, '--name', @name, - *extra + *(rootfs_args + extra) end def destroy diff --git a/lib/vagrant-lxc/provider.rb b/lib/vagrant-lxc/provider.rb index f1f2bdc..8b93653 100644 --- a/lib/vagrant-lxc/provider.rb +++ b/lib/vagrant-lxc/provider.rb @@ -34,7 +34,7 @@ module Vagrant end end - # @see Vagrant::Plugin::V1::Provider#action + # @see Vagrant::Plugin::V2::Provider#action def action(name) # Attempt to get the action method from the Action class if it # exists, otherwise return nil to show that we don't support the @@ -53,7 +53,7 @@ module Vagrant { :host => @container.assigned_ip, - :port => 22 # @driver.ssh_port(@machine.config.ssh.guest_port) + :port => @machine.config.ssh.guest_port } end diff --git a/lib/vagrant-lxc/version.rb b/lib/vagrant-lxc/version.rb index f68d04c..fbd605d 100644 --- a/lib/vagrant-lxc/version.rb +++ b/lib/vagrant-lxc/version.rb @@ -1,5 +1,5 @@ module Vagrant module LXC - VERSION = "0.1.0" + VERSION = "0.1.1.dev" end end diff --git a/spec/unit/container/cli_spec.rb b/spec/unit/container/cli_spec.rb index aedf6e6..14f9b83 100644 --- a/spec/unit/container/cli_spec.rb +++ b/spec/unit/container/cli_spec.rb @@ -33,19 +33,31 @@ describe Vagrant::LXC::Container::CLI do subject { described_class.new(name) } before do - subject.stub(:run) - subject.create(template, template_args) + subject.stub(:run) { |*args| @run_args = args } + subject.create(template, rootfs, template_args) end - it 'issues a lxc-create with provided template, container name and hash of arguments' do - subject.should have_received(:run).with( - :create, - '--template', template, - '--name', name, - '--', - '--extra-param', 'param', - '--other', 'value' - ) + context 'when no rootfs is passed' do + let(:rootfs) { nil } + + it 'issues a lxc-create with provided template, container name and hash of arguments' do + subject.should have_received(:run).with( + :create, + '--template', template, + '--name', name, + '--', + '--extra-param', 'param', + '--other', 'value' + ) + end + end + + context 'when the rootfs is passed' do + let(:rootfs) { 'rootfs_path' } + + it 'issues a lxc-create with the right rootfs arguments' do + @run_args.join(' ').should =~ /-B dir --dir #{rootfs}/ + end end end diff --git a/spec/unit/container_spec.rb b/spec/unit/container_spec.rb index 5a316f0..bf3c96c 100644 --- a/spec/unit/container_spec.rb +++ b/spec/unit/container_spec.rb @@ -33,22 +33,26 @@ describe Vagrant::LXC::Container do end describe 'creation' do - let(:name) { 'random-container-name' } + let(:base_name) { 'container-name' } + let(:suffix) { 'random-suffix' } let(:template_name) { 'template-name' } let(:rootfs_cache) { '/path/to/cache' } + let(:target_rootfs) { '/path/to/rootfs' } let(:public_key_path) { Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s } let(:cli) { fire_double('Vagrant::LXC::Container::CLI', :create => true, :name= => true) } subject { described_class.new(name, cli) } before do - SecureRandom.stub(hex: name) - subject.create 'template-name' => template_name, 'rootfs-cache-path' => rootfs_cache, 'template-opts' => { '--foo' => 'bar'} + SecureRandom.stub(hex: suffix) + subject.create base_name, target_rootfs, 'template-name' => template_name, 'rootfs-cache-path' => rootfs_cache, 'template-opts' => { '--foo' => 'bar'} end it 'creates container with the right arguments' do + cli.should have_received(:name=).with("#{base_name}-#{suffix}") cli.should have_received(:create).with( template_name, + target_rootfs, '--auth-key' => public_key_path, '--cache' => rootfs_cache, '--foo' => 'bar'