vagrant-shell-commander 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -17,4 +17,5 @@ tmp
17
17
  .ruby-*
18
18
  *~
19
19
  .vagrant
20
- *gem
20
+ *gem
21
+ debug*
@@ -1,8 +1,8 @@
1
1
  GIT
2
2
  remote: git://github.com/mitchellh/vagrant.git
3
- revision: e1e57024dc78565b99b8f2ccdd9c388270bf2de0
3
+ revision: 4638a7a0dff2a242ae583e045c56f6ce49191a4e
4
4
  specs:
5
- vagrant (1.2.3.dev)
5
+ vagrant (1.3.2.dev)
6
6
  childprocess (~> 0.3.7)
7
7
  erubis (~> 2.7.0)
8
8
  i18n (~> 0.6.0)
@@ -13,7 +13,7 @@ GIT
13
13
  PATH
14
14
  remote: .
15
15
  specs:
16
- vagrant-shell-commander (0.1.4)
16
+ vagrant-shell-commander (0.2.0)
17
17
 
18
18
  GEM
19
19
  remote: https://rubygems.org/
@@ -25,26 +25,26 @@ GEM
25
25
  diff-lcs (1.2.4)
26
26
  erubis (2.7.0)
27
27
  ffi (1.9.0)
28
- i18n (0.6.4)
28
+ i18n (0.6.5)
29
29
  log4r (1.1.10)
30
30
  multi_json (1.7.7)
31
- net-scp (1.1.1)
31
+ net-scp (1.1.2)
32
32
  net-ssh (>= 2.6.5)
33
- net-ssh (2.6.7)
33
+ net-ssh (2.6.8)
34
34
  parallel (0.7.1)
35
35
  rake (10.1.0)
36
36
  reek (1.3.1)
37
37
  ruby2ruby (~> 2.0.2)
38
38
  ruby_parser (~> 3.1.1)
39
39
  sexp_processor
40
- rspec (2.13.0)
41
- rspec-core (~> 2.13.0)
42
- rspec-expectations (~> 2.13.0)
43
- rspec-mocks (~> 2.13.0)
44
- rspec-core (2.13.1)
45
- rspec-expectations (2.13.0)
40
+ rspec (2.14.1)
41
+ rspec-core (~> 2.14.0)
42
+ rspec-expectations (~> 2.14.0)
43
+ rspec-mocks (~> 2.14.0)
44
+ rspec-core (2.14.5)
45
+ rspec-expectations (2.14.2)
46
46
  diff-lcs (>= 1.1.3, < 2.0)
47
- rspec-mocks (2.13.1)
47
+ rspec-mocks (2.14.3)
48
48
  ruby2ruby (2.0.6)
49
49
  ruby_parser (~> 3.1)
50
50
  sexp_processor (~> 4.0)
data/README.md CHANGED
@@ -3,13 +3,26 @@
3
3
 
4
4
  # Vagrant::Shell::Commander
5
5
 
6
- Vagrant plugin for executing arbitrary shell commands on guest. Executes the given command on all the machines on multinode environments. It also gives the option to specify a working directory.
6
+ Vagrant plugin for running arbitrary shell commands on guest(s). Executes the given command on all the machines of multinode environments, or just in one of them. It also gives the option to specify a working directory and a user by command line.
7
+
8
+ It allows you to hook into the boot process, specifying a command to be run once the machine has finished the complete boot process. This can be handy for running init scripts which depends on files located in shared folders, for example.
9
+
7
10
 
8
11
  ## Installation
9
12
 
10
- As usual with vagrant plugins:
13
+ Given you have Vagrant 1.1+ installed, as usual with vagrant plugins:
11
14
 
12
15
  $ vagrant plugin install vagrant-shell-commander
16
+
17
+ or with the great Bindler, after adding a plugins.json with, at least:
18
+
19
+ {
20
+ "vagrant-shell-commander"
21
+ }
22
+
23
+ execute:
24
+
25
+ $ vagrant plugin bundle
13
26
 
14
27
  ## Usage
15
28
 
@@ -25,6 +38,17 @@ Specify the working directory (remember to quote multiword commands):
25
38
 
26
39
  $ vagrant sh -c 'ls -al' -d /srv/www
27
40
 
