Improved box metadata handling and container creation
This commit is contained in:
parent
c0a3622413
commit
04cdd1f3db
5 changed files with 91 additions and 69 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue