From f454924a59e6466f316ce6cedc60b81628874556 Mon Sep 17 00:00:00 2001 From: Azamat Khudaygulov Date: Tue, 23 Sep 2014 16:07:03 +0400 Subject: [PATCH] The path of storage containers taken from lxc-config, instead of using a constant for lxc>=1.0.0. * for lxc to 1.0.0 using constant Vagrant::LXC::Driver::DEFAULT_CONTAINERS_PATH * change method Vagrant::LXC::Driver::CLI#version to call lxc-create if lxc-version command not exists (to lxc version 1.0.0) --- lib/vagrant-lxc/driver.rb | 11 ++++++--- lib/vagrant-lxc/driver/cli.rb | 25 +++++++++++++++++-- lib/vagrant-lxc/errors.rb | 4 +++ locales/en.yml | 4 +++ spec/unit/driver/cli_spec.rb | 46 ++++++++++++++++++++++++++++++++--- spec/unit/driver_spec.rb | 27 +++++++++++++++++++- 6 files changed, 107 insertions(+), 10 deletions(-) diff --git a/lib/vagrant-lxc/driver.rb b/lib/vagrant-lxc/driver.rb index 04adeff..dbba577 100644 --- a/lib/vagrant-lxc/driver.rb +++ b/lib/vagrant-lxc/driver.rb @@ -13,8 +13,8 @@ module Vagrant # a name. class ContainerNotFound < StandardError; end - # Root folder where container configs are stored - CONTAINERS_PATH = '/var/lib/lxc' + # Default root folder where container configs are stored + DEFAULT_CONTAINERS_PATH = '/var/lib/lxc' attr_reader :container_name, :customizations @@ -31,12 +31,17 @@ module Vagrant raise ContainerNotFound if @container_name && ! @cli.list.include?(@container_name) end + # Root folder where container configs are stored + def containers_path + @containers_path ||= @cli.support_config_command? ? @cli.config('lxc.lxcpath') : DEFAULT_CONTAINERS_PATH + end + def all_containers @cli.list end def base_path - Pathname.new("#{CONTAINERS_PATH}/#{@container_name}") + Pathname.new("#{containers_path}/#{@container_name}") end def rootfs_path diff --git a/lib/vagrant-lxc/driver/cli.rb b/lib/vagrant-lxc/driver/cli.rb index d7ada25..128eb22 100644 --- a/lib/vagrant-lxc/driver/cli.rb +++ b/lib/vagrant-lxc/driver/cli.rb @@ -28,14 +28,24 @@ module Vagrant end def version - if run(:version) =~ /lxc version:\s+(.+)\s*$/ - $1.downcase + return @version if @version + @version = support_version_command? ? run(:version) : run(:create, '--version') + if @version =~ /(lxc version:\s+|)(.+)\s*$/ + @version = $2.downcase else # TODO: Raise an user friendly error raise 'Unable to parse lxc version!' end end + def config(param) + if support_config_command? + run(:config, param).gsub("\n", '') + else + raise Errors::CommandNotSupported, name: 'config', available_version: '> 1.x.x', version: version + end + end + def state if @name && run(:info, '--name', @name, retryable: true) =~ /^state:[^A-Z]+([A-Z]+)$/i $1.downcase.to_sym @@ -134,6 +144,17 @@ module Vagrant return @supports_attach end + def support_config_command? + version[0].to_i >= 1 + end + + def support_version_command? + @sudo_wrapper.run('which', 'lxc-version') + return true + rescue Vagrant::LXC::Errors::ExecuteError + return false + end + private def run(command, *args) diff --git a/lib/vagrant-lxc/errors.rb b/lib/vagrant-lxc/errors.rb index c75bfa3..4446b70 100644 --- a/lib/vagrant-lxc/errors.rb +++ b/lib/vagrant-lxc/errors.rb @@ -26,6 +26,10 @@ module Vagrant error_key(:lxc_container_already_exists) end + class CommandNotSupported < Vagrant::Errors::VagrantError + error_key(:lxc_command_not_supported) + end + # Box related errors class TemplateFileMissing < Vagrant::Errors::VagrantError error_key(:lxc_template_file_missing) diff --git a/locales/en.yml b/locales/en.yml index 37c0188..51f8d8c 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -66,3 +66,7 @@ en: There is container on your system with the same name you've specified on your Vagrantfile (%{name}), please choose a different one or run `lxc-destroy --name %{name}` and try again. + + lxc_command_not_supported: |- + Command (lxc-%{command}) not supported in version %{version}. + This command is available with version %{available_version}. diff --git a/spec/unit/driver/cli_spec.rb b/spec/unit/driver/cli_spec.rb index 7ddd66b..a3e0114 100644 --- a/spec/unit/driver/cli_spec.rb +++ b/spec/unit/driver/cli_spec.rb @@ -29,14 +29,52 @@ describe Vagrant::LXC::Driver::CLI do end describe 'version' do - let(:lxc_version_out) { "lxc version: 0.x.y-rc1\n" } - before do allow(subject).to receive(:run).with(:version).and_return(lxc_version_out) end - it 'parses the version from the output' do - expect(subject.version).to eq('0.x.y-rc1') + describe 'lxc version before 1.x.x' do + let(:lxc_version_out) { "lxc version: 0.x.y-rc1\n" } + + it 'parses the version from the output' do + expect(subject.version).to eq('0.x.y-rc1') + end + end + + describe 'lxc version after 1.x.x' do + let(:lxc_version_out) { "1.0.0\n" } + + it 'parses the version from the output' do + expect(subject.version).to eq('1.0.0') + end + end + end + + describe 'config' do + before do + allow(subject).to receive(:run).with(:config, 'lxc.lxcpath').and_return(lxc_config_out) + allow(subject).to receive(:run).with(:version).and_return(lxc_version_out) + allow(subject).to receive(:run).with(:create, '--version').and_return(lxc_version_out) + end + + describe 'lxc version before 1.x.x' do + let(:support_version_command?) { true } + let(:lxc_config_out) { "/var/lib/lxc\n" } + let(:lxc_version_out) { "lxc version: 0.x.y-rc1\n" } + + it 'not supported' do + expect{subject.config('lxc.lxcpath')}.to raise_error(Vagrant::LXC::Errors::CommandNotSupported) + end + end + + describe 'lxc version before after 1.x.x'do + let(:support_version_command?) { false } + let(:lxc_config_out) { "/var/lib/lxc\n" } + let(:lxc_version_out) { "1.0.0\n" } + + it 'parser the lxc.lxcpath value' do + expect(subject.config('lxc.lxcpath')).not_to end_with("\n") + end end end diff --git a/spec/unit/driver_spec.rb b/spec/unit/driver_spec.rb index 6bab0cc..69534b9 100644 --- a/spec/unit/driver_spec.rb +++ b/spec/unit/driver_spec.rb @@ -89,7 +89,7 @@ describe Vagrant::LXC::Driver do describe 'start' do let(:customizations) { [['a', '1'], ['b', '2']] } let(:internal_customization) { ['internal', 'customization'] } - let(:cli) { double(Vagrant::LXC::Driver::CLI, start: true) } + let(:cli) { double(Vagrant::LXC::Driver::CLI, start: true, support_config_command?: false) } let(:sudo) { double(Vagrant::LXC::SudoWrapper) } subject { described_class.new('name', sudo, cli) } @@ -99,6 +99,7 @@ describe Vagrant::LXC::Driver do and_return('# CONFIGURATION') sudo.should_receive(:run).twice.with('cp', '-f', %r{/tmp/.*}, '/var/lib/lxc/name/config') sudo.should_receive(:run).twice.with('chown', 'root:root', '/var/lib/lxc/name/config') + subject.customizations << internal_customization subject.start(customizations) end @@ -150,6 +151,30 @@ describe Vagrant::LXC::Driver do end end + describe 'containers_path' do + let(:cli) { double(Vagrant::LXC::Driver::CLI, config: cli_config_value, support_config_command?: cli_support_config_command_value) } + + subject { described_class.new('name', nil, cli) } + + describe 'lxc version before 1.x.x' do + let(:cli_support_config_command_value) { false } + let(:cli_config_value) { '/var/lib/lxc' } + + it 'delegates to cli' do + expect(subject.containers_path).to eq(cli_config_value) + end + end + + describe 'lxc version after 1.x.x' do + let(:cli_support_config_command_value) { true } + let(:cli_config_value) { '/etc/lxc' } + + it 'delegates to cli' do + expect(subject.containers_path).to eq(cli_config_value) + end + end + end + describe 'folder sharing' do let(:shared_folder) { {guestpath: '/vagrant', hostpath: '/path/to/host/dir'} } let(:ro_rw_folder) { {guestpath: '/vagrant/ro_rw', hostpath: '/path/to/host/dir', mount_options: ['ro', 'rw']} }