elsewhere 0.5 → 0.6

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/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