Make use of box metadata for creating containers

This commit is contained in:
Fabio Rehm 2013-03-02 12:17:04 -03:00
parent 849e9c73d7
commit 79efbe9cd0
6 changed files with 108 additions and 23 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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