Improved box metadata handling and container creation

This commit is contained in:
Fabio Rehm 2013-04-05 03:10:38 -03:00
parent c0a3622413
commit 04cdd1f3db
5 changed files with 91 additions and 69 deletions

View file

@ -7,12 +7,18 @@ module Vagrant
end
def call(env)
base_name = env[:root_path].basename.to_s
base_name.gsub!(/[^-a-z0-9_]/i, "")
container_name = env[:root_path].basename.to_s
container_name.gsub!(/[^-a-z0-9_]/i, "")
container_name << "-#{Time.now.to_i}"
env[:machine].provider.driver.create(
container_name,
env[:lxc_template_src],
env[:lxc_template_opts]
)
env[:machine].id = container_name
machine_id = env[:machine].provider.driver.create(base_name, env[:machine].box.metadata)
env[:machine].id = machine_id
env[:just_created] = true
@app.call env
end
end

View file

@ -3,9 +3,6 @@ module Vagrant
module Action
# Prepare arguments to be used for lxc-create
class HandleBoxMetadata
LXC_TEMPLATES_PATH = Pathname.new("/usr/share/lxc/templates")
TEMP_PREFIX = "vagrant-lxc-rootfs-temp-"
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::lxc::action::handle_box_metadata")
@ -15,26 +12,27 @@ module Vagrant
env[:ui].info I18n.t("vagrant.actions.vm.import.importing",
:name => env[:machine].box.name)
rootfs_cache = Dir.mktmpdir(TEMP_PREFIX)
box = env[:machine].box
template_name = "vagrant-#{box.name}"
box = env[:machine].box
# Prepends "lxc-" to the template file so that `lxc-create` is able to find it
lxc_template_src = box.directory.join('lxc-template').to_s
unless File.exists?(lxc_template_src)
template_src = box.directory.join('lxc-template').to_s
unless File.exists?(template_src)
raise Errors::TemplateFileMissing.new name: box.name
end
dest = LXC_TEMPLATES_PATH.join("lxc-#{template_name}").to_s
@logger.debug('Copying LXC template into place')
system(%Q[sudo su root -c "cp #{lxc_template_src} #{dest}"])
# TODO: Validate box version
@logger.debug('Merging metadata with template name and rootfs tarball')
box.metadata.merge!(
'template-name' => template_name,
'rootfs-tarball' => box.directory.join('rootfs.tar.gz')
template_opts = box.metadata.fetch('template-opts', {}).dup
template_opts.merge!(
'--tarball' => box.directory.join('rootfs.tar.gz').to_s,
'--auth-key' => Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s
)
@app.call(env)
env[:lxc_template_opts] = template_opts
env[:lxc_template_src] = template_src
@app.call env
end
end
end

View file

@ -1,5 +1,3 @@
require 'securerandom'
require "vagrant/util/retryable"
require "vagrant/util/subprocess"
@ -9,9 +7,6 @@ require "vagrant-lxc/driver/cli"
module Vagrant
module LXC
class Driver
# Root folder where containers are stored
CONTAINERS_PATH = '/var/lib/lxc'
# Include this so we can use `Subprocess` more easily.
include Vagrant::Util::Retryable
@ -39,20 +34,13 @@ module Vagrant
Pathname.new(base_path.join('config').read.match(/^lxc\.rootfs\s+=\s+(.+)$/)[1])
end
def create(base_name, metadata = {})
@logger.debug('Creating container using lxc-create...')
def create(name, template_path, template_options = {})
@cli.name = @name = name
@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,
'--tarball' => metadata.fetch('rootfs-tarball').to_s
)
@cli.name = @name
@cli.create(metadata.fetch('template-name'), meta_opts)
@name
import_template(template_path) do |template_name|
@logger.debug "Creating container..."
@cli.create template_name, template_options
end
end
def share_folders(folders, config)
@ -136,6 +124,33 @@ module Vagrant
return $1.to_s
end
end
protected
LXC_TEMPLATES_PATH = Pathname.new("/usr/share/lxc/templates")
# Root folder where container configs are stored
CONTAINERS_PATH = '/var/lib/lxc'
def base_path
Pathname.new("#{CONTAINERS_PATH}/#{@name}")
end
def rootfs_path
Pathname.new(base_path.join('config').read.match(/^lxc\.rootfs\s+=\s+(.+)$/)[1])
end
def import_template(path)
template_name = "vagrant-tmp-#{@name}"
tmp_template_path = LXC_TEMPLATES_PATH.join("lxc-#{template_name}").to_s
@logger.debug 'Copying LXC template into place'
system(%Q[sudo su root -c "cp #{path} #{tmp_template_path}"])
yield template_name
ensure
system(%Q[sudo su root -c "rm #{tmp_template_path}"])
end
end
end
end

