From e8388743ca04096850e0c65e18bc383d3bae2025 Mon Sep 17 00:00:00 2001
From: Fabio Rehm <fgrehm@gmail.com>
Date: Tue, 19 Mar 2013 01:25:27 -0300
Subject: [PATCH] Add support for starting processes inside a running container
 using `lxc-attach`

---
 lib/vagrant-lxc/container.rb     |  1 -
 lib/vagrant-lxc/container/cli.rb | 12 ++++++++++++
 spec/unit/container/cli_spec.rb  | 21 +++++++++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/lib/vagrant-lxc/container.rb b/lib/vagrant-lxc/container.rb
index 45976f5..4169ffc 100644
--- a/lib/vagrant-lxc/container.rb
+++ b/lib/vagrant-lxc/container.rb
@@ -1,4 +1,3 @@
-# FIXME: Ruby 1.8 users dont have SecureRandom
 require 'securerandom'
 
 require "vagrant-lxc/errors"
diff --git a/lib/vagrant-lxc/container/cli.rb b/lib/vagrant-lxc/container/cli.rb
index 5dd1c5a..e1ceaca 100644
--- a/lib/vagrant-lxc/container/cli.rb
+++ b/lib/vagrant-lxc/container/cli.rb
@@ -56,6 +56,18 @@ module Vagrant
           run :shutdown, '--name', @name
         end
 
+        def attach(*cmd)
+          cmd = ['--'] + cmd
+
+          if cmd.last.is_a?(Hash)
+            opts       = cmd.pop
+            namespaces = Array(opts[:namespaces]).map(&:upcase).join('|')
+            extra      = ['--namespaces', namespaces] if namespaces
+          end
+
+          run :attach, '--name', @name, *((extra || []) + cmd)
+        end
+
         def transition_to(state, &block)
           raise TransitionBlockNotProvided unless block_given?
 
diff --git a/spec/unit/container/cli_spec.rb b/spec/unit/container/cli_spec.rb
index 2a54533..aedf6e6 100644
--- a/spec/unit/container/cli_spec.rb
+++ b/spec/unit/container/cli_spec.rb
@@ -122,6 +122,27 @@ describe Vagrant::LXC::Container::CLI do
     end
   end
 
+  describe 'attach' do
+    let(:name)           { 'a-running-container' }
+    let(:command)        { ['ls', 'cat /tmp/file'] }
+    let(:command_output) { 'folders list' }
+    subject              { described_class.new(name) }
+
+    before do
+      subject.stub(run: command_output)
+    end
+
+    it 'calls lxc-attach with specified command' do
+      subject.attach(*command)
+      subject.should have_received(:run).with(:attach, '--name', name, '--', *command)
+    end
+
+    it 'supports a "namespaces" parameter' do
+      subject.attach *(command + [{namespaces: ['network', 'mount']}])
+      subject.should have_received(:run).with(:attach, '--name', name, '--namespaces', 'NETWORK|MOUNT', '--', *command)
+    end
+  end
+
   describe 'transition block' do
     let(:name) { 'a-running-container' }
     subject    { described_class.new(name) }