remote_run 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +2 -0
- data/.rvmrc +1 -3
- data/Gemfile +6 -3
- data/Rakefile +9 -0
- data/lib/remote_run/configuration.rb +8 -4
- data/lib/remote_run/host.rb +15 -14
- data/lib/remote_run/runner.rb +1 -1
- data/lib/remote_run/version.rb +1 -1
- data/spec/remote_run/configuration_spec.rb +7 -10
- data/spec/remote_run/host_spec.rb +12 -20
- data/spec/remote_run/runner_spec.rb +1 -1
- data/spec/spec_helper.rb +6 -0
- metadata +14 -7
data/.rspec
ADDED
data/.rvmrc
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,2 +1,11 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rspec/core'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
1
5
|
require 'bundler'
|
2
6
|
Bundler::GemHelper.install_tasks
|
7
|
+
|
8
|
+
task :default => :spec
|
9
|
+
|
10
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
11
|
+
RSpec::Core::RakeTask.new(:spec)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module RemoteRun
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :remote_path, :local_path, :login_as, :exclude, :temp_path, :quiet, :before_task, :after_task, :before_run, :after_run, :around_task, :around_run
|
3
|
+
attr_accessor :remote_path, :local_path, :login_as, :exclude, :temp_path, :quiet, :before_task, :after_task, :before_run, :after_run, :around_task, :around_run,
|
4
|
+
:known_hosts, :ssh_options, :rsync_options
|
4
5
|
attr_reader :local_hostname, :identifier, :start_time
|
5
6
|
attr_reader :host_manager, :task_manager
|
6
7
|
|
@@ -9,12 +10,15 @@ module RemoteRun
|
|
9
10
|
@host_manager = HostManager.new
|
10
11
|
|
11
12
|
@local_path = Dir.getwd
|
12
|
-
@login_as =
|
13
|
+
@login_as = ENV["USER"]
|
13
14
|
@remote_path = "/tmp/remote"
|
14
15
|
@exclude = []
|
15
16
|
@temp_path = "/tmp/remote"
|
16
17
|
@quiet = false
|
17
18
|
@start_time = Time.now
|
19
|
+
@known_hosts = File.expand_path("#{ENV['HOME']}/.ssh/known_hosts")
|
20
|
+
@ssh_options = "-o NoHostAuthenticationForLocalhost=yes -o UserKnownHostsFile=#{known_hosts} -o NumberOfPasswordPrompts=0 -o StrictHostKeyChecking=no -o ConnectTimeout=3 -4 "
|
21
|
+
@rsync_options = "--delete --rsh='ssh #{ssh_options}' --timeout=60 -a"
|
18
22
|
|
19
23
|
# used in the runner
|
20
24
|
@identifier = `echo $RANDOM`.strip
|
@@ -27,7 +31,7 @@ module RemoteRun
|
|
27
31
|
@after_task = Proc.new{}
|
28
32
|
@around_task = Proc.new {|&block| block.call }
|
29
33
|
$runner = self
|
30
|
-
yield self
|
34
|
+
yield self if block_given?
|
31
35
|
end
|
32
36
|
|
33
37
|
def hosts
|
@@ -40,7 +44,7 @@ module RemoteRun
|
|
40
44
|
|
41
45
|
def hosts=(hostnames)
|
42
46
|
hostnames.each do |hostname|
|
43
|
-
@host_manager.add(Host.new(hostname))
|
47
|
+
@host_manager.add(Host.new(hostname, self))
|
44
48
|
end
|
45
49
|
end
|
46
50
|
|
data/lib/remote_run/host.rb
CHANGED
@@ -2,12 +2,12 @@ module RemoteRun
|
|
2
2
|
class Host
|
3
3
|
FAIL = 1
|
4
4
|
PASS = 0
|
5
|
-
|
6
|
-
attr_reader :hostname
|
5
|
+
attr_reader :hostname, :configuration
|
7
6
|
|
8
|
-
def initialize(hostname)
|
7
|
+
def initialize(hostname, configuration)
|
9
8
|
@hostname = hostname
|
10
|
-
@lock_file = LockFile.new(@hostname, $runner.local_hostname, $runner.identifier)
|
9
|
+
@lock_file = LockFile.new(@hostname, $runner.local_hostname, $runner.identifier, configuration)
|
10
|
+
@configuration = configuration
|
11
11
|
end
|
12
12
|
|
13
13
|
def lock
|
@@ -21,15 +21,15 @@ module RemoteRun
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def run(task)
|
24
|
-
command = %Q{ssh #{
|
24
|
+
command = %Q{ssh #{configuration.ssh_options} #{ssh_host_and_user} 'cd #{$runner.remote_path}; #{task}' 2>&1}
|
25
25
|
system(command)
|
26
26
|
$?.exitstatus
|
27
27
|
end
|
28
28
|
|
29
29
|
def copy_codebase
|
30
|
-
system("ssh #{
|
30
|
+
system("ssh #{configuration.ssh_options} #{ssh_host_and_user} 'mkdir -p #{$runner.remote_path}'")
|
31
31
|
excludes = $runner.exclude.map { |dir| "--exclude '#{dir}'"}
|
32
|
-
if system(%{rsync
|
32
|
+
if system(%{rsync #{configuration.rsync_options} --delete-excluded #{excludes.join(" ")} #{$runner.temp_path}/ #{ssh_host_and_user}:#{$runner.remote_path}/})
|
33
33
|
return true
|
34
34
|
else
|
35
35
|
return false
|
@@ -37,7 +37,7 @@ module RemoteRun
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def is_up?
|
40
|
-
result = `ssh #{
|
40
|
+
result = `ssh #{configuration.ssh_options} #{ssh_host_and_user} "echo 'success'" 2>/dev/null`.strip
|
41
41
|
if result == "success"
|
42
42
|
return true
|
43
43
|
else
|
@@ -47,7 +47,7 @@ module RemoteRun
|
|
47
47
|
|
48
48
|
def start_ssh_master_connection
|
49
49
|
fork do
|
50
|
-
system("ssh #{
|
50
|
+
system("ssh #{configuration.ssh_options} #{ssh_host_and_user} -M &> /dev/null")
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -68,10 +68,10 @@ module RemoteRun
|
|
68
68
|
class LockFile
|
69
69
|
FILE = "/tmp/remote-run-lock"
|
70
70
|
|
71
|
-
def initialize(remote_hostname, local_hostname, unique_run_marker)
|
71
|
+
def initialize(remote_hostname, local_hostname, unique_run_marker, configuration)
|
72
72
|
@filename = FILE
|
73
73
|
@locker = "#{local_hostname}-#{unique_run_marker}"
|
74
|
-
@remote_file = RemoteFile.new(remote_hostname)
|
74
|
+
@remote_file = RemoteFile.new(remote_hostname, configuration)
|
75
75
|
end
|
76
76
|
|
77
77
|
def release
|
@@ -93,8 +93,9 @@ module RemoteRun
|
|
93
93
|
end
|
94
94
|
|
95
95
|
class RemoteFile
|
96
|
-
def initialize(hostname)
|
96
|
+
def initialize(hostname, configuration)
|
97
97
|
@hostname = hostname
|
98
|
+
@configuration = configuration
|
98
99
|
end
|
99
100
|
|
100
101
|
def exist?(file_path)
|
@@ -114,11 +115,11 @@ module RemoteRun
|
|
114
115
|
end
|
115
116
|
|
116
117
|
def run(command)
|
117
|
-
`ssh #{
|
118
|
+
`ssh #{@configuration.ssh_options} #{$runner.login_as}@#{@hostname} '#{command};'`.strip
|
118
119
|
end
|
119
120
|
|
120
121
|
def run_and_test(command)
|
121
|
-
system("ssh #{
|
122
|
+
system("ssh #{@configuration.ssh_options} #{$runner.login_as}@#{@hostname} '#{command}' 2>/dev/null")
|
122
123
|
end
|
123
124
|
end
|
124
125
|
end
|
data/lib/remote_run/runner.rb
CHANGED
@@ -39,7 +39,7 @@ module RemoteRun
|
|
39
39
|
def sync_working_copy_to_temp_location
|
40
40
|
log("Creating temporary copy of #{@configuration.local_path} in #{@configuration.temp_path}...")
|
41
41
|
excludes = @configuration.exclude.map { |dir| "--exclude '#{dir}'"}
|
42
|
-
system("rsync
|
42
|
+
system("rsync #{Configuration::RSYNC_CONFIG} --delete-excluded #{excludes.join(" ")} -q #{@configuration.local_path}/ #{@configuration.temp_path}/")
|
43
43
|
log("Done.")
|
44
44
|
end
|
45
45
|
|
data/lib/remote_run/version.rb
CHANGED
@@ -1,21 +1,18 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
describe RemoteRun::Configuration do
|
3
|
-
let(:
|
4
|
-
let(:
|
5
|
-
let!(:pre_run) { double(call: true) }
|
6
|
-
let!(:post_run) { double(call: true) }
|
3
|
+
let!(:before_run) { double(call: true) }
|
4
|
+
let!(:after_run) { double(call: true) }
|
7
5
|
subject do
|
8
6
|
RemoteRun::Configuration.new do |config|
|
9
|
-
config.
|
10
|
-
config.
|
11
|
-
config.
|
12
|
-
config.post_run = post_run
|
7
|
+
config.before_run = before_run
|
8
|
+
config.around_run = Proc.new {}
|
9
|
+
config.after_run = after_run
|
13
10
|
end
|
14
11
|
end
|
15
12
|
|
16
13
|
it "pre_run should have a callable block" do
|
17
|
-
|
18
|
-
|
14
|
+
before_run.should_receive(:call).once
|
15
|
+
after_run.should_receive(:call).once
|
19
16
|
subject.run
|
20
17
|
end
|
21
18
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe RemoteRun::Host do
|
4
|
-
|
5
|
-
|
4
|
+
let(:configuration) { RemoteRun::Configuration.new }
|
5
|
+
let(:host) { RemoteRun::Host.new("localhost", configuration) }
|
6
6
|
|
7
|
+
context "when locking" do
|
7
8
|
it "can be locked" do
|
8
9
|
host.lock.should be_true
|
9
10
|
end
|
@@ -15,15 +16,14 @@ describe RemoteRun::Host do
|
|
15
16
|
|
16
17
|
it "tells the lock file to get a lock" do
|
17
18
|
host.lock
|
18
|
-
|
19
|
+
ssh_command("localhost", "test -e #{RemoteRun::Host::LockFile::FILE} && cat #{RemoteRun::Host::LockFile::FILE}").should == "#{$runner.local_hostname}-#{$runner.identifier}"
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
23
|
context "when locked by someone else" do
|
23
24
|
before { lock_file.get }
|
24
|
-
let(:host) { RemoteRun::Host.new("localhost") }
|
25
25
|
let(:lock_file) {
|
26
|
-
lock_file = RemoteRun::Host::LockFile.new("localhost", "myfakelocalhost", "999")
|
26
|
+
lock_file = RemoteRun::Host::LockFile.new("localhost", "myfakelocalhost", "999", configuration)
|
27
27
|
}
|
28
28
|
|
29
29
|
it "cannot be unlocked by me" do
|
@@ -33,8 +33,6 @@ describe RemoteRun::Host do
|
|
33
33
|
|
34
34
|
context "when locked by me" do
|
35
35
|
before { host.lock }
|
36
|
-
let(:host) { RemoteRun::Host.new("localhost") }
|
37
|
-
|
38
36
|
it "cannot be locked" do
|
39
37
|
host.lock.should be_false
|
40
38
|
end
|
@@ -44,23 +42,21 @@ describe RemoteRun::Host do
|
|
44
42
|
end
|
45
43
|
|
46
44
|
it "removes a file on the remote filesystem to unlock" do
|
47
|
-
|
45
|
+
ssh_command("localhost", "test -e #{RemoteRun::Host::LockFile::FILE}; echo $?").should == "0"
|
48
46
|
host.unlock
|
49
|
-
|
47
|
+
ssh_command("localhost", "test -e #{RemoteRun::Host::LockFile::FILE}; echo $?").should == "1"
|
50
48
|
end
|
51
49
|
end
|
52
50
|
|
53
51
|
context "when checking to see if a host is up" do
|
54
52
|
context "when using an authorized host" do
|
55
|
-
let(:host) { RemoteRun::Host.new("localhost") }
|
56
|
-
|
57
53
|
it "returns true" do
|
58
54
|
host.is_up?.should be_true
|
59
55
|
end
|
60
56
|
end
|
61
57
|
|
62
58
|
context "when using an unauthorized host" do
|
63
|
-
let(:host) { RemoteRun::Host.new("foozmcbarry") }
|
59
|
+
let(:host) { RemoteRun::Host.new("foozmcbarry", configuration) }
|
64
60
|
|
65
61
|
it "returns false" do
|
66
62
|
host.is_up?.should be_false
|
@@ -70,12 +66,10 @@ describe RemoteRun::Host do
|
|
70
66
|
|
71
67
|
context "when running a task" do
|
72
68
|
before do
|
73
|
-
|
69
|
+
ssh_command "localhost", "rm -rf /tmp/testing-remote-run"
|
74
70
|
host.lock
|
75
71
|
end
|
76
72
|
|
77
|
-
let(:host) { RemoteRun::Host.new("localhost") }
|
78
|
-
|
79
73
|
context "when executing a shell command with a zero status code" do
|
80
74
|
it "returns zero" do
|
81
75
|
host.run("date > /dev/null").should == 0
|
@@ -91,17 +85,15 @@ describe RemoteRun::Host do
|
|
91
85
|
|
92
86
|
describe "#copy_codebase" do
|
93
87
|
before do
|
94
|
-
|
88
|
+
ssh_command "localhost", "rm -rf /tmp/testing-remote-run"
|
95
89
|
host.lock
|
96
90
|
end
|
97
91
|
|
98
|
-
let(:host) { RemoteRun::Host.new("localhost") }
|
99
|
-
|
100
92
|
it "copies the codebase to a remote directory" do
|
101
93
|
$runner.remote_path = "/tmp/testing-remote-run"
|
102
|
-
|
94
|
+
ssh_command("localhost", "test -e /tmp/testing-remote-run; echo $?").should_not == "0"
|
103
95
|
host.copy_codebase
|
104
|
-
|
96
|
+
ssh_command("localhost", "test -e /tmp/testing-remote-run; echo $?").should == "0"
|
105
97
|
end
|
106
98
|
end
|
107
99
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe RemoteRun::Runner do
|
4
4
|
let(:host_manager) { double(:host_manager) }
|
5
5
|
let(:task_manager) { double(:task_manager, count: 0) }
|
6
|
-
let(:configuration) { double(:configuration, task_manager: task_manager, host_manager: host_manager) }
|
6
|
+
let(:configuration) { double(:configuration, before_task: nil, after_task: nil,around_task: nil, task_manager: task_manager, host_manager: host_manager) }
|
7
7
|
let(:runner) { RemoteRun::Runner.new(configuration) }
|
8
8
|
subject { runner }
|
9
9
|
it { should be }
|
data/spec/spec_helper.rb
CHANGED
@@ -14,3 +14,9 @@ RSpec.configure do |config|
|
|
14
14
|
system("rm -f #{RemoteRun::Host::LockFile::FILE}")
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
def ssh_command(host, cmd)
|
19
|
+
result = `ssh -q -o NoHostAuthenticationForLocalhost=yes -o UserKnownHostsFile=/dev/null -o NumberOfPasswordPrompts=0 -o StrictHostKeyChecking=no -o ConnectTimeout=3 -4 #{host} '#{cmd}'`.strip
|
20
|
+
raise "SSH Execution Error: #{result}" unless $?.success?
|
21
|
+
result
|
22
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remote_run
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-03 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: highline
|
16
|
-
requirement: &
|
16
|
+
requirement: &70153015390580 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70153015390580
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70153015390040 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70153015390040
|
36
36
|
description: Can be used as a parallel unit test runner
|
37
37
|
email:
|
38
38
|
- casecommons-dev@googlegroups.com
|
@@ -41,6 +41,7 @@ extensions: []
|
|
41
41
|
extra_rdoc_files: []
|
42
42
|
files:
|
43
43
|
- .gitignore
|
44
|
+
- .rspec
|
44
45
|
- .rvmrc
|
45
46
|
- Gemfile
|
46
47
|
- LICENSE
|
@@ -71,15 +72,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
72
|
- - ! '>='
|
72
73
|
- !ruby/object:Gem::Version
|
73
74
|
version: '0'
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
hash: -2891303972546043614
|
74
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
79
|
none: false
|
76
80
|
requirements:
|
77
81
|
- - ! '>='
|
78
82
|
- !ruby/object:Gem::Version
|
79
83
|
version: '0'
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
hash: -2891303972546043614
|
80
87
|
requirements: []
|
81
88
|
rubyforge_project: remote_run
|
82
|
-
rubygems_version: 1.8.
|
89
|
+
rubygems_version: 1.8.13
|
83
90
|
signing_key:
|
84
91
|
specification_version: 3
|
85
92
|
summary: Run N shell scripts on a pool of remote hosts
|