elsewhere 0.5 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -13,8 +13,12 @@ r.commands << "source /etc/profile"
13
13
  r.commands << "cd ~/current"
14
14
  r.commands << "rake do:something:useful"
15
15
 
16
+ #fails silently
16
17
  r.execute
17
18
 
19
+ #raises exception on nonzero status codes
20
+ r.execute!
21
+
18
22
  => { "www.example.com" => "results from data stream"}
19
23
  ```
20
24
 
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.version = Elsewhere::VERSION
8
8
  s.authors = ["Bill Chapman"]
9
9
  s.email = ["bchapman@academicmanagement.com"]
10
- s.homepage = ""
10
+ s.homepage = "https://github.com/byllc/elsewhere"
11
11
  s.summary = %q{ Simple wrapper for Net SSH to run a list of commands remotely }
12
12
  s.description = %q{ Yet another way to run stuff remotely }
13
13
 
@@ -1,18 +1,18 @@
1
1
  module Elsewhere
2
2
 
3
- # Execute commands on a remote server
4
- # I know capistrano already does this
5
- # This was abstracted from a more specific solution that we already had in place and I thought it was worth sharing
6
- #
7
- # Usage:
8
- #
9
- # r = RemoteRun.new("hostname","username")
10
- # r.commands << "source /etc/profile"
11
- # r.commands << "cd ~/current"
12
- # r.commands << "rake extractor:run cas=3 users=12550"
13
- #
14
- # r.execute
15
- #
3
+ # Execute commands on a remote server
4
+ # I know capistrano already does this
5
+ # This was abstracted from a more specific solution that we already had in place and I thought it was worth sharing
6
+ #
7
+ # Usage:
8
+ #
9
+ # r = RemoteRun.new("hostname","username")
10
+ # r.commands << "source /etc/profile"
11
+ # r.commands << "cd ~/current"
12
+ # r.commands << "rake extractor:run cas=3 users=12550"
13
+ #
14
+ # r.execute
15
+ #
16
16
  require 'net/ssh'
17
17
  require 'net/ssh/gateway'
18
18
  require 'yaml'
@@ -21,7 +21,7 @@ module Elsewhere
21
21
  #TODO: move to remote_run/exceptions.rb when we gemify this
22
22
  class RemoteRunError < StandardError; end
23
23
 
24
- attr_accessor :hosts, :gateway_address, :gateway_user, :commands
24
+ attr_accessor :hosts, :user, :gateway_address, :gateway_user, :commands
25
25
 
26
26
  def initialize(hosts,user, options={})
27
27
  @hosts = [hosts].flatten #accept a single host or an array of hosts
@@ -31,6 +31,14 @@ module Elsewhere
31
31
  @commands = []
32
32
  end
33
33
 
34
+ def add_command
35
+ @commands << command
36
+ end
37
+
38
+ def remove_command command
39
+ @commands.delete(command.strip)
40
+ end
41
+
34
42
  #expects the config file to be formatted as yaml as follows
35
43
  #environment:
36
44
  # group:
@@ -53,18 +61,23 @@ module Elsewhere
53
61
  end
54
62
  end
55
63
 
56
- def ssh_wrapper(host,command)
64
+ def ssh_wrapper(host,command,raise_exceptions)
57
65
  output = nil
58
66
  Net::SSH.start(host, @user) do |ssh|
59
- output = execute_over_ssh(ssh,command)
67
+ output = execute_over_ssh(ssh,command,raise_exceptions)
60
68
  end
61
69
  output
62
70
  end
63
71
 
72
+ #run all items and raise an exception if exit_code is nonzero
73
+ def execute!(joined_by = " && ")
74
+ execute( joined_by, true )
75
+ end
76
+
64
77
  # Run all of the items in the commands hash
65
78
  # The joined_by paramenter dictates how to join the commands before execution
66
79
  # Returns: A hash of the responses for each specified host
67
- def execute(joined_by = " && ")
80
+ def execute(joined_by = " && ", raise_exceptions=false)
68
81
  run_me = @commands.join(joined_by)
69
82
  output = {}
70
83
 
@@ -72,30 +85,54 @@ module Elsewhere
72
85
  gateway_wrapper.ssh(host, @user, {:forward_agent => true}) do |gateway|
73
86
  @hosts.uniq.each do |h|
74
87
  gateway.ssh(host, options[:gateway_user], {:forward_agent => true}) do |ssh|
75
- output[h] = execute_over_ssh(ssh, run_me)
88
+ output[h] = execute_over_ssh(ssh, run_me,raise_exceptions)
76
89
  end
77
90
  end
78
91
  end
79
92
  else
80
- @hosts.uniq.each{ |h| output[h] = ssh_wrapper(h,run_me) }
93
+ @hosts.uniq.each{ |h| output[h] = ssh_wrapper(h,run_me,raise_exceptions) }
81
94
  end
82
95
 
83
96
  return output
84
97
  end
85
98
 
86
- #execute the given commend for the Net::SSH instance
99
+ #execute the given command set for the Net::SSH instance
87
100
  #return the data or raise an error depending on which stream is returned
88
- def execute_over_ssh(ssh,command)
89
- stdout = ""
90
- ssh.exec!(command) do |channel,stream,data|
91
- case stream
92
- when :stderr
93
- raise RemoteRunError, data
94
- else
95
- stdout = data
96
- end
97
- end
98
- return stdout
101
+ def execute_over_ssh(ssh,command,raise_exceptions)
102
+ stdout = ""
103
+ stderr = ""
104
+ exit_code = nil
105
+ channel = ssh.open_channel do |channel|
106
+
107
+ channel.exec(command) do |channel, success|
108
+ channel.on_data do |ch,data|
109
+ stdout = data
110
+ end
111
+
112
+ channel.on_extended_data do |ch, type, data|
113
+ stderr = data
114
+ end
115
+
116
+ channel.on_close do |ch|
117
+ #when channel closes
118
+ #TODO: Implement callback here
119
+ end
120
+
121
+ channel.on_request "exit-status" do |channel, data|
122
+ exit_code = data.read_long
123
+ end
124
+
125
+ end
126
+ end
127
+
128
+ ssh.loop
129
+
130
+ #we want to raise any non zero exit codes
131
+ unless ( exit_code == 0 && raise_exceptions )
132
+ raise RemoteRunError, "#{stderr} - Exit Code: #{exit_code}"
133
+ else
134
+ return stdout
135
+ end
99
136
  end
100
137
 
101
138
 
@@ -103,9 +140,11 @@ module Elsewhere
103
140
  end
104
141
 
105
142
  if __FILE__ == $0
106
- host = ""
107
- user = ""
108
- r = RemoteRun.new(host,user)
109
- r.commands << "ls"
143
+ host = "wa-app-q0"
144
+ user = "wa-current"
145
+ r = Elsewhere::RemoteRun.new(host,user)
146
+ r.commands << "source /etc/profile"
147
+ r.commands << "cd ~/current"
148
+ r.commands << "bundle exec rake --trace transformer:run cas=3 queue=solo remote_run_id=1 ddcid=2013 exit=true RAILS_ENV=qa"
110
149
  puts r.execute
111
150
  end
@@ -1,3 +1,3 @@
1
1
  module Elsewhere
2
- VERSION = "0.5"
2
+ VERSION = "0.6"
3
3
  end
@@ -0,0 +1,10 @@
1
+ test:
2
+ test_group:
3
+ host: www.example.com
4
+ user: test_user
5
+ test_group_with_gateway:
6
+ host: www.example.com
7
+ user: test_user
8
+ gateway:
9
+ host: www.examplegateway.com
10
+ user: test_user
@@ -0,0 +1,34 @@
1
+ require 'minitest/autorun'
2
+ require 'elsewhere'
3
+
4
+ class TestRemoteRun < MiniTest::Unit::TestCase
5
+
6
+ def setup
7
+ @user = "test_user"
8
+ @hosts = %w{ www.example.com }
9
+ @gateway = "www.examplegateway.com"
10
+ @gateway_user = "test_user"
11
+
12
+ @config = Dir.pwd + "/tests/test_config.yml"
13
+ @remote_run = Elsewhere::RemoteRun.initialize_from_config(@config, 'test', 'test_group')
14
+ @remote_run_with_gateway = Elsewhere::RemoteRun.initialize_from_config(@config, 'test', 'test_group_with_gateway')
15
+
16
+ end
17
+
18
+ def test_hosts_are_set_from_initialized_config
19
+ assert_equal @hosts , @remote_run.hosts
20
+ end
21
+
22
+ def test_user_is_set_from_initialized_config
23
+ assert_equal @user, @remote_run.user
24
+ end
25
+
26
+ def test_gateway_is_set_from_initialized_config
27
+ assert_equal @gateway, @remote_run_with_gateway.gateway_address
28
+ end
29
+
30
+ def test_gateway_user_is_set_from_initialized_config
31
+ assert_equal @gateway_user, @remote_run_with_gateway.gateway_user
32
+ end
33
+
34
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elsewhere
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.5'
4
+ version: '0.6'
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: 2012-05-01 00:00:00.000000000Z
12
+ date: 2012-05-08 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
16
- requirement: &2160742620 !ruby/object:Gem::Requirement
16
+ requirement: &2168858640 !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: :development
23
23
  prerelease: false
24
- version_requirements: *2160742620
24
+ version_requirements: *2168858640
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: net-ssh
27
- requirement: &2160742200 !ruby/object:Gem::Requirement
27
+ requirement: &2168858200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2160742200
35
+ version_requirements: *2168858200
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: net-ssh-gateway
38
- requirement: &2160741780 !ruby/object:Gem::Requirement
38
+ requirement: &2168857760 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2160741780
46
+ version_requirements: *2168857760
47
47
  description: ! ' Yet another way to run stuff remotely '
48
48
  email:
49
49
  - bchapman@academicmanagement.com
@@ -59,7 +59,9 @@ files:
59
59
  - lib/elsewhere.rb
60
60
  - lib/elsewhere/remote_run.rb
61
61
  - lib/elsewhere/version.rb
62
- homepage: ''
62
+ - tests/test_config.yml
63
+ - tests/test_remote_run.rb
64
+ homepage: https://github.com/byllc/elsewhere
63
65
  licenses: []
64
66
  post_install_message:
65
67
  rdoc_options: []
@@ -79,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
81
  version: '0'
80
82
  requirements: []
81
83
  rubyforge_project: elsewhere
82
- rubygems_version: 1.8.10
84
+ rubygems_version: 1.8.17
83
85
  signing_key:
84
86
  specification_version: 3
85
87
  summary: Simple wrapper for Net SSH to run a list of commands remotely