Merge pull request #249 from fgrehm/vagrant-1.5
Support for Vagrant 1.5
This commit is contained in:
commit
f20f6aaa40
45 changed files with 550 additions and 559 deletions
|
@ -1,8 +1,8 @@
|
|||
language: ruby
|
||||
rvm:
|
||||
- 1.9.3
|
||||
- 2.0.0
|
||||
- 2.1.1
|
||||
matrix:
|
||||
allow_failures:
|
||||
- rvm: 2.0.0
|
||||
- rvm: 2.1.1
|
||||
script: "bundle exec rake ci"
|
||||
|
|
2
BOXES.md
2
BOXES.md
|
@ -52,5 +52,5 @@ on knowing what makes a base box for vagrant-lxc, here's what's needed:
|
|||
| --- | --- | --- |
|
||||
| `provider` | Yes | Required by Vagrant |
|
||||
| `version` | Yes | Tracks backward incompatibilities |
|
||||
| `built-on` | No | Date / time when the box was packaged |
|
||||
| `built-on` | No | Date / time when the box was packaged for the first time |
|
||||
| `template-opts` | No | Extra options to be passed to the `lxc-template` script provided with the .box package |
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## [0.8.1](https://github.com/fgrehm/vagrant-lxc/compare/v0.8.0...master) (unreleased)
|
||||
## [1.0.0.beta1](https://github.com/fgrehm/vagrant-lxc/compare/v0.8.0...master) (unreleased)
|
||||
|
||||
DEPRECATIONS:
|
||||
|
||||
|
|
23
Gemfile
23
Gemfile
|
@ -3,22 +3,23 @@ source 'https://rubygems.org'
|
|||
gemspec
|
||||
|
||||
group :development do
|
||||
gem 'vagrant', github: 'mitchellh/vagrant'
|
||||
gem 'vagrant-cachier', github: 'fgrehm/vagrant-cachier'
|
||||
gem 'vagrant-pristine', github: 'fgrehm/vagrant-pristine'
|
||||
gem 'vagrant-omnibus'
|
||||
gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git'
|
||||
gem 'guard'
|
||||
gem 'guard-rspec'
|
||||
gem 'rb-inotify'
|
||||
end
|
||||
|
||||
|
||||
group :development, :test do
|
||||
gem 'rake'
|
||||
# Update https://github.com/fgrehm/vagrant-lxc/issues/111 once we are able to
|
||||
# upgrade to a newer release
|
||||
gem 'rspec', '~> 2.13.0'
|
||||
gem 'rspec-fire', require: 'rspec/fire'
|
||||
gem 'rspec-spies', require: false
|
||||
gem 'coveralls', require: false
|
||||
gem 'rspec', '2.99.0.beta2'
|
||||
gem 'coveralls', require: (ENV['COVERAGE'] == 'true')
|
||||
gem 'vagrant-spec', git: 'https://github.com/mitchellh/vagrant-spec.git'
|
||||
end
|
||||
|
||||
group :plugins do
|
||||
gem 'vagrant-lxc', path: '.'
|
||||
acceptance = (ENV['ACCEPTANCE'] == 'true')
|
||||
gem 'vagrant-cachier', git: 'https://github.com/fgrehm/vagrant-cachier.git', require: !acceptance
|
||||
gem 'vagrant-pristine', git: 'https://github.com/fgrehm/vagrant-pristine.git', require: !acceptance
|
||||
gem 'vagrant-omnibus', require: !acceptance
|
||||
end
|
||||
|
|
114
Gemfile.lock
114
Gemfile.lock
|
@ -1,40 +1,54 @@
|
|||
GIT
|
||||
remote: git://github.com/fgrehm/vagrant-cachier.git
|
||||
revision: 2faa6615466f8d518893f5ba51b493b877d2efde
|
||||
remote: https://github.com/fgrehm/vagrant-cachier.git
|
||||
revision: 2df1e319408a7e6f1c6e75d48e36591199e98527
|
||||
specs:
|
||||
vagrant-cachier (0.6.1.dev)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/fgrehm/vagrant-pristine.git
|
||||
revision: 4638491786943bfbf6f115b1fc379f069963fe46
|
||||
remote: https://github.com/fgrehm/vagrant-pristine.git
|
||||
revision: 503dbc47848c81d0fbfa6840491856f518d244a1
|
||||
specs:
|
||||
vagrant-pristine (0.3.0)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/mitchellh/vagrant.git
|
||||
revision: a92e03cf4ce936243d3959b7b5603262a234a58d
|
||||
remote: https://github.com/mitchellh/vagrant-spec.git
|
||||
revision: aae28ee57071cdd121ca782c6e0709a5c650a4be
|
||||
specs:
|
||||
vagrant (1.3.6.dev)
|
||||
childprocess (~> 0.3.7)
|
||||
vagrant-spec (0.0.1)
|
||||
childprocess (~> 0.5.0)
|
||||
log4r (~> 1.1.9)
|
||||
rspec (~> 2.14)
|
||||
thor (~> 0.18.1)
|
||||
|
||||
GIT
|
||||
remote: https://github.com/mitchellh/vagrant.git
|
||||
revision: 56dd0e8531e1810fc3ceb17411eeded711794f59
|
||||
specs:
|
||||
vagrant (1.5.1.dev)
|
||||
bundler (~> 1.5.2)
|
||||
childprocess (~> 0.5.0)
|
||||
erubis (~> 2.7.0)
|
||||
i18n (~> 0.6.0)
|
||||
log4r (~> 1.1.9)
|
||||
listen (~> 2.4.0)
|
||||
log4r (~> 1.1.9, < 1.1.11)
|
||||
net-scp (~> 1.1.0)
|
||||
net-ssh (~> 2.6.6)
|
||||
net-ssh (>= 2.6.6, < 2.8.0)
|
||||
rb-kqueue (~> 0.2.0)
|
||||
wdm (~> 0.1.0)
|
||||
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
vagrant-lxc (0.8.1.dev)
|
||||
vagrant-lxc (1.0.0.beta1.dev)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
celluloid (0.15.2)
|
||||
timers (~> 1.1.0)
|
||||
childprocess (0.3.9)
|
||||
childprocess (0.5.1)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
coderay (1.0.9)
|
||||
coderay (1.1.0)
|
||||
coveralls (0.7.0)
|
||||
multi_json (~> 1.3)
|
||||
rest-client
|
||||
|
@ -42,64 +56,65 @@ GEM
|
|||
term-ansicolor
|
||||
thor
|
||||
diff-lcs (1.2.5)
|
||||
docile (1.1.3)
|
||||
erubis (2.7.0)
|
||||
ffi (1.9.3)
|
||||
formatador (0.2.4)
|
||||
guard (2.2.3)
|
||||
guard (2.4.0)
|
||||
formatador (>= 0.2.4)
|
||||
listen (~> 2.1)
|
||||
lumberjack (~> 1.0)
|
||||
pry (>= 0.9.12)
|
||||
thor (>= 0.18.1)
|
||||
guard-rspec (3.1.0)
|
||||
guard (>= 1.8)
|
||||
rspec (~> 2.13)
|
||||
i18n (0.6.5)
|
||||
listen (2.2.0)
|
||||
guard-rspec (4.2.8)
|
||||
guard (~> 2.1)
|
||||
rspec (>= 2.14, < 4.0)
|
||||
i18n (0.6.9)
|
||||
listen (2.4.1)
|
||||
celluloid (>= 0.15.2)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
log4r (1.1.10)
|
||||
lumberjack (1.0.4)
|
||||
method_source (0.8.2)
|
||||
mime-types (2.0)
|
||||
multi_json (1.8.2)
|
||||
mime-types (2.1)
|
||||
multi_json (1.9.0)
|
||||
net-scp (1.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.6.8)
|
||||
pry (0.9.12.2)
|
||||
coderay (~> 1.0.5)
|
||||
net-ssh (2.7.0)
|
||||
pry (0.9.12.6)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
rake (10.1.0)
|
||||
rb-fsevent (0.9.3)
|
||||
rb-inotify (0.9.2)
|
||||
rake (10.1.1)
|
||||
rb-fsevent (0.9.4)
|
||||
rb-inotify (0.9.3)
|
||||
ffi (>= 0.5.0)
|
||||
rb-kqueue (0.2.2)
|
||||
ffi (>= 0.5.0)
|
||||
rest-client (1.6.7)
|
||||
mime-types (>= 1.16)
|
||||
rspec (2.13.0)
|
||||
rspec-core (~> 2.13.0)
|
||||
rspec-expectations (~> 2.13.0)
|
||||
rspec-mocks (~> 2.13.0)
|
||||
rspec-core (2.13.1)
|
||||
rspec-expectations (2.13.0)
|
||||
rspec (2.99.0.beta2)
|
||||
rspec-core (= 2.99.0.beta2)
|
||||
rspec-expectations (= 2.99.0.beta2)
|
||||
rspec-mocks (= 2.99.0.beta2)
|
||||
rspec-core (2.99.0.beta2)
|
||||
rspec-expectations (2.99.0.beta2)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-fire (1.3.0)
|
||||
rspec (>= 2.11, < 4)
|
||||
rspec-mocks (2.13.1)
|
||||
rspec-spies (2.1.4)
|
||||
rspec (~> 2.0)
|
||||
simplecov (0.7.1)
|
||||
multi_json (~> 1.0)
|
||||
simplecov-html (~> 0.7.1)
|
||||
simplecov-html (0.7.1)
|
||||
slop (3.4.6)
|
||||
term-ansicolor (1.2.2)
|
||||
tins (~> 0.8)
|
||||
rspec-mocks (2.99.0.beta2)
|
||||
simplecov (0.8.2)
|
||||
docile (~> 1.1.0)
|
||||
multi_json
|
||||
simplecov-html (~> 0.8.0)
|
||||
simplecov-html (0.8.0)
|
||||
slop (3.5.0)
|
||||
term-ansicolor (1.3.0)
|
||||
tins (~> 1.0)
|
||||
thor (0.18.1)
|
||||
timers (1.1.0)
|
||||
tins (0.13.0)
|
||||
vagrant-omnibus (1.1.2)
|
||||
tins (1.0.0)
|
||||
vagrant-omnibus (1.3.1)
|
||||
wdm (0.1.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
@ -110,11 +125,10 @@ DEPENDENCIES
|
|||
guard-rspec
|
||||
rake
|
||||
rb-inotify
|
||||
rspec (~> 2.13.0)
|
||||
rspec-fire
|
||||
rspec-spies
|
||||
rspec (= 2.99.0.beta2)
|
||||
vagrant!
|
||||
vagrant-cachier!
|
||||
vagrant-lxc!
|
||||
vagrant-omnibus
|
||||
vagrant-pristine!
|
||||
vagrant-spec!
|
||||
|
|
10
README.md
10
README.md
|
@ -9,14 +9,18 @@ as an alternative to the built in VirtualBox provider for Linux hosts. Check out
|
|||
[this blog post](http://fabiorehm.com/blog/2013/04/28/lxc-provider-for-vagrant/)
|
||||
to see it in action.
|
||||
|
||||
**NOTICE:** The master branch is targetting an initial beta for 1.0.0, for the
|
||||
latest stable version of the plugin, please check the [0.8-stable](https://github.com/fgrehm/vagrant-lxc/tree/0.8-stable)
|
||||
branch.
|
||||
|
||||
## Features / Limitations
|
||||
|
||||
## Features
|
||||
|
||||
* Provides the same workflow as the Vagrant VirtualBox provider
|
||||
* Port forwarding via [`redir`](http://linux.die.net/man/1/redir)
|
||||
* Does not support public / private networks
|
||||
* Assumes you have a `lxcbr0` bridge configured on your host similar to [Ubuntu's built-in](https://help.ubuntu.com/lts/serverguide/lxc.html#lxcbr0)
|
||||
|
||||
As of now, it does not support public / private networks, but [private networks](https://github.com/fgrehm/vagrant-lxc/issues/120)
|
||||
will be coming along _soon_.
|
||||
|
||||
## Requirements
|
||||
|
||||
|
|
12
lib/vagrant-backports/README.md
Normal file
12
lib/vagrant-backports/README.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
# vagrant-backports
|
||||
|
||||
<!--
|
||||
[![Build Status](https://travis-ci.org/fgrehm/vagrant-backports.png?branch=master)](https://travis-ci.org/fgrehm/vagrant-backports) [![Gem Version](https://badge.fury.io/rb/vagrant-backports.png)](http://badge.fury.io/rb/vagrant-backports) [![Code Climate](https://codeclimate.com/github/fgrehm/vagrant-backports.png)](https://codeclimate.com/github/fgrehm/vagrant-backports) [![Coverage Status](https://coveralls.io/repos/fgrehm/vagrant-backports/badge.png?branch=master)](https://coveralls.io/r/fgrehm/vagrant-backports) [![Gittip](http://img.shields.io/gittip/fgrehm.svg)](https://www.gittip.com/fgrehm/)
|
||||
-->
|
||||
|
||||
A _"hypothetical"_ gem that helps Vagrant plugin developers to stay sane when
|
||||
keeping up with Vagrant improvements by backporting parts of its recent versions
|
||||
functionality.
|
||||
|
||||
More information will be provided if there is enough interest on having this
|
||||
extracted as a separate gem.
|
1
lib/vagrant-backports/action/handle_box.rb
Normal file
1
lib/vagrant-backports/action/handle_box.rb
Normal file
|
@ -0,0 +1 @@
|
|||
Vagrant::Action::Builtin.const_set :HandleBox, Vagrant::Action::Builtin::HandleBoxUrl
|
34
lib/vagrant-backports/action/is_state.rb
Normal file
34
lib/vagrant-backports/action/is_state.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
module Vagrant
|
||||
module Backports
|
||||
module Action
|
||||
# This middleware is meant to be used with Call and can check if
|
||||
# a machine is in the given state ID.
|
||||
class IsState
|
||||
# Note: Any of the arguments can be arrays as well.
|
||||
#
|
||||
# @param [Symbol] target_state The target state ID that means that
|
||||
# the machine was properly shut down.
|
||||
# @param [Symbol] source_state The source state ID that the machine
|
||||
# must be in to be shut down.
|
||||
def initialize(app, env, check, **opts)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new("vagrant::action::builtin::is_state")
|
||||
@check = check
|
||||
@invert = !!opts[:invert]
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@logger.debug("Checking if machine state is '#{@check}'")
|
||||
state = env[:machine].state.id
|
||||
@logger.debug("-- Machine state: #{state}")
|
||||
|
||||
env[:result] = @check == state
|
||||
env[:result] = !env[:result] if @invert
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Vagrant::Action::Builtin.const_set :IsState, Vagrant::Backports::Action::IsState
|
20
lib/vagrant-backports/action/message.rb
Normal file
20
lib/vagrant-backports/action/message.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module Vagrant
|
||||
module Backports
|
||||
module Action
|
||||
# This middleware simply outputs a message to the UI.
|
||||
class Message
|
||||
def initialize(app, env, message, **opts)
|
||||
@app = app
|
||||
@message = message
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:ui].info(@message)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Vagrant::Action::Builtin.const_set :Message, Vagrant::Backports::Action::Message
|
|
@ -1,12 +1,11 @@
|
|||
# This acts like a backport of Vagrant's built in action from 1.3+ for older versions
|
||||
# and will probably be deprecated on 0.8+
|
||||
# This acts like a backport of Vagrant's built in action from 1.3+ for previous version
|
||||
# https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/action/builtin/wait_for_communicator.rb
|
||||
module Vagrant
|
||||
module LXC
|
||||
module Backports
|
||||
module Action
|
||||
class WaitForCommunicator
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
|
@ -21,7 +20,7 @@ module Vagrant
|
|||
max_tries = @env[:machine].config.ssh.max_tries.to_i
|
||||
max_tries.times do |i|
|
||||
if @env[:machine].communicate.ready?
|
||||
@env[:ui].info I18n.t("vagrant_lxc.messages.container_ready")
|
||||
@env[:ui].info 'Machine booted and ready!'
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -39,3 +38,5 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
Vagrant::Action::Builtin.const_set :WaitForCommunicator, Vagrant::Backports::Action::WaitForCommunicator
|
12
lib/vagrant-backports/ui.rb
Normal file
12
lib/vagrant-backports/ui.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
module Vagrant
|
||||
module UI
|
||||
class Interface
|
||||
def output(*args)
|
||||
info(*args)
|
||||
end
|
||||
def detail(*args)
|
||||
info(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
27
lib/vagrant-backports/utils.rb
Normal file
27
lib/vagrant-backports/utils.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
module Vagrant
|
||||
module Backports
|
||||
class << self
|
||||
def vagrant_1_2_or_later?
|
||||
greater_than?('1.2.0')
|
||||
end
|
||||
|
||||
def vagrant_1_3_or_later?
|
||||
greater_than?('1.3.0')
|
||||
end
|
||||
|
||||
def vagrant_1_4_or_later?
|
||||
greater_than?('1.4.0')
|
||||
end
|
||||
|
||||
def vagrant_1_5_or_later?
|
||||
greater_than?('1.5.0')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def greater_than?(version)
|
||||
Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new(version)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,28 +1,28 @@
|
|||
require 'vagrant-lxc/action/boot'
|
||||
require 'vagrant-lxc/action/check_created'
|
||||
require 'vagrant-lxc/action/check_running'
|
||||
require 'vagrant-lxc/action/clear_forwarded_ports'
|
||||
require 'vagrant-lxc/action/create'
|
||||
require 'vagrant-lxc/action/created'
|
||||
require 'vagrant-lxc/action/destroy'
|
||||
require 'vagrant-lxc/action/destroy_confirm'
|
||||
require 'vagrant-lxc/action/disconnect'
|
||||
require 'vagrant-lxc/action/compress_rootfs'
|
||||
require 'vagrant-lxc/action/fetch_ip_with_lxc_attach'
|
||||
require 'vagrant-lxc/action/fetch_ip_from_dnsmasq_leases'
|
||||
require 'vagrant-lxc/action/forced_halt'
|
||||
require 'vagrant-lxc/action/forward_ports'
|
||||
require 'vagrant-lxc/action/handle_box_metadata'
|
||||
require 'vagrant-lxc/action/is_running'
|
||||
require 'vagrant-lxc/action/message'
|
||||
require 'vagrant-lxc/action/prepare_nfs_settings'
|
||||
require 'vagrant-lxc/action/prepare_nfs_valid_ids'
|
||||
require 'vagrant-lxc/action/remove_temporary_files'
|
||||
require 'vagrant-lxc/action/setup_package_files'
|
||||
require 'vagrant-lxc/action/share_folders'
|
||||
require 'vagrant-lxc/action/warn_networks'
|
||||
|
||||
unless Vagrant::LXC.vagrant_1_3_or_later
|
||||
require 'vagrant-lxc/action/wait_for_communicator'
|
||||
Vagrant::Action::Builtin.const_set :WaitForCommunicator, Vagrant::LXC::Action::WaitForCommunicator
|
||||
unless Vagrant::Backports.vagrant_1_3_or_later?
|
||||
require 'vagrant-backports/action/wait_for_communicator'
|
||||
end
|
||||
unless Vagrant::Backports.vagrant_1_5_or_later?
|
||||
require 'vagrant-backports/ui'
|
||||
require 'vagrant-backports/action/handle_box'
|
||||
require 'vagrant-backports/action/message'
|
||||
require 'vagrant-backports/action/is_state'
|
||||
end
|
||||
|
||||
module Vagrant
|
||||
|
@ -37,9 +37,9 @@ module Vagrant
|
|||
# machine back up with the new configuration.
|
||||
def self.action_reload
|
||||
Builder.new.tap do |b|
|
||||
b.use Builtin::Call, Created do |env1, b2|
|
||||
if !env1[:result]
|
||||
b2.use Message, :not_created
|
||||
b.use Builtin::Call, Builtin::IsState, :not_created do |env1, b2|
|
||||
if env1[:result]
|
||||
b2.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_created")
|
||||
next
|
||||
end
|
||||
|
||||
|
@ -57,7 +57,15 @@ module Vagrant
|
|||
b.use Builtin::Provision
|
||||
b.use Builtin::EnvSet, :port_collision_repair => true
|
||||
b.use Builtin::HandleForwardedPortCollisions
|
||||
b.use ShareFolders
|
||||
if Vagrant::Backports.vagrant_1_4_or_later?
|
||||
b.use PrepareNFSValidIds
|
||||
b.use Builtin::SyncedFolderCleanup
|
||||
b.use Builtin::SyncedFolders
|
||||
b.use PrepareNFSSettings
|
||||
else
|
||||
require 'vagrant-lxc/backports/action/share_folders'
|
||||
b.use ShareFolders
|
||||
end
|
||||
b.use Builtin::SetHostname
|
||||
b.use WarnNetworks
|
||||
b.use ForwardPorts
|
||||
|
@ -70,15 +78,15 @@ module Vagrant
|
|||
def self.action_provision
|
||||
Builder.new.tap do |b|
|
||||
b.use Builtin::ConfigValidate
|
||||
b.use Builtin::Call, Created do |env1, b2|
|
||||
if !env1[:result]
|
||||
b2.use Message, :not_created
|
||||
b.use Builtin::Call, Builtin::IsState, :not_created do |env1, b2|
|
||||
if env1[:result]
|
||||
b2.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_created")
|
||||
next
|
||||
end
|
||||
|
||||
b2.use Builtin::Call, IsRunning do |env2, b3|
|
||||
b2.use Builtin::Call, Builtin::IsState, :running do |env2, b3|
|
||||
if !env2[:result]
|
||||
b3.use Message, :not_running
|
||||
b3.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_running")
|
||||
next
|
||||
end
|
||||
|
||||
|
@ -93,7 +101,7 @@ module Vagrant
|
|||
def self.action_start
|
||||
Builder.new.tap do |b|
|
||||
b.use Builtin::ConfigValidate
|
||||
b.use Builtin::Call, IsRunning do |env, b2|
|
||||
b.use Builtin::Call, Builtin::IsState, :running do |env, b2|
|
||||
# If the VM is running, then our work here is done, exit
|
||||
next if env[:result]
|
||||
b2.use action_boot
|
||||
|
@ -106,10 +114,10 @@ module Vagrant
|
|||
def self.action_up
|
||||
Builder.new.tap do |b|
|
||||
b.use Builtin::ConfigValidate
|
||||
b.use Builtin::Call, Created do |env, b2|
|
||||
b.use Builtin::Call, Builtin::IsState, :not_created do |env, b2|
|
||||
# If the VM is NOT created yet, then do the setup steps
|
||||
if !env[:result]
|
||||
b2.use Builtin::HandleBoxUrl
|
||||
if env[:result]
|
||||
b2.use Builtin::HandleBox
|
||||
b2.use HandleBoxMetadata
|
||||
b2.use Create
|
||||
end
|
||||
|
@ -122,19 +130,18 @@ module Vagrant
|
|||
# the virtual machine, gracefully or by force.
|
||||
def self.action_halt
|
||||
Builder.new.tap do |b|
|
||||
b.use Builtin::Call, Created do |env, b2|
|
||||
b.use Builtin::Call, Builtin::IsState, :not_created do |env, b2|
|
||||
if env[:result]
|
||||
# TODO: Remove once we drop support for vagrant 1.1
|
||||
b2.use Disconnect
|
||||
b2.use ClearForwardedPorts
|
||||
b2.use RemoveTemporaryFiles
|
||||
b2.use Builtin::Call, Builtin::GracefulHalt, :stopped, :running do |env2, b3|
|
||||
if !env2[:result]
|
||||
b3.use ForcedHalt
|
||||
end
|
||||
b2.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_created")
|
||||
next
|
||||
end
|
||||
|
||||
b2.use ClearForwardedPorts
|
||||
b2.use RemoveTemporaryFiles
|
||||
b2.use Builtin::Call, Builtin::GracefulHalt, :stopped, :running do |env2, b3|
|
||||
if !env2[:result]
|
||||
b3.use ForcedHalt
|
||||
end
|
||||
else
|
||||
b2.use Message, :not_created
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -144,9 +151,9 @@ module Vagrant
|
|||
# freeing the resources of the underlying virtual machine.
|
||||
def self.action_destroy
|
||||
Builder.new.tap do |b|
|
||||
b.use Builtin::Call, Created do |env1, b2|
|
||||
if !env1[:result]
|
||||
b2.use Message, :not_created
|
||||
b.use Builtin::Call, Builtin::IsState, :not_created do |env1, b2|
|
||||
if env1[:result]
|
||||
b2.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_created")
|
||||
next
|
||||
end
|
||||
|
||||
|
@ -157,11 +164,11 @@ module Vagrant
|
|||
b3.use Builtin::EnvSet, :force_halt => true
|
||||
b3.use action_halt
|
||||
b3.use Destroy
|
||||
if Vagrant::LXC.vagrant_1_3_or_later
|
||||
if Vagrant::Backports.vagrant_1_3_or_later?
|
||||
b3.use Builtin::ProvisionerCleanup
|
||||
end
|
||||
else
|
||||
b3.use Message, :will_not_destroy
|
||||
b3.use Builtin::Message, I18n.t("vagrant_lxc.messages.will_not_destroy")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -171,9 +178,9 @@ module Vagrant
|
|||
# This action packages the virtual machine into a single box file.
|
||||
def self.action_package
|
||||
Builder.new.tap do |b|
|
||||
b.use Builtin::Call, Created do |env1, b2|
|
||||
if !env1[:result]
|
||||
b2.use Message, :not_created
|
||||
b.use Builtin::Call, Builtin::IsState, :not_created do |env1, b2|
|
||||
if env1[:result]
|
||||
b2.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_created")
|
||||
next
|
||||
end
|
||||
|
||||
|
@ -198,18 +205,44 @@ module Vagrant
|
|||
# This is the action that will exec into an SSH shell.
|
||||
def self.action_ssh
|
||||
Builder.new.tap do |b|
|
||||
b.use CheckCreated
|
||||
b.use CheckRunning
|
||||
b.use Builtin::SSHExec
|
||||
b.use Builtin::ConfigValidate
|
||||
b.use Builtin::Call, Builtin::IsState, :not_created do |env, b2|
|
||||
if env[:result]
|
||||
b2.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_created")
|
||||
next
|
||||
end
|
||||
|
||||
b2.use Builtin::Call, Builtin::IsState, :running do |env1, b3|
|
||||
if !env1[:result]
|
||||
b3.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_running")
|
||||
next
|
||||
end
|
||||
|
||||
b3.use BuiltIn::SSHExec
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This is the action that will run a single SSH command.
|
||||
def self.action_ssh_run
|
||||
Builder.new.tap do |b|
|
||||
b.use CheckCreated
|
||||
b.use CheckRunning
|
||||
b.use Builtin::SSHRun
|
||||
b.use Builtin::ConfigValidate
|
||||
b.use Builtin::Call, Builtin::IsState, :not_created do |env, b2|
|
||||
if env[:result]
|
||||
b2.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_created")
|
||||
next
|
||||
end
|
||||
|
||||
b2.use Builtin::Call, Builtin::IsState, :running do |env1, b3|
|
||||
if !env1[:result]
|
||||
b3.use Builtin::Message, I18n.t("vagrant_lxc.messages.not_running")
|
||||
next
|
||||
end
|
||||
|
||||
b3.use Builtin::SSHRun
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
module Action
|
||||
class CheckCreated
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if env[:machine].state.id == :not_created
|
||||
raise Vagrant::Errors::VMNotCreatedError
|
||||
end
|
||||
|
||||
# Call the next if we have one (but we shouldn't, since this
|
||||
# middleware is built to run with the Call-type middlewares)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
module Action
|
||||
class CheckRunning
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if env[:machine].state.id != :running
|
||||
raise Vagrant::Errors::VMNotRunningError
|
||||
end
|
||||
|
||||
# Call the next if we have one (but we shouldn't, since this
|
||||
# middleware is built to run with the Call-type middlewares)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
module Action
|
||||
class Created
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# Set the result to be true if the machine is created.
|
||||
env[:result] = env[:machine].state.id != :not_created
|
||||
|
||||
# Call the next if we have one (but we shouldn't, since this
|
||||
# middleware is built to run with the Call-type middlewares)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,18 +0,0 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
module Action
|
||||
class Disconnect
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@app.call env
|
||||
# FIXME: Vagrant >= 1.1.3 should not need this
|
||||
# https://github.com/mitchellh/vagrant/compare/715539eac30bc9ae62ddbb6337d13f036f7b774d...ec1bae0#L2R128
|
||||
env[:machine].instance_variable_set(:@communicator, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
module Action
|
||||
class IsRunning
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:result] = env[:machine].state.id == :running
|
||||
|
||||
# Call the next if we have one (but we shouldn't, since this
|
||||
# middleware is built to run with the Call-type middlewares)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
module Action
|
||||
# XXX: Is this really needed? Should we contribute this back to Vagrant's core?
|
||||
class Message
|
||||
def initialize(app, env, msg_key, type = :info)
|
||||
@app = app
|
||||
@msg_key = msg_key
|
||||
@type = type
|
||||
end
|
||||
|
||||
def call(env)
|
||||
machine = env[:machine]
|
||||
message = I18n.t("vagrant_lxc.messages.#{@msg_key}", name: machine.name)
|
||||
|
||||
env[:ui].send @type, message
|
||||
|
||||
@app.call env
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
64
lib/vagrant-lxc/action/prepare_nfs_settings.rb
Normal file
64
lib/vagrant-lxc/action/prepare_nfs_settings.rb
Normal file
|
@ -0,0 +1,64 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
module Action
|
||||
class PrepareNFSSettings
|
||||
include Vagrant::Util::Retryable
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new("vagrant::action::vm::nfs")
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@machine = env[:machine]
|
||||
|
||||
@app.call(env)
|
||||
|
||||
# if using_nfs? # TODO: && !privileged_container?
|
||||
# raise Errors::NfsWithoutPrivilegedError
|
||||
# end
|
||||
|
||||
if using_nfs?
|
||||
@logger.info("Using NFS, preparing NFS settings by reading host IP and machine IP")
|
||||
add_ips_to_env!(env)
|
||||
end
|
||||
end
|
||||
|
||||
# We're using NFS if we have any synced folder with NFS configured. If
|
||||
# we are not using NFS we don't need to do the extra work to
|
||||
# populate these fields in the environment.
|
||||
def using_nfs?
|
||||
@machine.config.vm.synced_folders.any? { |_, opts| opts[:type] == :nfs }
|
||||
end
|
||||
|
||||
# TODO:
|
||||
# def privileged_container?
|
||||
# @machine.provider.driver.privileged?(@machine.id)
|
||||
# end
|
||||
|
||||
# Extracts the proper host and guest IPs for NFS mounts and stores them
|
||||
# in the environment for the SyncedFolder action to use them in
|
||||
# mounting.
|
||||
#
|
||||
# The ! indicates that this method modifies its argument.
|
||||
def add_ips_to_env!(env)
|
||||
provider = @machine.provider
|
||||
|
||||
host_ip = read_host_ip
|
||||
machine_ip = provider.ssh_info[:host]
|
||||
|
||||
raise Vagrant::Errors::NFSNoHostonlyNetwork if !host_ip || !machine_ip
|
||||
|
||||
env[:nfs_host_ip] = host_ip
|
||||
env[:nfs_machine_ip] = machine_ip
|
||||
end
|
||||
|
||||
def read_host_ip
|
||||
@machine.communicate.execute 'echo $SSH_CLIENT' do |buffer, output|
|
||||
return output.chomp.split(' ')[0] if buffer == :stdout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
19
lib/vagrant-lxc/action/prepare_nfs_valid_ids.rb
Normal file
19
lib/vagrant-lxc/action/prepare_nfs_valid_ids.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
module Action
|
||||
class PrepareNFSValidIds
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new("vagrant::action::vm::nfs")
|
||||
end
|
||||
|
||||
def call(env)
|
||||
machine = env[:machine]
|
||||
env[:nfs_valid_ids] = machine.provider.driver.all_containers
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -45,10 +45,12 @@ module Vagrant
|
|||
box_dir = @env[:machine].box.directory
|
||||
FileUtils.cp box_dir.join('lxc-template').to_s, @env['package.directory'].to_s
|
||||
FileUtils.cp box_dir.join('metadata.json').to_s, @env['package.directory'].to_s
|
||||
# TODO: Update built-on metadata.json
|
||||
if (conf = box_dir.join('lxc.conf')).exist?
|
||||
FileUtils.cp conf.to_s, @env['package.directory'].to_s
|
||||
end
|
||||
if (conf = box_dir.join('lxc-config')).exist?
|
||||
FileUtils.cp conf.to_s, @env['package.directory'].to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,10 @@ module Vagrant
|
|||
raise ContainerNotFound if @container_name && ! @cli.list.include?(@container_name)
|
||||
end
|
||||
|
||||
def all_containers
|
||||
@cli.list
|
||||
end
|
||||
|
||||
def base_path
|
||||
Pathname.new("#{CONTAINERS_PATH}/#{@container_name}")
|
||||
end
|
||||
|
@ -58,20 +62,24 @@ module Vagrant
|
|||
|
||||
def share_folders(folders)
|
||||
folders.each do |folder|
|
||||
guestpath = rootfs_path.join(folder[:guestpath].gsub(/^\//, ''))
|
||||
unless guestpath.directory?
|
||||
begin
|
||||
@logger.debug("Guest path doesn't exist, creating: #{guestpath}")
|
||||
@sudo_wrapper.run('mkdir', '-p', guestpath.to_s)
|
||||
rescue Errno::EACCES
|
||||
raise Vagrant::Errors::SharedFolderCreateFailed, :path => guestpath.to_s
|
||||
end
|
||||
end
|
||||
|
||||
@customizations << ['mount.entry', "#{folder[:hostpath]} #{guestpath} none bind 0 0"]
|
||||
share_folder(folder[:hostpath], folder[:guestpath])
|
||||
end
|
||||
end
|
||||
|
||||
def share_folder(host_path, guest_path)
|
||||
guest_path = rootfs_path.join(guest_path.gsub(/^\//, ''))
|
||||
unless guest_path.directory?
|
||||
begin
|
||||
@logger.debug("Guest path doesn't exist, creating: #{guest_path}")
|
||||
@sudo_wrapper.run('mkdir', '-p', guest_path.to_s)
|
||||
rescue Errno::EACCES
|
||||
raise Vagrant::Errors::SharedFolderCreateFailed, :path => guest_path.to_s
|
||||
end
|
||||
end
|
||||
|
||||
@customizations << ['mount.entry', "#{host_path} #{guest_path} none bind 0 0"]
|
||||
end
|
||||
|
||||
def start(customizations)
|
||||
@logger.info('Starting container...')
|
||||
|
||||
|
@ -87,6 +95,7 @@ module Vagrant
|
|||
|
||||
def forced_halt
|
||||
@logger.info('Shutting down container...')
|
||||
# TODO: Remove `lxc-shutdown` usage, graceful halt is enough
|
||||
@cli.transition_to(:stopped) { |c| c.shutdown }
|
||||
# REFACTOR: Do not use exception to control the flow
|
||||
rescue CLI::TargetStateNotReached, CLI::ShutdownNotSupported
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require "vagrant"
|
||||
require 'vagrant'
|
||||
require 'vagrant-backports/utils'
|
||||
|
||||
module Vagrant
|
||||
module LXC
|
||||
|
@ -9,7 +10,9 @@ module Vagrant
|
|||
LXC-based virtual machines.
|
||||
EOF
|
||||
|
||||
provider(:lxc, parallel: true) do
|
||||
extra = []
|
||||
extra << {parallel: true} if Vagrant::Backports.vagrant_1_2_or_later?
|
||||
provider(:lxc, *extra) do
|
||||
require File.expand_path("../provider", __FILE__)
|
||||
|
||||
I18n.load_path << File.expand_path(File.dirname(__FILE__) + '/../../locales/en.yml')
|
||||
|
@ -22,10 +25,20 @@ module Vagrant
|
|||
require File.expand_path("../config", __FILE__)
|
||||
Config
|
||||
end
|
||||
end
|
||||
|
||||
def self.vagrant_1_3_or_later
|
||||
Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.3.0')
|
||||
if Vagrant::Backports.vagrant_1_4_or_later?
|
||||
synced_folder(:lxc) do
|
||||
require File.expand_path("../synced_folder", __FILE__)
|
||||
SyncedFolder
|
||||
end
|
||||
end
|
||||
|
||||
if Vagrant::Backports.vagrant_1_5_or_later?
|
||||
provider_capability("lxc", "public_address") do
|
||||
require_relative "provider/cap/public_address"
|
||||
Provider::Cap::PublicAddress
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
17
lib/vagrant-lxc/provider/cap/public_address.rb
Normal file
17
lib/vagrant-lxc/provider/cap/public_address.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
class Provider
|
||||
module Cap
|
||||
module PublicAddress
|
||||
def self.public_address(machine)
|
||||
return nil if machine.state.id != :running
|
||||
|
||||
ssh_info = machine.ssh_info
|
||||
return nil if !ssh_info
|
||||
ssh_info[:host]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
38
lib/vagrant-lxc/synced_folder.rb
Normal file
38
lib/vagrant-lxc/synced_folder.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
||||
def usable?(machine)
|
||||
# These synced folders only work if the provider is LXC
|
||||
machine.provider_name == :lxc
|
||||
end
|
||||
|
||||
def prepare(machine, folders, _opts)
|
||||
machine.ui.output(I18n.t("vagrant.actions.lxc.share_folders.preparing"))
|
||||
|
||||
folders.each do |id, data|
|
||||
host_path = Pathname.new(File.expand_path(data[:hostpath], machine.env.root_path))
|
||||
guest_path = data[:guestpath]
|
||||
|
||||
if !host_path.directory? && data[:create]
|
||||
# Host path doesn't exist, so let's create it.
|
||||
@logger.info("Host path doesn't exist, creating: #{host_path}")
|
||||
|
||||
begin
|
||||
host_path.mkpath
|
||||
rescue Errno::EACCES
|
||||
raise Vagrant::Errors::SharedFolderCreateFailed,
|
||||
:path => hostpath.to_s
|
||||
end
|
||||
end
|
||||
|
||||
machine.provider.driver.share_folder(host_path, guest_path)
|
||||
# Guest path specified, so mount the folder to specified point
|
||||
machine.ui.detail(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
|
||||
guestpath: data[:guestpath],
|
||||
hostpath: data[:hostpath],
|
||||
guest_path: data[:guestpath]))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +1,5 @@
|
|||
module Vagrant
|
||||
module LXC
|
||||
VERSION = "0.8.1.dev"
|
||||
VERSION = "1.0.0.beta1.dev"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,11 +12,6 @@ en:
|
|||
Starting container...
|
||||
force_shutdown: |-
|
||||
Forcing shutdown of container...
|
||||
# TODO: Remove the following keys after we drop support for vagrant < 1.3
|
||||
waiting_for_start: |-
|
||||
Waiting for container to start. This should not take long.
|
||||
container_ready: |-
|
||||
Container started and ready for use!
|
||||
warn_networks: |-
|
||||
Warning! The LXC provider doesn't support any of the Vagrant public / private
|
||||
network configurations (ex: `config.vm.network :private_network, ip: "some-ip"`).
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
require 'acceptance_helper'
|
||||
|
||||
describe 'Sanity check' do
|
||||
after(:all) { destroy_container }
|
||||
|
||||
context 'running `vagrant up` from scratch' do
|
||||
before(:all) do
|
||||
destroy_container
|
||||
vagrant_up
|
||||
end
|
||||
|
||||
it 'creates a container' do
|
||||
containers = `sudo lxc-ls`.chomp.split(/\s+/).uniq
|
||||
expect(containers).to include vagrant_container_name
|
||||
end
|
||||
|
||||
it 'starts the newly created container' do
|
||||
status = `sudo lxc-info -n #{vagrant_container_name}`
|
||||
expect(status).to include 'RUNNING'
|
||||
end
|
||||
|
||||
it "is able to be SSH'ed" do
|
||||
expect(vagrant_ssh('hostname')).to eq 'lxc-test-box'
|
||||
end
|
||||
|
||||
it 'mounts shared folders with the right permissions' do
|
||||
vagrant_ssh 'mkdir -p /vagrant/tmp && echo -n "Shared" > /vagrant/tmp/shared'
|
||||
shared_file_contents = File.read('/vagrant/spec/tmp/shared')
|
||||
expect(shared_file_contents).to eq 'Shared'
|
||||
end
|
||||
|
||||
it 'provisions the container based on Vagrantfile configs' do
|
||||
provisioned_file_contents = File.read('/vagrant/spec/tmp/provisioning')
|
||||
expect(provisioned_file_contents).to eq 'Provisioned'
|
||||
end
|
||||
|
||||
it 'forwards configured ports' do
|
||||
output = `curl -s localhost:8080`.strip.chomp
|
||||
expect(output).to include 'It works!'
|
||||
end
|
||||
end
|
||||
|
||||
context '`vagrant halt` on a running container' do
|
||||
before(:all) do
|
||||
destroy_container
|
||||
vagrant_up
|
||||
vagrant_ssh 'touch /tmp/{some,files}'
|
||||
vagrant_halt
|
||||
end
|
||||
|
||||
it 'shuts down the container' do
|
||||
status = `sudo lxc-info -n #{vagrant_container_name}`
|
||||
expect(status).to include 'STOPPED'
|
||||
end
|
||||
|
||||
it 'clears forwarded ports' do
|
||||
`curl -s localhost:8080 --connect-timeout 2`
|
||||
expect($?.exitstatus).to_not eq 0
|
||||
end
|
||||
|
||||
it 'kills redir processes' do
|
||||
processes = `pgrep redir`
|
||||
expect($?.exitstatus).to_not eq 0
|
||||
end
|
||||
|
||||
xit 'removes files under `/tmp`' do
|
||||
container_tmp_files = `sudo ls -l "/var/lib/lxc/#{vagrant_container_name}/rootfs/tmp"`.split("\n")
|
||||
puts container_tmp_files.join("\n")
|
||||
expect(container_tmp_files).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context '`vagrant destroy`' do
|
||||
before(:all) do
|
||||
destroy_container
|
||||
vagrant_up
|
||||
@container_name = vagrant_container_name
|
||||
vagrant_destroy
|
||||
end
|
||||
|
||||
it 'destroys the underlying container' do
|
||||
containers = `sudo lxc-ls`.chomp.split(/\s+/).uniq
|
||||
expect(containers).to_not include @container_name
|
||||
end
|
||||
end
|
||||
|
||||
pending 'box packaging' do
|
||||
before(:all) do
|
||||
destroy_container
|
||||
vagrant_box_remove('new-box')
|
||||
vagrant_up
|
||||
vagrant_package
|
||||
@box_name = ENV['BOX_NAME']
|
||||
# This will make
|
||||
ENV["BOX_NAME"] = 'new-box'
|
||||
ENV['BOX_URL'] = '/vagrant/spec/tmp/package.box'
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
vagrant_box_remove('new-box')
|
||||
ENV["BOX_NAME"] = @box_name
|
||||
ENV['BOX_URL'] = nil
|
||||
end
|
||||
|
||||
it 'creates a package that can be successfully brought up on a later `vagrant up`' do
|
||||
vagrant_up
|
||||
# Just to make sure we packaged it properly
|
||||
expect(vagrant_ssh('cat /home/vagrant/original-box')).to eq @box_name
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,76 +0,0 @@
|
|||
module AcceptanceExampleGroup
|
||||
def self.included(base)
|
||||
base.metadata[:type] = :acceptance
|
||||
end
|
||||
|
||||
ID_FILE = "/vagrant/spec/.vagrant/machines/default/lxc/id"
|
||||
def vagrant_container_name
|
||||
File.read(ID_FILE).strip.chomp if File.exists?(ID_FILE)
|
||||
end
|
||||
|
||||
def destroy_container
|
||||
if name = vagrant_container_name
|
||||
`sudo lxc-shutdown -n #{name} 2>/dev/null`
|
||||
`sudo lxc-wait -n #{name} --state STOPPED 2>/dev/null`
|
||||
`sudo lxc-destroy -n #{name} 2>/dev/null`
|
||||
`rm -rf /vagrant/spec/.vagrant/`
|
||||
end
|
||||
`sudo killall -9 redir 2>/dev/null`
|
||||
end
|
||||
|
||||
def with_vagrant_environment
|
||||
opts = { cwd: '/vagrant/spec', ui_class: TestUI }
|
||||
env = Vagrant::Environment.new(opts)
|
||||
yield env
|
||||
env.unload
|
||||
end
|
||||
|
||||
def vagrant_up
|
||||
with_vagrant_environment do |env|
|
||||
env.cli('up', '--provider', 'lxc')
|
||||
end
|
||||
end
|
||||
|
||||
def vagrant_halt
|
||||
with_vagrant_environment do |env|
|
||||
env.cli('halt')
|
||||
end
|
||||
end
|
||||
|
||||
def vagrant_destroy
|
||||
with_vagrant_environment do |env|
|
||||
env.cli('destroy', '-f')
|
||||
end
|
||||
end
|
||||
|
||||
def vagrant_ssh(cmd)
|
||||
output = nil
|
||||
with_vagrant_environment do |env|
|
||||
result = env.cli('ssh', '-c', cmd)
|
||||
if result.to_i != 0
|
||||
raise "SSH command failed: '#{cmd}'\n#{env.ui.messages.inspect}"
|
||||
end
|
||||
output = env.ui.messages[:info].join("\n").chomp
|
||||
end
|
||||
output
|
||||
end
|
||||
|
||||
def vagrant_package
|
||||
with_vagrant_environment do |env|
|
||||
pkg = '/vagrant/spec/tmp/package.box'
|
||||
`rm -f #{pkg}`
|
||||
env.cli('package', '--output', pkg)
|
||||
end
|
||||
end
|
||||
|
||||
def vagrant_box_remove(name)
|
||||
with_vagrant_environment do |env|
|
||||
env.cli('box', 'list')
|
||||
output = env.ui.messages[:info].join("\n").chomp
|
||||
|
||||
if output.include?(name)
|
||||
env.cli('box', 'remove', name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
# Monkey patch vagrant in order to reuse the UI test object that is set on
|
||||
# our Vagrant::Environments
|
||||
#
|
||||
require 'vagrant/machine'
|
||||
Vagrant::Machine.class_eval do
|
||||
alias :old_action :action
|
||||
|
||||
define_method :action do |action_name, extra_env = nil|
|
||||
extra_env = { ui: @env.ui }.merge(extra_env || {})
|
||||
old_action action_name, extra_env
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
class TestUI < Vagrant::UI::Interface
|
||||
attr_reader :messages
|
||||
|
||||
METHODS = [:clear_line, :report_progress, :warn, :error, :info, :success]
|
||||
|
||||
def initialize
|
||||
super
|
||||
@messages = METHODS.each_with_object({}) { |m, h| h[m] = [] }
|
||||
end
|
||||
|
||||
def ask(*args)
|
||||
super
|
||||
# Automated tests should not depend on user input, obviously.
|
||||
raise Errors::UIExpectsTTY
|
||||
end
|
||||
|
||||
METHODS.each do |method|
|
||||
define_method(method) do |*args|#message, *opts|
|
||||
@messages[method].push args[0]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
unless ENV['USER'] == 'vagrant'
|
||||
puts 'Acceptance specs are supposed to run from one of the vagrant-lxc dev machines'
|
||||
exit 1
|
||||
end
|
||||
|
||||
if defined? SimpleCov
|
||||
SimpleCov.command_name 'acceptance'
|
||||
end
|
||||
|
||||
require 'vagrant'
|
||||
require 'vagrant-lxc'
|
||||
|
||||
Dir[File.dirname(__FILE__) + "/acceptance/support/**/*.rb"].each { |f| require f }
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.include AcceptanceExampleGroup, :type => :acceptance, :example_group => {
|
||||
:file_path => /\bspec\/acceptance\//
|
||||
}
|
||||
end
|
|
@ -10,22 +10,10 @@ require 'bundler/setup'
|
|||
|
||||
require 'i18n'
|
||||
|
||||
require 'rspec-spies'
|
||||
require 'vagrant-lxc/plugin'
|
||||
|
||||
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each { |f| require f }
|
||||
|
||||
# If we should verify constant names, eager loads
|
||||
if ENV['VERIFY_CONSTANT_NAMES']
|
||||
require 'vagrant-lxc/plugin'
|
||||
require 'vagrant-lxc/provider'
|
||||
require 'vagrant-lxc/config'
|
||||
end
|
||||
|
||||
require 'rspec/fire'
|
||||
RSpec::Fire.configure do |config|
|
||||
config.verify_constant_names = ENV['VERIFY_CONSTANT_NAMES'] == '1'
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.treat_symbols_as_metadata_keys_with_true_values = true
|
||||
config.run_all_when_everything_filtered = true
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
require 'unit_helper'
|
||||
|
||||
require 'vagrant-lxc/plugin'
|
||||
require 'vagrant-lxc/provider'
|
||||
require 'vagrant-lxc/action/compress_rootfs'
|
||||
|
||||
describe Vagrant::LXC::Action::CompressRootFS do
|
||||
let(:app) { double(:app, call: true) }
|
||||
let(:env) { {machine: machine, ui: double(info: true)} }
|
||||
let(:machine) { instance_double('Vagrant::Machine', provider: provider) }
|
||||
let(:provider) { instance_double('Vagrant::LXC::Provider', driver: driver) }
|
||||
let(:driver) { instance_double('Vagrant::LXC::Driver', compress_rootfs: compressed_rootfs_path) }
|
||||
let(:machine) { double(Vagrant::Machine, provider: provider) }
|
||||
let(:provider) { double(Vagrant::LXC::Provider, driver: driver) }
|
||||
let(:driver) { double(Vagrant::LXC::Driver, compress_rootfs: compressed_rootfs_path) }
|
||||
let(:compressed_rootfs_path) { '/path/to/rootfs.tar.gz' }
|
||||
|
||||
subject { described_class.new(app, env) }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'unit_helper'
|
||||
|
||||
require 'tmpdir'
|
||||
require 'vagrant-lxc/errors'
|
||||
require 'vagrant-lxc/provider'
|
||||
require 'vagrant-lxc/action/forward_ports'
|
||||
|
||||
describe Vagrant::LXC::Action::ForwardPorts do
|
||||
|
@ -9,7 +9,7 @@ describe Vagrant::LXC::Action::ForwardPorts do
|
|||
let(:env) { {machine: machine, ui: double(info: true)} }
|
||||
let(:machine) { double(:machine) }
|
||||
let!(:data_dir) { Pathname.new(Dir.mktmpdir) }
|
||||
let(:provider) { instance_double('Vagrant::LXC::Provider', ssh_info: {host: container_ip}) }
|
||||
let(:provider) { double(Vagrant::LXC::Provider, ssh_info: {host: container_ip}) }
|
||||
let(:host_ip) { '127.0.0.1' }
|
||||
let(:host_port) { 8080 }
|
||||
let(:guest_port) { 80 }
|
||||
|
|
|
@ -102,15 +102,11 @@ describe Vagrant::LXC::Action::HandleBoxMetadata do
|
|||
it 'validates box versions' do
|
||||
%w( 2 3 1.0.0 ).each do |v|
|
||||
metadata['version'] = v
|
||||
expect {
|
||||
subject.call(env)
|
||||
}.to_not raise_error(Vagrant::LXC::Errors::IncompatibleBox)
|
||||
expect { subject.call(env) }.to_not raise_error
|
||||
end
|
||||
|
||||
metadata['version'] = '1'
|
||||
expect {
|
||||
subject.call(env)
|
||||
}.to raise_error(Vagrant::LXC::Errors::IncompatibleBox)
|
||||
expect { subject.call(env) }.to raise_error
|
||||
end
|
||||
|
||||
it 'raises an error if the rootfs tarball cant be found' do
|
||||
|
|
|
@ -5,16 +5,16 @@ require 'vagrant-lxc/action/setup_package_files'
|
|||
describe Vagrant::LXC::Action::SetupPackageFiles do
|
||||
let(:app) { double(:app, call: true) }
|
||||
let(:env) { {machine: machine, tmp_path: tmp_path, ui: double(info: true), 'package.rootfs' => rootfs_path} }
|
||||
let(:machine) { instance_double('Vagrant::Machine', box: box) }
|
||||
let(:machine) { double(Vagrant::Machine, box: box) }
|
||||
let!(:tmp_path) { Pathname.new(Dir.mktmpdir) }
|
||||
let(:box) { instance_double('Vagrant::Box', directory: tmp_path.join('box')) }
|
||||
let(:box) { double(Vagrant::Box, directory: tmp_path.join('box')) }
|
||||
let(:rootfs_path) { tmp_path.join('rootfs-amd64.tar.gz') }
|
||||
|
||||
subject { described_class.new(app, env) }
|
||||
|
||||
before do
|
||||
box.directory.mkdir
|
||||
files = %w( lxc-template metadata.json lxc.conf ).map { |f| box.directory.join(f) }
|
||||
files = %w( lxc-template metadata.json lxc.conf lxc-config ).map { |f| box.directory.join(f) }
|
||||
(files + [rootfs_path]).each do |file|
|
||||
file.open('w') { |f| f.puts file.to_s }
|
||||
end
|
||||
|
@ -41,6 +41,10 @@ describe Vagrant::LXC::Action::SetupPackageFiles do
|
|||
env['package.directory'].join('lxc-template').should be_file
|
||||
end
|
||||
|
||||
it 'copies box lxc-config to package directory' do
|
||||
env['package.directory'].join('lxc-config').should be_file
|
||||
end
|
||||
|
||||
it 'moves the compressed rootfs to package directory' do
|
||||
env['package.directory'].join(rootfs_path.basename).should be_file
|
||||
env['package.rootfs'].should_not be_file
|
||||
|
@ -56,4 +60,14 @@ describe Vagrant::LXC::Action::SetupPackageFiles do
|
|||
expect { subject.call(env) }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when lxc-config file is not present' do
|
||||
before do
|
||||
box.directory.join('lxc-config').delete
|
||||
end
|
||||
|
||||
it 'does not blow up' do
|
||||
expect { subject.call(env) }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
require 'unit_helper'
|
||||
|
||||
require 'vagrant-lxc/sudo_wrapper'
|
||||
require 'vagrant-lxc/driver/cli'
|
||||
|
||||
describe Vagrant::LXC::Driver::CLI do
|
||||
let(:sudo_wrapper) { instance_double('Vagrant::LXC::SudoWrapper', run: true) }
|
||||
let(:sudo_wrapper) { double(Vagrant::LXC::SudoWrapper, run: true) }
|
||||
|
||||
subject { described_class.new(sudo_wrapper) }
|
||||
|
||||
|
@ -197,6 +198,6 @@ describe Vagrant::LXC::Driver::CLI do
|
|||
}.to raise_error(described_class::TransitionBlockNotProvided)
|
||||
end
|
||||
|
||||
pending 'waits for the expected container state'
|
||||
skip 'waits for the expected container state'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
require 'unit_helper'
|
||||
|
||||
require 'vagrant'
|
||||
require 'vagrant-lxc/driver'
|
||||
require 'vagrant-lxc/driver/cli'
|
||||
require 'vagrant-lxc/sudo_wrapper'
|
||||
|
||||
describe Vagrant::LXC::Driver do
|
||||
describe 'container name validation' do
|
||||
let(:unknown_container) { described_class.new('unknown', nil, cli) }
|
||||
let(:valid_container) { described_class.new('valid', nil, cli) }
|
||||
let(:new_container) { described_class.new(nil, nil) }
|
||||
let(:cli) { instance_double('Vagrant::LXC::Driver::CLI', list: ['valid']) }
|
||||
let(:cli) { double(Vagrant::LXC::Driver::CLI, list: ['valid']) }
|
||||
|
||||
it 'raises a ContainerNotFound error if an unknown container name gets provided' do
|
||||
expect {
|
||||
|
@ -37,7 +37,7 @@ describe Vagrant::LXC::Driver do
|
|||
let(:template_opts) { {'--some' => 'random-option'} }
|
||||
let(:config_file) { '/path/to/lxc-config-from-box' }
|
||||
let(:rootfs_tarball) { '/path/to/cache/rootfs.tar.gz' }
|
||||
let(:cli) { instance_double('Vagrant::LXC::Driver::CLI', :create => true, :name= => true) }
|
||||
let(:cli) { double(Vagrant::LXC::Driver::CLI, :create => true, :name= => true) }
|
||||
|
||||
subject { described_class.new(nil, nil, cli) }
|
||||
|
||||
|
@ -60,7 +60,7 @@ describe Vagrant::LXC::Driver do
|
|||
end
|
||||
|
||||
describe 'destruction' do
|
||||
let(:cli) { instance_double('Vagrant::LXC::Driver::CLI', destroy: true) }
|
||||
let(:cli) { double(Vagrant::LXC::Driver::CLI, destroy: true) }
|
||||
|
||||
subject { described_class.new('name', nil, cli) }
|
||||
|
||||
|
@ -74,8 +74,8 @@ describe Vagrant::LXC::Driver do
|
|||
describe 'start' do
|
||||
let(:customizations) { [['a', '1'], ['b', '2']] }
|
||||
let(:internal_customization) { ['internal', 'customization'] }
|
||||
let(:cli) { instance_double('Vagrant::LXC::Driver::CLI', start: true) }
|
||||
let(:sudo) { instance_double('Vagrant::LXC::SudoWrapper', su_c: true) }
|
||||
let(:cli) { double(Vagrant::LXC::Driver::CLI, start: true) }
|
||||
let(:sudo) { double(Vagrant::LXC::SudoWrapper, su_c: true) }
|
||||
|
||||
subject { described_class.new('name', sudo, cli) }
|
||||
|
||||
|
@ -94,7 +94,7 @@ describe Vagrant::LXC::Driver do
|
|||
end
|
||||
|
||||
describe 'halt' do
|
||||
let(:cli) { instance_double('Vagrant::LXC::Driver::CLI', shutdown: true) }
|
||||
let(:cli) { double(Vagrant::LXC::Driver::CLI, shutdown: true) }
|
||||
|
||||
subject { described_class.new('name', nil, cli) }
|
||||
|
||||
|
@ -129,7 +129,7 @@ describe Vagrant::LXC::Driver do
|
|||
|
||||
describe 'state' do
|
||||
let(:cli_state) { :something }
|
||||
let(:cli) { instance_double('Vagrant::LXC::Driver::CLI', state: cli_state) }
|
||||
let(:cli) { double(Vagrant::LXC::Driver::CLI, state: cli_state) }
|
||||
|
||||
subject { described_class.new('name', nil, cli) }
|
||||
|
||||
|
@ -143,7 +143,7 @@ describe Vagrant::LXC::Driver do
|
|||
let(:folders) { [shared_folder] }
|
||||
let(:rootfs_path) { Pathname('/path/to/rootfs') }
|
||||
let(:expected_guest_path) { "#{rootfs_path}/vagrant" }
|
||||
let(:sudo_wrapper) { instance_double('Vagrant::LXC::SudoWrapper', run: true) }
|
||||
let(:sudo_wrapper) { double(Vagrant::LXC::SudoWrapper, run: true) }
|
||||
|
||||
subject { described_class.new('name', sudo_wrapper) }
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@ if defined? SimpleCov
|
|||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.include RSpec::Fire
|
||||
|
||||
config.include UnitExampleGroup, :type => :unit, :example_group => {
|
||||
:file_path => /\bspec\/unit\//
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ begin
|
|||
require 'coveralls/rake/task'
|
||||
|
||||
desc 'Run all specs'
|
||||
task :spec => ['spec:unit', 'spec:acceptance']
|
||||
task :spec => ['spec:set_coverage', 'spec:unit', 'spec:acceptance']
|
||||
|
||||
desc 'Default task which runs all specs with code coverage enabled'
|
||||
task :default => ['spec:set_coverage', 'spec:unit']
|
||||
|
@ -17,17 +17,24 @@ namespace :spec do
|
|||
ENV['COVERAGE'] = 'true'
|
||||
end
|
||||
|
||||
def types
|
||||
dirs = Dir['./spec/**/*_spec.rb'].map { |f| f.sub(/^\.\/(spec\/\w+)\/.*/, '\\1') }.uniq
|
||||
Hash[dirs.map { |d| [d.split('/').last, d] }]
|
||||
desc 'Run acceptance specs using vagrant-spec'
|
||||
task :acceptance do
|
||||
components = %w(
|
||||
basic
|
||||
network/forwarded_port
|
||||
synced_folder
|
||||
synced_folder/nfs
|
||||
synced_folder/rsync
|
||||
provisioner/shell
|
||||
provisioner/puppet
|
||||
provisioner/chef-solo
|
||||
package
|
||||
).map{|s| "provider/lxc/#{s}" }
|
||||
sh "export ACCEPTANCE=true && bundle exec vagrant-spec test --components=#{components.join(' ')}"
|
||||
end
|
||||
types.each do |type, dir|
|
||||
desc "Run the code examples in #{dir}"
|
||||
RSpec::Core::RakeTask.new(type) do |t|
|
||||
# Tells rspec-fire to verify if constants used really exist
|
||||
ENV['VERIFY_CONSTANT_NAMES'] = '1'
|
||||
|
||||
t.pattern = "./#{dir}/**/*_spec.rb"
|
||||
end
|
||||
desc "Run unit specs with rspec"
|
||||
RSpec::Core::RakeTask.new(:unit) do |t|
|
||||
t.pattern = "./unit/**/*_spec.rb"
|
||||
end
|
||||
end
|
||||
|
|
33
vagrant-spec.config.rb
Normal file
33
vagrant-spec.config.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
unless ENV['USER'] == 'vagrant'
|
||||
puts 'Acceptance specs are supposed to run from one of the vagrant-lxc dev machines'
|
||||
exit 1
|
||||
end
|
||||
|
||||
# FIXME: Figure out why this doesn't work
|
||||
if ENV['COVERAGE'] == 'true'
|
||||
require 'simplecov'
|
||||
require 'coveralls'
|
||||
|
||||
SimpleCov.start { add_filter '/spec/' }
|
||||
SimpleCov.command_name 'acceptance'
|
||||
end
|
||||
|
||||
# if defined? SimpleCov
|
||||
# SimpleCov.command_name 'acceptance'
|
||||
# end
|
||||
|
||||
if ENV['BOX_PATH'] == nil
|
||||
latest = ENV.fetch('LATEST_BOXES','2014-03-11')
|
||||
release = ENV.fetch('RELEASE', 'precise')
|
||||
local_path ="#{File.expand_path("../", __FILE__)}/boxes/output/#{latest}/vagrant-lxc-#{release}-amd64.box"
|
||||
if File.exists?(local_path)
|
||||
ENV['BOX_PATH'] = local_path
|
||||
else
|
||||
raise 'Set $BOX_PATH to the latest released boxes'
|
||||
end
|
||||
end
|
||||
|
||||
Vagrant::Spec::Acceptance.configure do |c|
|
||||
c.component_paths << "spec/acceptance"
|
||||
c.provider 'lxc', box: ENV['BOX_PATH'], features: ['!suspend']
|
||||
end
|
Loading…
Reference in a new issue