41
+ To execute a command once the machine(s) has booted, add this configuration option to the Vagrantfile:
42
+
43
+ ```ruby
44
+ Vagrant.configure("2") do |config|
45
+ # other...
46
+
47
+ config.sh.after_share_folders = "sudo /etc/init.d/myapp start"
48
+
49
+ end
50
+ ```
51
+
28
52
  Get help:
29
53
 
30
54
  $ vagrant sh -h
@@ -1,6 +1,11 @@
1
1
  Vagrant.require_plugin "vagrant-shell-commander"
2
2
 
3
- Vagrant::Config.run do |config|
3
+ Vagrant.configure("2") do |config|
4
4
  config.vm.box = "canonical-ubuntu-12.04"
5
5
  config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box"
6
+
7
+ config.vm.define "node1"
8
+ config.vm.define "node2"
9
+
10
+ config.sh.after_share_folders = "free"
6
11
  end
@@ -1,15 +1,7 @@
1
1
  require "vagrant-shell-commander/version"
2
2
  require "vagrant-shell-commander/option_manager"
3
+ require "vagrant-shell-commander/plugin"
4
+ require 'vagrant-shell-commander/command'
5
+ require 'vagrant-shell-commander/config'
6
+ require 'vagrant-shell-commander/action'
3
7
 
4
- module VagrantShellCommander
5
- # Plugin definition
6
- #
7
- class Plugin < Vagrant.plugin("2")
8
- name 'vagrant shell commander'
9
-
10
- command 'sh' do
11
- require_relative 'vagrant-shell-commander/command'
12
- Command
13
- end
14
- end
15
- end
@@ -0,0 +1,26 @@
1
+ module VagrantShellCommander
2
+ # Action for shell command hooking
3
+ class Action
4
+ # Constructor
5
+ #
6
+ # @param app [Action] Next middleware to call
7
+ # @param env [Hash] Action environment
8
+ # @return nil
9
+ #
10
+ def initialize(app, env)
11
+ @app = app
12
+ @machine = env[:machine]
13
+ end
14
+
15
+ # Call method of this middleware
16
+ #
17
+ # @param env [Hash] Action environment
18
+ # @return nil
19
+ #
20
+ def call(env)
21
+ @app.call(env)
22
+ @machine.action(:ssh_run,
23
+ ssh_run_command: env[:global_config].sh.after_share_folders)
24
+ end
25
+ end
26
+ end
@@ -23,8 +23,6 @@ module VagrantShellCommander
23
23
 
24
24
  private
25
25
 
26
-
27
-
28
26
  # Executes actions for a given machine
29
27
  #
30
28
  # @param [Vagrant::Machine] subject vm
@@ -37,23 +35,24 @@ module VagrantShellCommander
37
35
  return
38
36
  end
39
37
 
40
- machine.communicate.
41
- execute(add_cwd_to_command(cli_options[:values][:cmd],
42
- cli_options[:values][:dir])) do |type, data|
43
- env.ui.success("#{machine.name}::")
44
- env.ui.info(data)
45
- end
38
+ env.ui.success("#{machine.name}::")
39
+ machine.action(:ssh_run,
40
+ ssh_run_command: add_options_to_command(cli_options[:values][:cmd],
41
+ cli_options[:values][:dir],
42
+ cli_options[:values][:user]))
46
43
  end
47
44
 
48
- # Adds the change to a working directory to the given command
45
+ # Adds the options to the given command
49
46
  #
50
47
  # @param cmd [String] Shell command
51
48
  # @param cwd [String] Optional working directory
52
- # @return [String] Command with directory change if cwd is present
49
+ # @param user [String] Optional executing user
50
+ # @return [String] Command with directory change if cwd is present and optional executing user
53
51
  #
54
- def add_cwd_to_command(cmd, cwd=nil)
55
- return cmd unless cwd
56
- "cd #{cwd} && #{cmd}"
52
+ def add_options_to_command(cmd, cwd=nil, user=nil)
53
+ cmd = "cd #{cwd} && #{cmd}" if cwd
54
+ cmd = "sudo su - #{user} -c \"#{cmd}\"" if user
55
+ cmd
57
56
  end
58
57
  end
59
58
  end
@@ -0,0 +1,19 @@
1
+ module VagrantShellCommander
2
+ # Configuration options
3
+ class Config < Vagrant.plugin("2", "config")
4
+ attr_accessor :after_share_folders
5
+
6
+ # Initialize override, setting config options default values
7
+ # for merging
8
+ def initialize
9
+ super
10
+
11
+ @after_share_folders = UNSET_VALUE
12
+ end
13
+
14
+ # finalize! override, unseting config options
15
+ def finalize!
16
+ @after_share_folders = nil if @after_share_folders == UNSET_VALUE
17
+ end
18
+ end
19
+ end
@@ -18,6 +18,11 @@ module VagrantShellCommander
18
18
  options[:dir] = dir
19
19
  end
20
20
 
21
+ parser.on('-u [USER]', '--user [USER]',
22
+ 'User to execute the command') do |user|
23
+ options[:user] = user
24
+ end
25
+
21
26
  parser.on("-c 'COMMAND'", "--command 'COMMAND'",
22
27
  'Command to execute, quotes required for multiword') do |cmd|
23
28
  options[:cmd] = cmd
@@ -0,0 +1,21 @@
1
+ module VagrantShellCommander
2
+ # Plugin definition
3
+ #
4
+ class Plugin < Vagrant.plugin("2")
5
+ name 'vagrant shell commander'
6
+
7
+ command 'sh' do
8
+ Command
9
+ end
10
+
11
+ config 'sh' do
12
+ Config
13
+ end
14
+
15
+ %w[up reload].each do |event|
16
+ action_hook("sh_hook_#{event}".to_sym, "machine_action_#{event}".to_sym) do |hook|
17
+ hook.append(VagrantShellCommander::Action)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module VagrantShellCommander
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe VagrantShellCommander::Action do
4
+ let(:app) {double(call: true)}
5
+ let(:machine) {double(action: true)}
6
+ let(:env) {double(:[] => machine)}
7
+ let(:cmd) {'cmd'}
8
+ let(:sh) {double(after_share_folders: cmd)}
9
+ let(:global_config) {double(sh: sh)}
10
+ let(:action_env) {{global_config: global_config}}
11
+ let(:subject) {described_class.new(app, env)}
12
+
13
+ describe "#call" do
14
+ after(:each) do
15
+ subject.call(action_env)
16
+ end
17
+
18
+ it "should call the next middleware" do
19
+ expect(app).to receive(:call).with(action_env)
20
+ end
21
+
22
+ it "should call SSHRun action of the current machine with the after_boot option as command" do
23
+ allow(env).to receive(:[]).with(:machine).and_return(machine)
24
+
25
+ expect(machine).to receive(:action).with(:ssh_run, ssh_run_command: cmd)
26
+ end
27
+ end
28
+ end
@@ -57,17 +57,18 @@ describe VagrantShellCommander::Command do
57
57
  end
58
58
 
59
59
  it 'reports information about state' do
60
- ui.should_receive(:warn).with("Machine #{machine_name} is not running.")
60
+ expect(ui).to receive(:warn).with("Machine #{machine_name} is not running.")
61
61
  end
62
62
 
63
63
  it 'dows not try to execute the command' do
64
- machine.should_not_receive(:communicate)
64
+ expect(machine).not_to receive(:communicate)
65
65
  end
66
66
  end
67
67
 
68
68
  context 'running machine' do
69
69
  let(:cmd) {'command'}
70
70
  let(:dir) {'dir'}
71
+ let(:user) {'user'}
71
72
  let(:communicate) {double(execute: true)}
72
73
 
73
74
  before(:each) do
@@ -75,35 +76,48 @@ describe VagrantShellCommander::Command do
75
76
  and_return(parser: 'parser', values: {cmd: cmd})
76
77
 
77
78
  machine.stub_chain(:state, :id).and_return(:running)
78
- machine.stub(:communicate).and_return(communicate)
79
+ allow(ui).to receive(:success)
80
+ allow(machine).to receive(:action)
79
81
  end
80
82
 
81
83
  it 'executes the given command' do
82
- communicate.should_receive(:execute).with(cmd)
84
+ expect(machine).to receive(:action).with(:ssh_run, ssh_run_command: cmd)
83
85
  end
84
86
 
85
- it 'shows the command output along with the machine name' do
86
- data = 'data'
87
-
88
- communicate.stub(:execute).and_yield('type', data)
89
-
90
- ui.should_receive(:success).with("#{machine_name}::")
91
- ui.should_receive(:info).with(data)
87
+ it 'shows the machine name' do
88
+ expect(ui).to receive(:success).with("#{machine_name}::")
92
89
  end
93
90
 
94
91
  it 'executes the command in the given dir' do
95
92
  VagrantShellCommander::OptionManager.stub_chain(:new, :execute).
96
93
  and_return(parser: 'parser', values: {cmd: cmd, dir: dir})
97
94
 
98
- communicate.should_receive(:execute).with("cd #{dir} && #{cmd}")
95
+ expect(machine).to receive(:action).with(:ssh_run,
96
+ ssh_run_command: "cd #{dir} && #{cmd}")
97
+ end
98
+
99
+ it 'executes the command for the given user' do
100
+ VagrantShellCommander::OptionManager.stub_chain(:new, :execute).
101
+ and_return(parser: 'parser', values: {cmd: cmd, user: user})
102
+
103
+ expect(machine).to receive(:action).with(:ssh_run,
104
+ ssh_run_command: "sudo su - #{user} -c \"#{cmd}\"")
105
+ end
106
+
107
+ it 'executes the command for the given user and the given dir' do
108
+ VagrantShellCommander::OptionManager.stub_chain(:new, :execute).
109
+ and_return(parser: 'parser', values: {cmd: cmd, user: user, dir: dir})
110
+
111
+ expect(machine).to receive(:action).with(:ssh_run,
112
+ ssh_run_command: "sudo su - #{user} -c \"cd #{dir} && #{cmd}\"")
99
113
  end
100
114
 
101
115
  describe 'shows help' do
102
116
  let(:parser) {'parser'}
103
117
 
104
118
  after(:each) do
105
- subject.should_not_receive(:with_target_vms)
106
- ui.should_receive(:info).with(parser)
119
+ expect(subject).not_to receive(:with_target_vms)
120
+ expect(ui).to receive(:info).with(parser)
107
121
  end
108
122
 
109
123
  it 'an empty command' do
@@ -113,7 +127,7 @@ describe VagrantShellCommander::Command do
113
127
 
114
128
  it 'non present command' do
115
129
  VagrantShellCommander::OptionManager.stub_chain(:new, :execute).
116
- and_return(parser: parser, values: {dir: dir})
130
+ and_return(parser: parser, values: {user: user})
117
131
  end
118
132
  end
119
133
  end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe VagrantShellCommander::Config do
4
+
5
+ let(:subject) {described_class.new}
6
+
7
+ describe 'config properies' do
8
+ it 'should have a after_share_folders attr_accessor' do
9
+ expect(subject).to respond_to(:after_share_folders)
10
+ expect(subject).to respond_to(:after_share_folders=)
11
+ end
12
+ end
13
+
14
+ describe "#initialize" do
15
+ it 'should initialize after_share_folders' do
16
+ expect(subject.after_share_folders).to be_equal(Vagrant::Plugin::V2::Config::UNSET_VALUE)
17
+ end
18
+ end
19
+
20
+ describe "#finalize!" do
21
+ it 'should deinitialize after_share_folders if it has been set' do
22
+ config = described_class.new
23
+ config.finalize!
24
+ expect(config.after_share_folders).to be_nil
25
+ end
26
+
27
+ it 'should not deinitialize after_share_folders if it has not been set' do
28
+ config = described_class.new
29
+ config.after_share_folders = 'value'
30
+ config.finalize!
31
+ expect(config.after_share_folders).to eq('value')
32
+ end
33
+
34
+ end
35
+ end
@@ -51,5 +51,19 @@ describe VagrantShellCommander::OptionManager do
51
51
 
52
52
  expect(result[:values][:cmd]).to eql(cmd_value)
53
53
  end
54
+
55
+ it 'has a user option' do
56
+ user_value = 'user'
57
+
58
+ option_parser.stub(:on).with('-u [USER]',
59
+ anything,
60
+ anything).
61
+ and_yield(user_value)
62
+
63
+ result = subject.execute
64
+
65
+ expect(result[:values][:user]).to eql(user_value)
66
+ end
67
+
54
68
  end
55
69
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe VagrantShellCommander::Plugin do
4
+ it 'should have a name' do
5
+ expect(described_class.name).not_to be_nil
6
+ end
7
+
8
+ it "should define a command of type Command" do
9
+ default_command = described_class.command.
10
+ to_hash[:"sh"]
11
+ expect(default_command).to be(VagrantShellCommander::Command)
12
+ end
13
+
14
+ it "should define a config of type Config" do
15
+ default_config = described_class.components.configs[:top].to_hash[:"sh"]
16
+ expect(default_config).to be(VagrantShellCommander::Config)
17
+ end
18
+
19
+ context 'action hooks' do
20
+ let(:hook) {double(append: true, prepend: true)}
21
+
22
+ it "should define an action hook for machine_action_up" do
23
+ hook_proc = described_class.components.action_hooks[:machine_action_up][0]
24
+ hook = double
25
+ expect(hook).to receive(:append).with(VagrantShellCommander::Action)
26
+ hook_proc.call(hook)
27
+ end
28
+
29
+ it "should define an action hook for machine_action_reload" do
30
+ hook_proc = described_class.components.action_hooks[:machine_action_reload][0]
31
+ hook = double
32
+ expect(hook).to receive(:append).with(VagrantShellCommander::Action)
33
+ hook_proc.call(hook)
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = VagrantShellCommander::VERSION
9
9
  spec.authors = ["Federico Gimenez Nieto"]
10
10
  spec.email = ["federico.gimenez@gmail.com"]
11
- spec.description = %q{This Vagrant plugin allows you to execute a given shell command on all the machines of your multinode environment. You can also specify the working directory to execute the command}
12
- spec.summary = %q{Vagrant plugin for executing arbitrary shell commands on guest(s)}
11
+ spec.description = %q{Vagrant plugin for executing shell commands on guests machines and hooking them in the boot process}
12
+ spec.summary = %q{Some variations to shell command execution on guest(s)}
13
13
  spec.homepage = "https://github.com/fgimenez/vagrant-shell-commander"
14
14
  spec.license = "MIT"
15
15
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-shell-commander
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-27 00:00:00.000000000 Z
12
+ date: 2013-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -123,9 +123,8 @@ dependencies:
123
123
  - - ! '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
- description: This Vagrant plugin allows you to execute a given shell command on all
127
- the machines of your multinode environment. You can also specify the working directory
128
- to execute the command
126
+ description: Vagrant plugin for executing shell commands on guests machines and hooking
127
+ them in the boot process
129
128
  email:
130
129
  - federico.gimenez@gmail.com
131
130
  executables: []
@@ -145,13 +144,18 @@ files:
145
144
  - lib/tasks/reek.rake
146
145
  - lib/tasks/rspec.rake
147
146
  - lib/vagrant-shell-commander.rb
147
+ - lib/vagrant-shell-commander/action.rb
148
148
  - lib/vagrant-shell-commander/command.rb
149
+ - lib/vagrant-shell-commander/config.rb
149
150
  - lib/vagrant-shell-commander/option_manager.rb
151
+ - lib/vagrant-shell-commander/plugin.rb
150
152
  - lib/vagrant-shell-commander/version.rb
153
+ - spec/action_spec.rb
151
154
  - spec/command_spec.rb
155
+ - spec/config_spec.rb
152
156
  - spec/option_manager_spec.rb
157
+ - spec/plugin_spec.rb
153
158
  - spec/spec_helper.rb
154
- - spec/vagrant_shell_commander_spec.rb
155
159
  - vagrant-shell-commander.gemspec
156
160
  homepage: https://github.com/fgimenez/vagrant-shell-commander
157
161
  licenses:
@@ -177,10 +181,12 @@ rubyforge_project:
177
181
  rubygems_version: 1.8.25
178
182
  signing_key:
179
183
  specification_version: 3
180
- summary: Vagrant plugin for executing arbitrary shell commands on guest(s)
184
+ summary: Some variations to shell command execution on guest(s)
181
185
  test_files:
186
+ - spec/action_spec.rb
182
187
  - spec/command_spec.rb
188
+ - spec/config_spec.rb
183
189
  - spec/option_manager_spec.rb
190
+ - spec/plugin_spec.rb
184
191
  - spec/spec_helper.rb
185
- - spec/vagrant_shell_commander_spec.rb
186
192
  has_rdoc:
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe VagrantShellCommander::Plugin do
4
- it 'should have a name' do
5
- expect(described_class.name).not_to be_nil
6
- end
7
-
8
- it "should define a command of type Command" do
9
- default_command = described_class.command.
10
- to_hash[:"sh"]
11
- expect(default_command).to be(VagrantShellCommander::Command)
12
- end
13
- end