Not so initial commit
This commit is contained in:
commit
55c9be772d
18 changed files with 777 additions and 0 deletions
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
*.gem
|
||||
*.rbc
|
||||
.bundle
|
||||
.config
|
||||
coverage
|
||||
InstalledFiles
|
||||
lib/bundler/man
|
||||
pkg
|
||||
rdoc
|
||||
spec/reports
|
||||
test/tmp
|
||||
test/version_tmp
|
||||
tmp
|
||||
|
||||
# YARD artifacts
|
||||
.yardoc
|
||||
_yardoc
|
||||
doc/
|
||||
|
||||
.vagrant
|
||||
/cache
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "vagrant-1.1"]
|
||||
path = vagrant-1.1
|
||||
url = git://github.com/mitchellh/vagrant.git
|
2
.rspec
Normal file
2
.rspec
Normal file
|
@ -0,0 +1,2 @@
|
|||
--color
|
||||
--format documentation
|
1
.vimrc
Normal file
1
.vimrc
Normal file
|
@ -0,0 +1 @@
|
|||
set wildignore+=*/vagrant-1.1/*
|
14
Gemfile
Normal file
14
Gemfile
Normal file
|
@ -0,0 +1,14 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
unless ENV['USER'] == 'vagrant'
|
||||
puts 'This Gemfile is meant to be used from the dev box'
|
||||
exit 1
|
||||
end
|
||||
|
||||
gem 'rake'
|
||||
gem 'net-ssh'
|
||||
gem 'rspec'
|
||||
gem 'guard'
|
||||
gem 'guard-rspec'
|
||||
gem 'rb-inotify'
|
||||
gem 'log4r'
|
50
Gemfile.lock
Normal file
50
Gemfile.lock
Normal file
|
@ -0,0 +1,50 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
coderay (1.0.8)
|
||||
diff-lcs (1.1.3)
|
||||
ffi (1.4.0)
|
||||
guard (1.6.2)
|
||||
listen (>= 0.6.0)
|
||||
lumberjack (>= 1.0.2)
|
||||
pry (>= 0.9.10)
|
||||
terminal-table (>= 1.4.3)
|
||||
thor (>= 0.14.6)
|
||||
guard-rspec (2.4.0)
|
||||
guard (>= 1.1)
|
||||
rspec (~> 2.11)
|
||||
listen (0.7.2)
|
||||
log4r (1.1.10)
|
||||
lumberjack (1.0.2)
|
||||
method_source (0.8.1)
|
||||
net-ssh (2.6.5)
|
||||
pry (0.9.12)
|
||||
coderay (~> 1.0.5)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
rake (10.0.3)
|
||||
rb-inotify (0.8.8)
|
||||
ffi (>= 0.5.0)
|
||||
rspec (2.12.0)
|
||||
rspec-core (~> 2.12.0)
|
||||
rspec-expectations (~> 2.12.0)
|
||||
rspec-mocks (~> 2.12.0)
|
||||
rspec-core (2.12.2)
|
||||
rspec-expectations (2.12.1)
|
||||
diff-lcs (~> 1.1.3)
|
||||
rspec-mocks (2.12.2)
|
||||
slop (3.4.3)
|
||||
terminal-table (1.4.5)
|
||||
thor (0.17.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
guard
|
||||
guard-rspec
|
||||
log4r
|
||||
net-ssh
|
||||
rake
|
||||
rb-inotify
|
||||
rspec
|
10
Guardfile
Normal file
10
Guardfile
Normal file
|
@ -0,0 +1,10 @@
|
|||
# A sample Guardfile
|
||||
# More info at https://github.com/guard/guard#readme
|
||||
|
||||
raise 'You should start guard from the dev box!' unless ENV['USER'] == 'vagrant'
|
||||
|
||||
guard 'rspec' do
|
||||
watch(%r{^spec/.+_spec\.rb$})
|
||||
watch('spec/spec_helper.rb') { 'spec' }
|
||||
watch('lib/provider') { 'spec' }
|
||||
end
|
37
README.md
Normal file
37
README.md
Normal file
|
@ -0,0 +1,37 @@
|
|||
# vagrant-lxc
|
||||
|
||||
Highly experimental Linux Containers support for Vagrant 1.1
|
||||
|
||||
## WARNING
|
||||
|
||||
Please keep in mind that this is not even alpha software and things might go wrong.
|
||||
Although I'm brave enough to use it on my physical machine, its recommended that you
|
||||
try it out on the Vagrant dev box ;)
|
||||
|
||||
## Development
|
||||
|
||||
On your host:
|
||||
|
||||
```terminal
|
||||
./setup-vagrant-dev-box
|
||||
vagrant ssh
|
||||
```
|
||||
|
||||
On the guest machine:
|
||||
|
||||
```terminal
|
||||
mkdir /tmp/vagrant-lxc
|
||||
cp /vagrant/config.yml.sample /tmp/vagrant-lxc/config.yml
|
||||
cd /tmp/vagrant-lxc
|
||||
/vagrant/lib/provider up
|
||||
/vagrant/lib/provider ssh
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If your container / dev box start acting weird, run `vagrant reload` to see if
|
||||
things get back to normal.
|
||||
|
||||
In case `vagrant reload` doesn't work, restore the VirtualBox snapshot that was
|
||||
created automagically right after `./setup-vagrant-dev-box` finished by running
|
||||
the same script again and selecting the `[r]estore snapshot` option when asked.
|
5
Rakefile
Normal file
5
Rakefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
raise 'This Rakefile is meant to be used from the dev box' unless ENV['USER'] == 'vagrant'
|
||||
|
||||
Dir['./tasks/**/*.rake'].each { |f| load f }
|
||||
|
||||
task :default => :spec
|
19
Vagrantfile
vendored
Normal file
19
Vagrantfile
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant::Config.run do |config|
|
||||
config.vm.box = "quantal64"
|
||||
config.vm.box_url = "https://github.com/downloads/roderik/VagrantQuantal64Box/quantal64.box"
|
||||
|
||||
config.vm.network :hostonly, "192.168.33.10"
|
||||
config.vm.forward_port 80, 8080
|
||||
config.vm.forward_port 2222, 2223
|
||||
|
||||
config.vm.customize [
|
||||
"modifyvm", :id,
|
||||
"--memory", 1024,
|
||||
"--cpus", "2"
|
||||
]
|
||||
|
||||
config.vm.share_folder("v-root", "/vagrant", ".", :nfs => true)
|
||||
end
|
5
config.yml.sample
Normal file
5
config.yml.sample
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
ip: 10.0.3.100
|
||||
forwards:
|
||||
- - 2222
|
||||
- 22
|
277
lib/provider
Executable file
277
lib/provider
Executable file
|
@ -0,0 +1,277 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems'
|
||||
require 'log4r'
|
||||
require 'yaml'
|
||||
require 'shellwords'
|
||||
require 'optparse'
|
||||
require 'net/ssh'
|
||||
|
||||
# Based on actions available to the VirtualBox provider:
|
||||
# https://github.com/mitchellh/vagrant/tree/master/plugins/providers/virtualbox
|
||||
class Provider
|
||||
WAIT = 5
|
||||
|
||||
def initialize(config)
|
||||
@config = config
|
||||
@logger = Log4r::Logger.new("vagrant::provider::lxc")
|
||||
@logger.outputters = Log4r::Outputter.stdout
|
||||
if config['output']
|
||||
@logger.outputters << Log4r::FileOutputter.new('output', 'filename' => config['output'])
|
||||
end
|
||||
# @logger.level = Log4r::INFO
|
||||
end
|
||||
|
||||
# @see Vagrant::Plugin::V1::Provider#action
|
||||
def action(name, *args)
|
||||
# Attempt to get the action method from this class if it
|
||||
# exists, otherwise return nil to show that we don't support the
|
||||
# given action.
|
||||
action_method = "action_#{name}"
|
||||
return send(action_method, *args) if respond_to?(action_method)
|
||||
nil
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def run(cmd)
|
||||
@logger.debug "Running: #{cmd}"
|
||||
system cmd
|
||||
end
|
||||
|
||||
def action_up
|
||||
was_created = container_created?
|
||||
if was_created
|
||||
@logger.info("Container already created, moving on...")
|
||||
else
|
||||
@logger.info("Creating container...")
|
||||
# TRY: run 'sudo lxc-create -t ubuntu -n vagrant-container -b vagrant'
|
||||
# DISCUSS: Copy key directly to /var/lib/lxc/$host/root/.ssh/authorized_keys to be generic?
|
||||
unless run 'sudo lxc-create -t ubuntu-cloud -n vagrant-container -- -S /home/vagrant/.ssh/id_rsa.pub'
|
||||
puts 'Error creating box'
|
||||
exit 1
|
||||
end
|
||||
unless container_created?
|
||||
puts 'Error creating container'
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
if container_started?
|
||||
@logger.info('Container already started')
|
||||
else
|
||||
share_folders
|
||||
|
||||
@logger.info('Starting container...')
|
||||
unless run "sudo lxc-start -n vagrant-container -d #{configs}"# -o /tmp/lxc-start.log -l DEBUG"
|
||||
puts 'Error starting container!'
|
||||
exit 1
|
||||
end
|
||||
run 'sudo lxc-wait --name vagrant-container --state RUNNING'
|
||||
unless container_started?
|
||||
puts 'Error starting container!'
|
||||
exit 1
|
||||
end
|
||||
@logger.info('Container started')
|
||||
|
||||
forward_ports
|
||||
|
||||
unless was_created
|
||||
@logger.debug "Waiting #{WAIT} seconds before setting up vagrant user"
|
||||
sleep WAIT
|
||||
setup_vagrant_user
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def action_halt
|
||||
if container_started?
|
||||
@logger.info('Stopping container...')
|
||||
unless run 'sudo lxc-shutdown -n vagrant-container'
|
||||
puts 'Error halting container!'
|
||||
exit 1
|
||||
end
|
||||
run 'sudo lxc-wait --name vagrant-container --state STOPPED'
|
||||
if container_started?
|
||||
puts 'Error halting container!'
|
||||
exit 1
|
||||
end
|
||||
@logger.info('Container halted')
|
||||
else
|
||||
@logger.info('Container already halted')
|
||||
end
|
||||
end
|
||||
|
||||
def action_destroy
|
||||
if container_created?
|
||||
if container_started?
|
||||
action_halt
|
||||
@logger.debug "Waiting #{WAIT} seconds to proceed with destroy..."
|
||||
sleep WAIT
|
||||
end
|
||||
@logger.info("Destroying container...")
|
||||
unless run 'sudo lxc-destroy -n vagrant-container'
|
||||
puts 'Error destroying container'
|
||||
exit 1
|
||||
end
|
||||
if container_created?
|
||||
puts 'Error destroying container'
|
||||
exit 1
|
||||
end
|
||||
@logger.debug "Waiting #{WAIT} seconds for things to settle down..."
|
||||
sleep WAIT
|
||||
@logger.info("Container destroyed")
|
||||
else
|
||||
@logger.info("Container not created")
|
||||
end
|
||||
end
|
||||
|
||||
def action_reload
|
||||
action_halt if container_started?
|
||||
action_up
|
||||
end
|
||||
|
||||
# TODO: Switch over to Net:SSH
|
||||
def action_ssh(opts = {'user' => 'vagrant'})
|
||||
# FIXME: We should not depend on an IP to be configured
|
||||
raise 'SSH support is currently available to a predefined IP only' unless @config['ip']
|
||||
|
||||
cmd = "ssh #{opts['user']}@#{@config['ip']} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=quiet"
|
||||
cmd << " -- #{Shellwords.escape opts['command']}" if opts['command']
|
||||
|
||||
unless run(cmd)
|
||||
puts 'Error running ssh command!'
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
def setup_vagrant_user
|
||||
unless @config['ip']
|
||||
# FIXME: Need to find a way to grab the container IP
|
||||
@logger.warn('Unfortunately automatic vagrant user setup does not work unless an IP is specified')
|
||||
return
|
||||
end
|
||||
|
||||
@logger.info 'Setting up vagrant user'
|
||||
|
||||
# TODO: We could try to use lxc-attach instead of SSH
|
||||
|
||||
# Based on:
|
||||
# https://github.com/jedi4ever/veewee/blob/master/templates/ubuntu-12.10-server-amd64-packages/vagrant.sh
|
||||
cmds = [
|
||||
#'groupadd -r admin',
|
||||
'useradd -d /home/vagrant -m vagrant -r -s /bin/bash',
|
||||
'usermod -a -G admin vagrant',
|
||||
'cp /etc/sudoers /etc/sudoers.orig',
|
||||
'sed -i -e \'/Defaults\s\+env_reset/a Defaults\texempt_group=admin\' /etc/sudoers',
|
||||
'sed -i -e \'s/%admin\s\+ALL=(ALL)\s\+ALL/%admin ALL=NOPASSWD:ALL/g\' /etc/sudoers',
|
||||
'service sudo restart',
|
||||
'-u vagrant -- mkdir -p /home/vagrant/.ssh',
|
||||
'-u vagrant -- curl -o /home/vagrant/.ssh/authorized_keys https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub'
|
||||
]
|
||||
|
||||
# FIXME: Needs to abort the process if any of this commands fail
|
||||
ssh_conn('ubuntu') do |ssh|
|
||||
cmds.each do |cmd|
|
||||
@logger.debug "SSH: sudo #{cmd}"
|
||||
ssh.exec!("sudo #{cmd}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def ssh_conn(user = 'vagrant')
|
||||
Net::SSH.start(@config['ip'], user, :user_known_hosts_file => '/dev/null') do |ssh|
|
||||
yield ssh
|
||||
end
|
||||
end
|
||||
|
||||
def container_created?
|
||||
`lxc-ls` =~ /^vagrant\-container/
|
||||
end
|
||||
|
||||
def container_started?
|
||||
`sudo -- lxc-info -n vagrant-container` =~ /RUNNING/
|
||||
end
|
||||
|
||||
def share_folders
|
||||
@logger.info('Setting up shared folders...')
|
||||
|
||||
mount_folder(File.expand_path('.'), '/vagrant')
|
||||
|
||||
Array(@config['shared_folders']).each do |folder|
|
||||
mount_folder(folder['source'], folder['destination'])
|
||||
end
|
||||
end
|
||||
|
||||
def mount_folder(source, destination)
|
||||
@logger.info("Sharing #{source} as #{destination}")
|
||||
run <<STR
|
||||
sudo mount --bind #{source} #{source}
|
||||
sudo mount --make-unbindable #{source}
|
||||
sudo mount --make-shared #{source}
|
||||
|
||||
if ! [ -d /var/lib/lxc/vagrant-container/rootfs#{destination} ]; then
|
||||
sudo mkdir -p /var/lib/lxc/vagrant-container/rootfs#{destination}
|
||||
fi
|
||||
|
||||
if ! $(sudo grep -q '#{source} /var/lib/lxc/vagrant-container/rootfs#{destination}' /var/lib/lxc/vagrant-container/fstab); then
|
||||
cat <<EOF | sudo tee -a /var/lib/lxc/vagrant-container/fstab
|
||||
#{source} /var/lib/lxc/vagrant-container/rootfs#{destination} none bind 0 0
|
||||
EOF
|
||||
fi
|
||||
STR
|
||||
end
|
||||
|
||||
def configs
|
||||
configs = []
|
||||
configs << "-s lxc.network.ipv4='#{@config['ip']}'" if @config['ip']
|
||||
configs << '-s lxc.cgroup.memory.limit_in_bytes=400M'
|
||||
configs << '-s lxc.cgroup.memory.memsw.limit_in_bytes=500M'
|
||||
configs.join(' ')
|
||||
end
|
||||
|
||||
def forward_ports
|
||||
return unless @config.key?('forwards')
|
||||
|
||||
@logger.info('Forwarding ports...')
|
||||
forwards = ''
|
||||
@config['forwards'].each do |forward|
|
||||
host_port, guest_port = forward
|
||||
@logger.info("-- #{guest_port} => #{host_port}")
|
||||
forwards << "0.0.0.0 #{host_port} #{@config['ip']} #{guest_port}"
|
||||
end
|
||||
|
||||
# FIXME: We should be nice to others and not overwrite the config all the time ;)
|
||||
File.open('/etc/rinetd.conf', 'w') do |f|
|
||||
f.puts forwards
|
||||
f.puts 'logfile /var/log/rinetd.log'
|
||||
end
|
||||
@logger.info('Restarting rinetd')
|
||||
`sudo service rinetd restart`
|
||||
end
|
||||
end
|
||||
|
||||
raise 'You need to provide an action' unless ARGV[0]
|
||||
|
||||
action = ARGV.shift.to_sym
|
||||
if action == :ssh
|
||||
options = {'user' => 'vagrant'}
|
||||
OptionParser.new do |opts|
|
||||
opts.on("-c", '--command [COMMAND]') { |v| options['command'] = v }
|
||||
opts.on('-u', '--user [USER]') { |v| options['user'] = v }
|
||||
end.parse!
|
||||
arguments = [options]
|
||||
else
|
||||
init_options = {}
|
||||
OptionParser.new do |opts|
|
||||
opts.on("-o", '--output [FILE]') { |v| init_options['output'] = v }
|
||||
end.parse!
|
||||
end
|
||||
|
||||
config = YAML.load File.open('./config.yml') if File.exists? './config.yml'
|
||||
config ||= {}
|
||||
config['output'] = init_options.delete('output') if init_options && init_options.key?('output')
|
||||
|
||||
@provider = Provider.new(config || {})
|
||||
|
||||
@provider.action(action, *(arguments || []))
|
101
setup-vagrant-dev-box
Executable file
101
setup-vagrant-dev-box
Executable file
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
raise 'You should not run this script from the dev box' if ENV['USER'] == 'vagrant'
|
||||
|
||||
require 'bundler'
|
||||
require 'json'
|
||||
|
||||
IMAGE_ROOT = 'https://cloud-images.ubuntu.com/releases/quantal/release-20130206'
|
||||
IMAGE_NAME = 'ubuntu-12.10-server-cloudimg-amd64-root.tar.gz'
|
||||
VAGRANT_REPO = 'https://raw.github.com/mitchellh/vagrant/master'
|
||||
|
||||
def download(source, destination)
|
||||
destination = "#{File.dirname __FILE__}/cache/#{destination}"
|
||||
return if File.exists?(destination)
|
||||
|
||||
sh "wget #{source} -O #{destination}"
|
||||
end
|
||||
|
||||
def sh(cmd)
|
||||
Bundler.with_clean_env do
|
||||
puts cmd
|
||||
raise 'Errored!' unless system cmd
|
||||
end
|
||||
end
|
||||
|
||||
def restore_snapshot!
|
||||
sh 'vagrant halt -f'
|
||||
conf = JSON.parse File.read('.vagrant')
|
||||
id = conf['active']['default']
|
||||
sh "VBoxManage snapshot '#{id}' restore ready-to-rock"
|
||||
sh 'vagrant up'
|
||||
exit 0
|
||||
end
|
||||
|
||||
# Initialize git submodules
|
||||
sh 'git submodule update --init'
|
||||
|
||||
Bundler.with_clean_env do
|
||||
# Ensure box has not been created yet
|
||||
unless `vagrant status` =~ /not created/
|
||||
print 'Vagrant box already created, do you want to [r]ecreate it, restore [s]napshot or [A]bort? '
|
||||
answer = gets.chomp
|
||||
exit 0 if answer.empty? || answer =~ /^a/i
|
||||
|
||||
case
|
||||
when answer =~ /^s/i
|
||||
restore_snapshot!
|
||||
when answer =~ /^r/i
|
||||
sh 'vagrant destroy -f'
|
||||
else
|
||||
puts 'Invalid option!'
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Cache development dependencies
|
||||
`mkdir -p cache`
|
||||
|
||||
# Cache container image between vagrant box destructions
|
||||
download "#{IMAGE_ROOT}/#{IMAGE_NAME}", IMAGE_NAME
|
||||
|
||||
# Start vagrant
|
||||
sh 'vagrant up'
|
||||
|
||||
# Because I'm lazy ;)
|
||||
sh 'vagrant ssh -c "echo \'cd /vagrant\' >> ~/.bashrc"'
|
||||
|
||||
# "be" archive is too slow for me
|
||||
sh 'vagrant ssh -c "sudo sed -i -e \'s/be.archive/br.archive/g\' /etc/apt/sources.list"'
|
||||
|
||||
# Ensure we have the latest packages around
|
||||
sh 'vagrant ssh -c "sudo apt-get update && sudo apt-get upgrade -y"'
|
||||
|
||||
# Ensure the machine can boot properly after upgrades
|
||||
sh 'vagrant reload'
|
||||
|
||||
# Install lxc, libffi, rinetd and bundler
|
||||
sh 'vagrant ssh -c "sudo apt-get install lxc rinetd libffi-dev libffi-ruby ruby1.9.1-dev htop -y && sudo gem install bundler --no-ri --no-rdoc"'
|
||||
|
||||
# Backup rinetd config
|
||||
sh "vagrant ssh -c 'cp /etc/rinetd.conf /vagrant/cache/rinetd.conf'"
|
||||
|
||||
# Make rinetd writable by vagrant user
|
||||
sh "vagrant ssh -c 'sudo chown vagrant:vagrant /etc/rinetd.conf'"
|
||||
|
||||
# Bundle!
|
||||
sh "vagrant ssh -c 'cd /vagrant && bundle'"
|
||||
|
||||
# Setup vagrant default ssh key
|
||||
sh 'vagrant ssh -c "cp /vagrant/vagrant-1.1/keys/vagrant ~/.ssh/id_rsa && cp /vagrant/vagrant-1.1/keys/vagrant.pub ~/.ssh/id_rsa.pub && chmod 600 ~/.ssh/id_rsa"'
|
||||
|
||||
# Setup lxc cache
|
||||
sh "vagrant ssh -c 'sudo mkdir -p /var/cache/lxc/cloud-quantal && sudo cp /vagrant/cache/#{IMAGE_NAME} /var/cache/lxc/cloud-quantal/#{IMAGE_NAME}'"
|
||||
|
||||
# Click
|
||||
sh 'vagrant halt'
|
||||
conf = JSON.parse File.read('.vagrant')
|
||||
id = conf['active']['default']
|
||||
sh "VBoxManage snapshot '#{id}' take ready-to-rock"
|
||||
sh 'vagrant up'
|
59
spec/spec_helper.rb
Normal file
59
spec/spec_helper.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
require 'rubygems'
|
||||
|
||||
require 'bundler/setup'
|
||||
|
||||
Bundler.require
|
||||
|
||||
require 'yaml'
|
||||
require 'shellwords'
|
||||
|
||||
`mkdir -p tmp`
|
||||
|
||||
module TestHelpers
|
||||
def provider_up
|
||||
`cd tmp && ../lib/provider up -o /vagrant/tmp/logger.log`
|
||||
end
|
||||
|
||||
def destroy_container!
|
||||
`cd tmp && ../lib/provider destroy -o /vagrant/tmp/logger.log`
|
||||
`rm -f tmp/config.yml`
|
||||
end
|
||||
|
||||
def restore_rinetd_conf!
|
||||
`sudo cp /vagrant/cache/rinetd.conf /etc/rinetd.conf`
|
||||
`sudo service rinetd restart`
|
||||
end
|
||||
|
||||
def configure_box_with(opts)
|
||||
opts = opts.dup
|
||||
opts.keys.each do |key|
|
||||
opts[key.to_s] = opts.delete(key)
|
||||
end
|
||||
File.open('./tmp/config.yml', 'w') { |f| f.puts YAML::dump(opts) }
|
||||
end
|
||||
|
||||
def provider_ssh(options)
|
||||
options = options.map { |opt, val| "-#{opt} #{Shellwords.escape val}" }
|
||||
options = options.join(' ')
|
||||
`cd tmp && ../lib/provider ssh #{options}`
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.treat_symbols_as_metadata_keys_with_true_values = true
|
||||
config.run_all_when_everything_filtered = true
|
||||
config.filter_run :focus
|
||||
|
||||
config.include TestHelpers
|
||||
|
||||
# Run specs in random order to surface order dependencies. If you find an
|
||||
# order dependency and want to debug it, you can fix the order by providing
|
||||
# the seed, which is printed after each run.
|
||||
# --seed 1234
|
||||
config.order = 'random'
|
||||
|
||||
config.after :all do
|
||||
destroy_container!
|
||||
restore_rinetd_conf!
|
||||
end
|
||||
end
|
20
spec/vagrant_ssh_spec.rb
Normal file
20
spec/vagrant_ssh_spec.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'vagrant ssh' do
|
||||
let(:ip) { '10.0.3.100' }
|
||||
|
||||
before :all do
|
||||
destroy_container!
|
||||
configure_box_with :forwards => [[2222, 22]], :ip => ip
|
||||
provider_up
|
||||
end
|
||||
|
||||
after :all do
|
||||
restore_rinetd_conf!
|
||||
destroy_container!
|
||||
end
|
||||
|
||||
it 'accepts a user argument' do
|
||||
provider_ssh('c' => 'echo $USER', 'u' => 'ubuntu').should include 'ubuntu'
|
||||
end
|
||||
end
|
148
spec/vagrant_up_spec.rb
Normal file
148
spec/vagrant_up_spec.rb
Normal file
|
@ -0,0 +1,148 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'vagrant up' do
|
||||
context 'given the machine has not been created yet' do
|
||||
let(:output) { @output }
|
||||
let(:containers) { @containers }
|
||||
let(:users) { File.read '/var/lib/lxc/vagrant-container/rootfs/etc/passwd' }
|
||||
let(:sudoers) { `sudo cat /var/lib/lxc/vagrant-container/rootfs/etc/sudoers` }
|
||||
let(:rinetd_conf) { File.read('/etc/rinetd.conf') }
|
||||
|
||||
before :all do
|
||||
destroy_container!
|
||||
configure_box_with :ip => '10.0.3.121'
|
||||
@output = provider_up
|
||||
@containers = `sudo lxc-ls`.split
|
||||
end
|
||||
|
||||
it 'outputs some debugging info' do
|
||||
output.should =~ /INFO lxc: Creating container.../
|
||||
output.should =~ /INFO lxc: Container started/
|
||||
end
|
||||
|
||||
it 'creates an lxc container' do
|
||||
containers.should include 'vagrant-container'
|
||||
end
|
||||
|
||||
it 'sets up the vagrant user with passwordless sudo' do
|
||||
users.should =~ /vagrant/
|
||||
sudoers.should =~ /Defaults\s+exempt_group=admin/
|
||||
sudoers.should =~ /%admin ALL=NOPASSWD:ALL/
|
||||
end
|
||||
|
||||
it 'automagically shares the root folder' do
|
||||
output.should =~ /Sharing \/vagrant\/tmp as \/vagrant/
|
||||
end
|
||||
|
||||
it 'automagically redirects 2222 port to 22 on guest machine'
|
||||
end
|
||||
|
||||
context 'given the machine was created and is down' do
|
||||
let(:output) { @output }
|
||||
let(:info) { @info }
|
||||
|
||||
before :all do
|
||||
destroy_container!
|
||||
provider_up
|
||||
`sudo lxc-stop -n vagrant-container`
|
||||
@output = provider_up
|
||||
@info = `sudo lxc-info -n vagrant-container`
|
||||
end
|
||||
|
||||
it 'outputs some debugging info' do
|
||||
output.should =~ /INFO lxc: Container already created, moving on/
|
||||
output.should =~ /INFO lxc: Container started/
|
||||
end
|
||||
|
||||
it 'starts the container' do
|
||||
info.should =~ /RUNNING/
|
||||
end
|
||||
end
|
||||
|
||||
context 'given the machine is up already' do
|
||||
let(:output) { @output }
|
||||
let(:containers) { @containers }
|
||||
|
||||
before :all do
|
||||
destroy_container!
|
||||
provider_up
|
||||
@output = provider_up
|
||||
end
|
||||
|
||||
it 'outputs some debugging info' do
|
||||
output.should =~ /INFO lxc: Container already created, moving on/
|
||||
output.should =~ /INFO lxc: Container already started/
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an ip was specified' do
|
||||
let(:ip) { '10.0.3.100' }
|
||||
let(:output) { @output }
|
||||
|
||||
before :all do
|
||||
destroy_container!
|
||||
configure_box_with :ip => ip
|
||||
@output = provider_up
|
||||
end
|
||||
|
||||
it 'sets up container ip' do
|
||||
`ping -c1 #{ip} > /dev/null && echo -n 'yes'`.should == 'yes'
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a port was configured to be forwarded' do
|
||||
let(:ip) { '10.0.3.101' }
|
||||
let(:output) { @output }
|
||||
let(:rinetd_conf) { File.read('/etc/rinetd.conf') }
|
||||
|
||||
before :all do
|
||||
destroy_container!
|
||||
configure_box_with :forwards => [[3333, 33]], :ip => ip
|
||||
@output = provider_up
|
||||
end
|
||||
|
||||
after :all do
|
||||
restore_rinetd_conf!
|
||||
end
|
||||
|
||||
it 'ouputs some debugging info' do
|
||||
output.should =~ /Forwarding ports\.\.\./
|
||||
output.should =~ /33 => 3333/
|
||||
output.should =~ /Restarting rinetd/
|
||||
end
|
||||
|
||||
it 'sets configs for rinetd' do
|
||||
rinetd_conf.should =~ /0\.0\.0\.0\s+3333\s+#{Regexp.escape ip}\s+33/
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a folder was configured to be shared' do
|
||||
let(:ip) { '10.0.3.100' }
|
||||
let(:output) { @output }
|
||||
|
||||
before :all do
|
||||
destroy_container!
|
||||
configure_box_with({
|
||||
:ip => ip,
|
||||
:shared_folders => [
|
||||
{'source' => '/vagrant', 'destination' => '/tmp/vagrant-all'}
|
||||
]
|
||||
})
|
||||
@output = provider_up
|
||||
`rm -f /vagrant/tmp/file-from-spec`
|
||||
end
|
||||
|
||||
after :all do
|
||||
`rm -f /vagrant/tmp/file-from-spec`
|
||||
end
|
||||
|
||||
it 'ouputs some debugging info' do
|
||||
output.should =~ /Sharing \/vagrant as \/tmp\/vagrant\-all/
|
||||
end
|
||||
|
||||
it 'mounts the folder on the right path' do
|
||||
`echo 'IT WORKS' > /vagrant/tmp/file-from-spec`
|
||||
provider_ssh('c' => 'cat /tmp/vagrant-all/tmp/file-from-spec').should include 'IT WORKS'
|
||||
end
|
||||
end
|
||||
end
|
4
tasks/spec.rake
Normal file
4
tasks/spec.rake
Normal file
|
@ -0,0 +1,4 @@
|
|||
if ENV['USER'] == 'vagrant'
|
||||
require 'rspec/core/rake_task'
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
end
|
1
vagrant-1.1
Submodule
1
vagrant-1.1
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 803269f7291719715011c5c76d66e20101f7af50
|
Loading…
Reference in a new issue