commit 55c9be772db32d4f49bf61af1801d2d6f14a880e
Author: Fabio Rehm <fgrehm@gmail.com>
Date:   Mon Feb 25 01:58:04 2013 -0300

    Not so initial commit

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6d588d6
--- /dev/null
+++ b/.gitignore
@@ -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
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..02032a4
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "vagrant-1.1"]
+	path = vagrant-1.1
+	url = git://github.com/mitchellh/vagrant.git
diff --git a/.rspec b/.rspec
new file mode 100644
index 0000000..16f9cdb
--- /dev/null
+++ b/.rspec
@@ -0,0 +1,2 @@
+--color
+--format documentation
diff --git a/.vimrc b/.vimrc
new file mode 100644
index 0000000..e596bb5
--- /dev/null
+++ b/.vimrc
@@ -0,0 +1 @@
+set wildignore+=*/vagrant-1.1/*
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..655a84e
--- /dev/null
+++ b/Gemfile
@@ -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'
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..08135b1
--- /dev/null
+++ b/Gemfile.lock
@@ -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
diff --git a/Guardfile b/Guardfile
new file mode 100644
index 0000000..a148482
--- /dev/null
+++ b/Guardfile
@@ -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
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d5f698a
--- /dev/null
+++ b/README.md
@@ -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.
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..eea5261
--- /dev/null
+++ b/Rakefile
@@ -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
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000..6bdbdbf
--- /dev/null
+++ b/Vagrantfile
@@ -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
diff --git a/config.yml.sample b/config.yml.sample
new file mode 100644
index 0000000..045a4ef
--- /dev/null
+++ b/config.yml.sample
@@ -0,0 +1,5 @@
+---
+ip: 10.0.3.100
+forwards:
+- - 2222
+  - 22
diff --git a/lib/provider b/lib/provider
new file mode 100755
index 0000000..3c8f9a5
--- /dev/null
+++ b/lib/provider
@@ -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 || []))
diff --git a/setup-vagrant-dev-box b/setup-vagrant-dev-box
new file mode 100755
index 0000000..f6ee4b4
--- /dev/null
+++ b/setup-vagrant-dev-box
@@ -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'
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..3380bd3
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -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
diff --git a/spec/vagrant_ssh_spec.rb b/spec/vagrant_ssh_spec.rb
new file mode 100644
index 0000000..62f952f
--- /dev/null
+++ b/spec/vagrant_ssh_spec.rb
@@ -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
diff --git a/spec/vagrant_up_spec.rb b/spec/vagrant_up_spec.rb
new file mode 100644
index 0000000..191ae2b
--- /dev/null
+++ b/spec/vagrant_up_spec.rb
@@ -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
diff --git a/tasks/spec.rake b/tasks/spec.rake
new file mode 100644
index 0000000..b72e1cf
--- /dev/null
+++ b/tasks/spec.rake
@@ -0,0 +1,4 @@
+if ENV['USER'] == 'vagrant'
+  require 'rspec/core/rake_task'
+  RSpec::Core::RakeTask.new(:spec)
+end
diff --git a/vagrant-1.1 b/vagrant-1.1
new file mode 160000
index 0000000..803269f
--- /dev/null
+++ b/vagrant-1.1
@@ -0,0 +1 @@
+Subproject commit 803269f7291719715011c5c76d66e20101f7af50