View file

@ -1,36 +1,41 @@
require 'unit_helper'
require 'vagrant'
require 'vagrant-lxc/action/handle_box_metadata'
describe Vagrant::LXC::Action::HandleBoxMetadata do
let(:metadata) { {'template-opts' => {'--foo' => 'bar'}} }
let(:box) { mock(:box, name: 'box-name', metadata: metadata, directory: box_directory) }
let(:box_directory) { Pathname.new('/path/to/box') }
let(:machine) { mock(:machine, box: box) }
let(:app) { mock(:app, call: true) }
let(:env) { {machine: machine, ui: stub(info: true)} }
let(:machine) { mock(:machine, box: box) }
let(:box) { mock(:box, name: 'box-name', metadata: metadata, directory: box_directory) }
let(:box_directory) { Pathname.new('/path/to/box') }
let(:metadata) { {'template-opts' => {'--foo' => 'bar'}} }
let(:vagrant_key) { Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s }
subject { described_class.new(app, env) }
before do
File.stub(exists?: true)
subject.stub(:system)
subject.call(env)
end
it 'sets the rootfs-tarball path on metadata hash' do
metadata['rootfs-tarball'].should == box_directory.join('rootfs.tar.gz')
it 'sets the tarball argument for the template' do
env[:lxc_template_opts].should include(
'--tarball' => box_directory.join('rootfs.tar.gz').to_s
)
end
it 'prepends vagrant and box name to template-name' do
metadata['template-name'].should == "vagrant-#{box.name}"
it 'sets the auth key argument for the template' do
env[:lxc_template_opts].should include(
'--auth-key' => vagrant_key
)
end
it 'copies box template file to the right folder' do
src = box_directory.join('lxc-template').to_s
dest = "/usr/share/lxc/templates/lxc-#{metadata['template-name']}"
it 'sets the template options from metadata on env hash' do
env[:lxc_template_opts].should include(metadata['template-opts'])
end
subject.should have_received(:system).
with("sudo su root -c \"cp #{src} #{dest}\"")
it 'sets the template source path on env hash' do
env[:lxc_template_src].should == box_directory.join('lxc-template').to_s
end
end

View file

@ -4,9 +4,6 @@ require 'vagrant'
require 'vagrant-lxc/driver'
describe Vagrant::LXC::Driver do
let(:name) { nil }
subject { described_class.new(name) }
describe 'container name validation' do
let(:unknown_container) { described_class.new('unknown', cli) }
let(:valid_container) { described_class.new('valid', cli) }
@ -33,27 +30,28 @@ describe Vagrant::LXC::Driver do
end
describe 'creation' do
let(:base_name) { 'container-name' }
let(:suffix) { 'random-suffix' }
let(:template_name) { 'template-name' }
let(:rootfs_tarball) { '/path/to/cache/rootfs.tar.gz' }
let(:public_key_path) { Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s }
let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', :create => true, :name= => true) }
let(:name) { 'container-name' }
let(:template_name) { 'auto-assigned-template-id' }
let(:template_path) { '/path/to/lxc-template-from-box' }
let(:template_opts) { {'--some' => 'random-option'} }
let(:rootfs_tarball) { '/path/to/cache/rootfs.tar.gz' }
let(:cli) { fire_double('Vagrant::LXC::Driver::CLI', :create => true, :name= => true) }
subject { described_class.new(name, cli) }
subject { described_class.new(nil, cli) }
before do
SecureRandom.stub(hex: suffix)
subject.create base_name, 'template-name' => template_name, 'rootfs-tarball' => rootfs_tarball, 'template-opts' => { '--foo' => 'bar'}
subject.stub(:import_template).and_yield(template_name)
subject.create name, template_path, template_opts
end
it 'sets the cli object container name' do
cli.should have_received(:name=).with(name)
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,
'--auth-key' => public_key_path,
'--tarball' => rootfs_tarball,
'--foo' => 'bar'
template_opts
)
end
end