Clean up Container object by making use of the CLI
This commit is contained in:
parent
228e03ecbe
commit
550b926497
2 changed files with 68 additions and 164 deletions
|
@ -46,19 +46,13 @@ module Vagrant
|
|||
|
||||
@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,
|
||||
'--cache' => metadata.fetch('rootfs-cache-path')
|
||||
)
|
||||
|
||||
meta_opts = metadata.fetch('template-opts', {}).to_a.flatten
|
||||
|
||||
# TODO: Handle errors
|
||||
lxc :create,
|
||||
# lxc-create options
|
||||
'--template', metadata.fetch('template-name'),
|
||||
'--name', @name,
|
||||
'--',
|
||||
# Template options
|
||||
'--auth-key', public_key,
|
||||
'--cache', metadata.fetch('rootfs-cache-path'),
|
||||
*meta_opts
|
||||
@cli.name = @name
|
||||
@cli.create(metadata.fetch('template-name'), meta_opts)
|
||||
|
||||
@name
|
||||
end
|
||||
|
@ -75,44 +69,36 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
|
||||
# http://blog.smartlogicsolutions.com/2009/06/04/mount-options-to-improve-ext4-file-system-performance/
|
||||
config.start_opts << "lxc.mount.entry=#{folder[:hostpath]} #{guestpath} none bind 0 0"
|
||||
end
|
||||
end
|
||||
|
||||
def start(config)
|
||||
# @logger.info('Starting container...')
|
||||
opts = config.start_opts.map { |opt| ["-s", opt] }.flatten
|
||||
opts += ['-o', ENV['LXC_START_LOG_FILE'], '-l', 'DEBUG'] if ENV['LXC_START_LOG_FILE']
|
||||
lxc :start, '-d', '--name', @name, *opts
|
||||
wait_until :running
|
||||
@logger.info('Starting container...')
|
||||
|
||||
opts = config.start_opts.dup
|
||||
if ENV['LXC_START_LOG_FILE']
|
||||
opts.merge!('-o' => ENV['LXC_START_LOG_FILE'], '-l' => 'DEBUG')
|
||||
end
|
||||
|
||||
@cli.transition_to(:running) { |c| c.start(opts) }
|
||||
end
|
||||
|
||||
def halt
|
||||
lxc :shutdown, '--name', @name
|
||||
wait_until :stopped
|
||||
@logger.info('Shutting down container...')
|
||||
|
||||
# TODO: issue an lxc-stop if a timeout gets reached
|
||||
@cli.transition_to(:stopped) { |c| c.shutdown }
|
||||
end
|
||||
|
||||
def destroy
|
||||
lxc :destroy, '--name', @name
|
||||
end
|
||||
|
||||
# REFACTOR:
|
||||
# transition_to :state do
|
||||
# ... code ...
|
||||
def wait_until(state)
|
||||
lxc :wait, '--name', @name, '--state', state.to_s.upcase
|
||||
end
|
||||
|
||||
def lxc(command, *args)
|
||||
execute('sudo', "lxc-#{command}", *args)
|
||||
@cli.destroy
|
||||
end
|
||||
|
||||
def state
|
||||
if @name && lxc(:info, '--name', @name) =~ /^state:[^A-Z]+([A-Z]+)$/
|
||||
$1.downcase.to_sym
|
||||
elsif @name
|
||||
:unknown
|
||||
if @name
|
||||
@cli.state
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -122,7 +108,7 @@ module Vagrant
|
|||
end
|
||||
mac_addr = $1
|
||||
|
||||
#`ip neigh flush all > /dev/null`
|
||||
# TODO: We might need to `ip neigh flush all > /dev/null` before running `arp`
|
||||
|
||||
ip = ''
|
||||
# See: http://programminglinuxblog.blogspot.com.br/2007/11/detecting-ip-address-from-mac-address.html
|
||||
|
@ -157,36 +143,6 @@ module Vagrant
|
|||
end
|
||||
|
||||
# TODO: Review code below this line, it was pretty much a copy and paste from VirtualBox base driver
|
||||
def execute(*command, &block)
|
||||
# Get the options hash if it exists
|
||||
opts = {}
|
||||
opts = command.pop if command.last.is_a?(Hash)
|
||||
|
||||
tries = 0
|
||||
tries = 3 if opts[:retryable]
|
||||
|
||||
# Variable to store our execution result
|
||||
r = nil
|
||||
|
||||
retryable(:on => LXC::Errors::ExecuteError, :tries => tries, :sleep => 1) do
|
||||
# Execute the command
|
||||
r = raw(*command, &block)
|
||||
|
||||
# If the command was a failure, then raise an exception that is
|
||||
# nicely handled by Vagrant.
|
||||
if r.exit_code != 0
|
||||
if @interrupted
|
||||
@logger.info("Exit code != 0, but interrupted. Ignoring.")
|
||||
else
|
||||
raise LXC::Errors::ExecuteError, :command => command.inspect
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Return the output, making sure to replace any Windows-style
|
||||
# newlines with Unix-style.
|
||||
r.stdout.gsub("\r\n", "\n")
|
||||
end
|
||||
|
||||
# Executes a command and returns the raw result object.
|
||||
def raw(*command, &block)
|
||||
|
|
|
@ -11,7 +11,7 @@ describe Vagrant::LXC::Container do
|
|||
let(:unknown_container) { described_class.new('unknown', cli) }
|
||||
let(:valid_container) { described_class.new('valid', cli) }
|
||||
let(:new_container) { described_class.new(nil) }
|
||||
let(:cli) { fire_double('Vagrant::LXC::CLI', list: ['valid']) }
|
||||
let(:cli) { fire_double('Vagrant::LXC::Container::CLI', list: ['valid']) }
|
||||
|
||||
it 'raises a NotFound error if an unknown container name gets provided' do
|
||||
expect {
|
||||
|
@ -32,147 +32,95 @@ describe Vagrant::LXC::Container do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'lxc commands execution' do
|
||||
let(:args) { @args }
|
||||
|
||||
before do
|
||||
subject.stub(:execute) { |*args| @args = args }
|
||||
subject.lxc :command, '--state', 'RUNNING'
|
||||
end
|
||||
|
||||
it 'prepends sudo' do
|
||||
args[0].should == 'sudo'
|
||||
end
|
||||
|
||||
it 'uses the first argument as lxc command suffix' do
|
||||
args[1].should == 'lxc-command'
|
||||
end
|
||||
|
||||
it 'pass through remaining arguments' do
|
||||
args[2].should == '--state'
|
||||
args[3].should == 'RUNNING'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'guard for container state' do
|
||||
let(:name) { 'random-container-name' }
|
||||
|
||||
before do
|
||||
subject.stub :lxc
|
||||
subject.wait_until :running
|
||||
end
|
||||
|
||||
it 'runs lxc-wait with the machine id and upcased state' do
|
||||
subject.should have_received(:lxc).with(
|
||||
:wait,
|
||||
'--name', name,
|
||||
'--state', 'RUNNING'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'creation' do
|
||||
let(:name) { 'random-container-name' }
|
||||
let(:template_name) { 'template-name' }
|
||||
let(:rootfs_cache) { '/path/to/cache' }
|
||||
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
|
||||
subject.stub(lxc: true)
|
||||
SecureRandom.stub(hex: name)
|
||||
subject.create 'template-name' => template_name, 'rootfs-cache-path' => rootfs_cache, 'template-opts' => { '--foo' => 'bar'}
|
||||
end
|
||||
|
||||
it 'calls lxc-create with the right arguments' do
|
||||
subject.should have_received(:lxc).with(
|
||||
:create,
|
||||
'--template', template_name,
|
||||
'--name', name,
|
||||
'--',
|
||||
'--auth-key', public_key_path,
|
||||
'--cache', rootfs_cache,
|
||||
'--foo', 'bar'
|
||||
it 'creates container with the right arguments' do
|
||||
cli.should have_received(:create).with(
|
||||
template_name,
|
||||
'--auth-key' => public_key_path,
|
||||
'--cache' => rootfs_cache,
|
||||
'--foo' => 'bar'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'destruction' do
|
||||
let(:name) { 'container-name' }
|
||||
let(:cli) { fire_double('Vagrant::LXC::Container::CLI', destroy: true) }
|
||||
|
||||
before do
|
||||
subject.stub(lxc: true)
|
||||
subject.destroy
|
||||
end
|
||||
subject { described_class.new(name, cli) }
|
||||
|
||||
it 'calls lxc-destroy with the right arguments' do
|
||||
subject.should have_received(:lxc).with(
|
||||
:destroy,
|
||||
'--name', name,
|
||||
)
|
||||
before { subject.destroy }
|
||||
|
||||
it 'delegates to cli object' do
|
||||
cli.should have_received(:destroy)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'start' do
|
||||
let(:config) { mock(:config, start_opts: ['a=1', 'b=2']) }
|
||||
let(:config) { mock(:config, start_opts: {'a' => '1', 'b' => '2'}) }
|
||||
let(:name) { 'container-name' }
|
||||
let(:cli) { fire_double('Vagrant::LXC::Container::CLI', start: true) }
|
||||
|
||||
subject { described_class.new(name, cli) }
|
||||
|
||||
before do
|
||||
subject.stub(lxc: true, wait_until: true)
|
||||
cli.stub(:transition_to).and_yield(cli)
|
||||
end
|
||||
|
||||
it 'starts container with configured lxc settings' do
|
||||
cli.should_receive(:start).with('a' => '1', 'b' => '2')
|
||||
subject.start(config)
|
||||
end
|
||||
|
||||
it 'calls lxc-start with the right arguments' do
|
||||
subject.should have_received(:lxc).with(
|
||||
:start,
|
||||
'-d',
|
||||
'--name', name,
|
||||
'-s', 'a=1',
|
||||
'-s', 'b=2'
|
||||
)
|
||||
end
|
||||
|
||||
it 'waits for container state to be RUNNING' do
|
||||
subject.should have_received(:wait_until).with(:running)
|
||||
it 'expects a transition to running state to take place' do
|
||||
cli.should_receive(:transition_to).with(:running)
|
||||
subject.start(config)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'halt' do
|
||||
let(:name) { 'random-container-name' }
|
||||
let(:name) { 'container-name' }
|
||||
let(:cli) { fire_double('Vagrant::LXC::Container::CLI', shutdown: true) }
|
||||
|
||||
subject { described_class.new(name, cli) }
|
||||
|
||||
before do
|
||||
subject.stub(lxc: true, wait_until: true)
|
||||
cli.stub(:transition_to).and_yield(cli)
|
||||
end
|
||||
|
||||
it 'delegates to cli shutdown' do
|
||||
cli.should_receive(:shutdown)
|
||||
subject.halt
|
||||
end
|
||||
|
||||
it 'calls lxc-shutdown with the right arguments' do
|
||||
subject.should have_received(:lxc).with(
|
||||
:shutdown,
|
||||
'--name', name
|
||||
)
|
||||
end
|
||||
|
||||
it 'waits for container state to be STOPPED' do
|
||||
subject.should have_received(:wait_until).with(:stopped)
|
||||
it 'expects a transition to running state to take place' do
|
||||
cli.should_receive(:transition_to).with(:stopped)
|
||||
subject.halt
|
||||
end
|
||||
end
|
||||
|
||||
describe 'state' do
|
||||
let(:name) { 'random-container-name' }
|
||||
let(:name) { 'random-container-name' }
|
||||
let(:cli_state) { :something }
|
||||
let(:cli) { fire_double('Vagrant::LXC::Container::CLI', state: cli_state) }
|
||||
|
||||
before do
|
||||
subject.stub(lxc: "state: STOPPED\npid: 2")
|
||||
end
|
||||
subject { described_class.new(name, cli) }
|
||||
|
||||
it 'calls lxc-info with the right arguments' do
|
||||
subject.state
|
||||
subject.should have_received(:lxc).with(
|
||||
:info,
|
||||
'--name', name
|
||||
)
|
||||
end
|
||||
|
||||
it 'maps the output of lxc-info status out to a symbol' do
|
||||
subject.state.should == :stopped
|
||||
it 'delegates to cli' do
|
||||
subject.state.should == cli_state
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue