From 79efbe9cd0d35c748c8bc6b30e0a10eae4e92c37 Mon Sep 17 00:00:00 2001 From: Fabio Rehm Date: Sat, 2 Mar 2013 12:17:04 -0300 Subject: [PATCH] Make use of box metadata for creating containers --- lib/vagrant-lxc/action.rb | 22 +++-------- lib/vagrant-lxc/action/base_action.rb | 16 ++++++++ lib/vagrant-lxc/action/handle_box_metadata.rb | 39 +++++++++++++++++++ lib/vagrant-lxc/container.rb | 11 ++++-- spec/unit/action/handle_box_metadata_spec.rb | 34 ++++++++++++++++ spec/unit/container_spec.rb | 9 +++-- 6 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 lib/vagrant-lxc/action/base_action.rb create mode 100644 lib/vagrant-lxc/action/handle_box_metadata.rb create mode 100644 spec/unit/action/handle_box_metadata_spec.rb diff --git a/lib/vagrant-lxc/action.rb b/lib/vagrant-lxc/action.rb index 30f5178..45483b7 100644 --- a/lib/vagrant-lxc/action.rb +++ b/lib/vagrant-lxc/action.rb @@ -1,5 +1,7 @@ -# TODO: Split action classes into their own files +require 'vagrant-lxc/action/base_action' +require 'vagrant-lxc/action/handle_box_metadata' +# TODO: Split action classes into their own files module Vagrant module LXC module Action @@ -71,8 +73,8 @@ module Vagrant b.use Vagrant::Action::Builtin::Call, Created do |env, b2| # If the VM is NOT created yet, then do the setup steps if !env[:result] + b2.use HandleBoxMetadata b2.use Create - # We'll probably have other actions down here... end end b.use action_start @@ -129,18 +131,6 @@ module Vagrant end end - - class BaseAction - def initialize(app, env) - @app = app - end - - def call(env) - puts "TODO: Implement #{self.class.name}" - @app.call(env) - end - end - class Created < BaseAction def call(env) # Set the result to be true if the machine is created. @@ -165,8 +155,8 @@ module Vagrant class Create < BaseAction def call(env) - puts "TODO: Create container" - env[:machine].id = env[:machine].provider.container.create + machine_id = env[:machine].provider.container.create(env[:machine].box.metadata) + env[:machine].id = machine_id @app.call env end end diff --git a/lib/vagrant-lxc/action/base_action.rb b/lib/vagrant-lxc/action/base_action.rb new file mode 100644 index 0000000..8167974 --- /dev/null +++ b/lib/vagrant-lxc/action/base_action.rb @@ -0,0 +1,16 @@ +module Vagrant + module LXC + module Action + class BaseAction + def initialize(app, env) + @app = app + end + + def call(env) + puts "TODO: Implement #{self.class.name}" + @app.call(env) + end + end + end + end +end diff --git a/lib/vagrant-lxc/action/handle_box_metadata.rb b/lib/vagrant-lxc/action/handle_box_metadata.rb new file mode 100644 index 0000000..5a1ca81 --- /dev/null +++ b/lib/vagrant-lxc/action/handle_box_metadata.rb @@ -0,0 +1,39 @@ +require 'vagrant-lxc/action/base_action' + +module Vagrant + module LXC + module Action + # Prepare arguments to be used for lxc-create + class HandleBoxMetadata < BaseAction + LXC_TEMPLATES_PATH = Pathname.new("/usr/share/lxc/templates") + + def initialize(app, env) + super + @logger = Log4r::Logger.new("vagrant::lxc::action::handle_box_metadata") + end + + def call(env) + box = env[:machine].box + metadata = box.metadata + template_name = metadata['template-name'] + + metadata.merge!( + 'template-name' => "vagrant-#{box.name}-#{template_name}", + 'tar-cache' => box.directory.join(metadata['tar-cache']).to_s + ) + + # Prepends "lxc-" to the template file so that `lxc-create` is able to find it + dest = LXC_TEMPLATES_PATH.join("lxc-#{metadata['template-name']}").to_s + src = box.directory.join(template_name).to_s + + @logger.debug('Copying LXC template into place') + # This should only ask for administrative permission once, even + # though its executed in multiple subshells. + system(%Q[sudo su root -c "cp #{src} #{dest}"]) + + @app.call(env) + end + end + end + end +end diff --git a/lib/vagrant-lxc/container.rb b/lib/vagrant-lxc/container.rb index 046fe8f..d24f765 100644 --- a/lib/vagrant-lxc/container.rb +++ b/lib/vagrant-lxc/container.rb @@ -27,12 +27,15 @@ module Vagrant raise NotFound if @name && ! lxc(:ls).split("\n").include?(@name) end - def create + def create(metadata = {}) # FIXME: Ruby 1.8 users dont have SecureRandom - name = SecureRandom.hex(6) - public_key = Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s - log, status = lxc :create, '--template', 'ubuntu-cloud', '--name', name, '--', '-S', public_key + # @logger.info('Creating container...') + name = SecureRandom.hex(6) + public_key = Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s + # TODO: Handle errors + lxc :create, '--template', metadata['template-name'], '--name', name, '--', '-S', public_key, '-T', metadata['tar-cache'] + @name = name end diff --git a/spec/unit/action/handle_box_metadata_spec.rb b/spec/unit/action/handle_box_metadata_spec.rb new file mode 100644 index 0000000..384479e --- /dev/null +++ b/spec/unit/action/handle_box_metadata_spec.rb @@ -0,0 +1,34 @@ +require 'unit_helper' + +require 'vagrant-lxc/action/handle_box_metadata' + +describe Vagrant::LXC::Action::HandleBoxMetadata do + let(:tar_cache) { 'template.zip' } + let(:template_name) { 'ubuntu-lts' } + let(:metadata) { {'template-name' => template_name, 'tar-cache' => tar_cache} } + let(:box) { mock(:box, name: 'box-name', metadata: metadata, directory: Pathname.new('/path/to/box')) } + let(:machine) { mock(:machine, box: box) } + let(:app) { mock(:app, call: true) } + let(:env) { {machine: machine} } + + subject { described_class.new(app, env) } + + before do + subject.stub(:system) + subject.call(env) + end + + it 'prepends box directory to tar-cache' do + metadata['tar-cache'].should == "#{box.directory.to_s}/#{tar_cache}" + end + + it 'prepends vagrant and box name to template-name' do + metadata['template-name'].should == "vagrant-#{box.name}-#{template_name}" + end + + it 'copies box template file to the right folder' do + src = box.directory.join(template_name).to_s + dest = "/usr/share/lxc/templates/lxc-#{metadata['template-name']}" + subject.should have_received(:system).with("sudo su root -c \"cp #{src} #{dest}\"") + end +end diff --git a/spec/unit/container_spec.rb b/spec/unit/container_spec.rb index dc6bde8..9dccdfd 100644 --- a/spec/unit/container_spec.rb +++ b/spec/unit/container_spec.rb @@ -77,21 +77,24 @@ describe Vagrant::LXC::Container do describe 'creation' do let(:name) { 'random-container-name' } + let(:template_name) { 'template-name' } + let(:tar_cache_path) { '/path/to/tar/cache' } let(:public_key_path) { Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s } before do subject.stub(:lxc) SecureRandom.stub(hex: name) - subject.create + subject.create 'template-name' => template_name, 'tar-cache' => tar_cache_path end it 'calls lxc-create with the right arguments' do subject.should have_received(:lxc).with( :create, - '--template', 'ubuntu-cloud', + '--template', template_name, '--name', name, '--', - '-S', public_key_path + '-S', public_key_path, + '-T', tar_cache_path ) end end