From 2b062487bc879da7e14ae0cbcdca729f43d99fa9 Mon Sep 17 00:00:00 2001
From: Fabio Rehm <fgrehm@gmail.com>
Date: Thu, 24 Oct 2013 11:44:45 -0200
Subject: [PATCH] Hack in a fix for hosts that do not have lxc-shutdown around
 [GH-150]

---
 CHANGELOG.md                  | 4 ++++
 lib/vagrant-lxc/driver.rb     | 3 ++-
 lib/vagrant-lxc/driver/cli.rb | 8 +++++++-
 spec/unit/driver/cli_spec.rb  | 8 +++++++-
 spec/unit/driver_spec.rb      | 7 +++++++
 5 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 691d604..584834a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ IMPROVEMENTS:
 
   - Make `lxc-template` compatible with Ubuntu 13.10 [#150](https://github.com/fgrehm/vagrant-lxc/issues/150)
 
+BUG FIXES:
+
+  - Fix force halt for hosts that do not have `lxc-shutdown` around (like Ubuntu 13.10) [#150](https://github.com/fgrehm/vagrant-lxc/issues/150)
+
 ## [0.6.3](https://github.com/fgrehm/vagrant-lxc/compare/v0.6.2...v0.6.3) (Oct 12, 2013)
 
 IMPROVEMENTS:
diff --git a/lib/vagrant-lxc/driver.rb b/lib/vagrant-lxc/driver.rb
index 67fc3c9..b98ed3e 100644
--- a/lib/vagrant-lxc/driver.rb
+++ b/lib/vagrant-lxc/driver.rb
@@ -84,7 +84,8 @@ module Vagrant
       def forced_halt
         @logger.info('Shutting down container...')
         @cli.transition_to(:stopped) { |c| c.shutdown }
-      rescue CLI::TargetStateNotReached
+      # REFACTOR: Do not use exception to control the flow
+      rescue CLI::TargetStateNotReached, CLI::ShutdownNotSupported
         @cli.transition_to(:stopped) { |c| c.stop }
       end
 
diff --git a/lib/vagrant-lxc/driver/cli.rb b/lib/vagrant-lxc/driver/cli.rb
index ba075b4..80e538f 100644
--- a/lib/vagrant-lxc/driver/cli.rb
+++ b/lib/vagrant-lxc/driver/cli.rb
@@ -10,6 +10,7 @@ module Vagrant
         attr_accessor :name
 
         class TransitionBlockNotProvided < RuntimeError; end
+        class ShutdownNotSupported < RuntimeError; end
         class TargetStateNotReached < RuntimeError
           def initialize(target_state, state)
             msg = "Target state '#{target_state}' not reached, currently on '#{state}'"
@@ -72,7 +73,12 @@ module Vagrant
         end
 
         def shutdown
-          run :shutdown, '--name', @name
+          if system('which lxc-shutdown > /dev/null')
+            run :shutdown, '--name', @name
+          else
+            # REFACTOR: Do not use exception to control the flow
+            raise ShutdownNotSupported
+          end
         end
 
         def attach(*cmd)
diff --git a/spec/unit/driver/cli_spec.rb b/spec/unit/driver/cli_spec.rb
index 8597648..1b7e00c 100644
--- a/spec/unit/driver/cli_spec.rb
+++ b/spec/unit/driver/cli_spec.rb
@@ -103,13 +103,19 @@ describe Vagrant::LXC::Driver::CLI do
     subject    { described_class.new(sudo_wrapper, name) }
 
     before do
+      subject.stub(system: true)
       subject.stub(:run)
-      subject.shutdown
     end
 
     it 'issues a lxc-shutdown with provided container name' do
+      subject.shutdown
       subject.should have_received(:run).with(:shutdown, '--name', name)
     end
+
+    it 'raises a ShutdownNotSupported in case it is not supported' do
+      subject.stub(:system).with('which lxc-shutdown > /dev/null').and_return(false)
+      expect { subject.shutdown }.to raise_error(described_class::ShutdownNotSupported)
+    end
   end
 
   describe 'state' do
diff --git a/spec/unit/driver_spec.rb b/spec/unit/driver_spec.rb
index f54e1d6..1b31e22 100644
--- a/spec/unit/driver_spec.rb
+++ b/spec/unit/driver_spec.rb
@@ -118,6 +118,13 @@ describe Vagrant::LXC::Driver do
       cli.should_receive(:stop)
       subject.forced_halt
     end
+
+    it 'attempts to force the container to stop in case lxc-shutdown is not supported' do
+      cli.stub(:shutdown).and_raise(Vagrant::LXC::Driver::CLI::ShutdownNotSupported)
+      cli.should_receive(:transition_to).with(:stopped).twice
+      cli.should_receive(:stop)
+      subject.forced_halt
+    end
   end
 
   describe 'state' do