runsible 0.1.2.1 → 0.1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/runsible +1 -1
  4. data/lib/runsible.rb +92 -68
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8eddd85cd8f461bb7429cc4ec8b791426abfa579
4
- data.tar.gz: d0f88b818945461a24e13825fc1ca0494a294dd6
3
+ metadata.gz: f31a8f06a0427b8f580a9240bc5698bc87e1b439
4
+ data.tar.gz: bf3daedd7b2e648992ced1ea3ec8140f83e9f30c
5
5
  SHA512:
6
- metadata.gz: fe055d42239b15ff92f99ecce93a17a3291a542c83e27d3c9b7eb1855fdc28fc0650c1e1f774c6fe51c88936516ccb4d2480098756978805b5752b88b576b880
7
- data.tar.gz: 3f41d2e3a40e9ff47e054a8da23314f228453b1d5b9e9d17b868aa20ff06700f5d4fc9b0c74d764ac08aff555f00461665fbdda1442de7a1cc7e0bbb01e67810
6
+ metadata.gz: 3c43fd82babf3dd5630fa2d1e69b82ff141a33ac23781b670a51d50e893e5313f8ad45305de6f9cd779176e720cf047e9c25866b8b66e59a5eebd6e79665b230
7
+ data.tar.gz: 539a72b37cab94eba245b16fdd5d67bbd31ade5cecadd84cd10f34a5457a29b3a3eca3b4085c1ec5c8b3f865fef52cd515ace50f45e5ee92a27cd6e455617823
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2.1
1
+ 0.1.3.1
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'runsible'
4
4
 
5
- Runsible.run
5
+ Runsible.spoon
@@ -18,8 +18,8 @@ end
18
18
  # STDOUT and STDERR
19
19
  #
20
20
  module Runsible
21
- SSH_CNX_TIMEOUT = 10
22
21
  class Error < RuntimeError; end
22
+ SSH_CNX_TIMEOUT = 10
23
23
 
24
24
  SETTINGS = {
25
25
  user: ENV['USER'],
@@ -29,6 +29,10 @@ module Runsible
29
29
  vars: [],
30
30
  }
31
31
 
32
+ #
33
+ # Utility stuff
34
+ #
35
+
32
36
  def self.default_settings
33
37
  hsh = {}
34
38
  SETTINGS.each { |sym, v|
@@ -48,32 +52,58 @@ module Runsible
48
52
  exit 1
49
53
  end
50
54
 
51
- def self.run(ssh_options = Hash.new)
52
- opts = Runsible.slop_parse
53
- Runsible.spoon(opts, self.extract_yaml(opts), ssh_options)
55
+ def self.alert(topic, message, settings)
56
+ backend = settings['alerts'] && settings['alerts']['backend']
57
+ case backend
58
+ when 'disabled', nil, false
59
+ return
60
+ when 'email'
61
+ Pony.mail(to: settings.fetch(:address),
62
+ from: 'runsible@spoon',
63
+ subject: topic,
64
+ body: message)
65
+ when 'kafka', 'slack'
66
+ # TODO
67
+ raise Error, "unsupported backend: #{backend.inspect}"
68
+ else
69
+ raise Error, "unknown backend: #{backend.inspect}"
70
+ end
54
71
  end
55
72
 
56
- def self.extract_yaml(opts)
57
- yaml_filename = opts.arguments.shift
58
- self.usage(opts, "yaml_file is required") if yaml_filename.nil?
73
+ def self.warn(msg)
74
+ $stdout.puts msg
75
+ $stderr.puts msg
76
+ end
59
77
 
60
- begin
61
- yaml = YAML.load_file(yaml_filename)
62
- rescue RuntimeError => e
63
- Runsible.usage(opts, "could not load yaml_file\n#{e}")
64
- end
65
- yaml
78
+ def self.die!(msg, settings)
79
+ self.warn(msg)
80
+ self.alert("runsible:fatal:#{Process.pid}", msg, settings)
81
+ exit 1
82
+ end
83
+
84
+
85
+ #
86
+ # CLI or bin/runsible stuff
87
+ #
88
+
89
+ # bin/runsible entry point
90
+ def self.spoon(ssh_options = Hash.new)
91
+ opts = Runsible.slop_parse
92
+ yaml = self.extract_yaml(opts)
93
+ settings = Runsible.default_settings.merge(yaml['settings'] || Hash.new)
94
+ settings = self.merge(opts, settings)
95
+ self.ssh_runlist(settings, yaml['runlist'] || Array.new, ssh_options, yaml)
66
96
  end
67
97
 
68
98
  def self.slop_parse
69
- d = SETTINGS
99
+ d = SETTINGS # display defaults
70
100
  Slop.parse do |o|
71
101
  o.banner = "usage: runsible [options] yaml_file"
72
102
  o.on '-h', '--help' do
73
103
  puts o
74
104
  exit 0
75
105
  end
76
- o.on '-v', '--version', 'show Runsible version' do
106
+ o.on '-v', '--version', 'show runsible version' do
77
107
  puts Runsible.version
78
108
  exit 0
79
109
  end
@@ -89,43 +119,30 @@ module Runsible
89
119
  end
90
120
  end
91
121
 
92
- def self.merge(opts, settings)
93
- Runsible::SETTINGS.keys.each { |sym|
94
- settings[sym.to_s] = opts[sym] if opts[sym]
95
- }
96
- settings['alerts'] = {} if opts.silent?
97
- settings
98
- end
122
+ def self.extract_yaml(opts)
123
+ yaml_filename = opts.arguments.shift
124
+ self.usage(opts, "yaml_file is required") if yaml_filename.nil?
99
125
 
100
- def self.alert(topic, message, settings)
101
- backend = settings['alerts'] && settings['alerts']['backend']
102
- case backend
103
- when 'disabled', nil, false
104
- return
105
- when 'email'
106
- Pony.mail(to: settings.fetch(:address),
107
- from: 'runsible@spoon',
108
- subject: topic,
109
- body: message)
110
- when 'kafka', 'slack'
111
- # TODO
112
- raise Error, "unsupported backend: #{backend.inspect}"
113
- else
114
- raise Error, "unknown backend: #{backend.inspect}"
126
+ begin
127
+ yaml = YAML.load_file(yaml_filename)
128
+ rescue RuntimeError => e
129
+ Runsible.usage(opts, "could not load yaml_file\n#{e}")
115
130
  end
131
+ yaml
116
132
  end
117
133
 
118
- def self.warn(msg)
119
- $stdout.puts msg
120
- $stderr.puts msg
121
- end
134
+ #
135
+ # Library stuff
136
+ #
122
137
 
123
- def self.spoon(opts, yaml, ssh_options = Hash.new)
124
- settings = Runsible.default_settings.merge(yaml['settings'] || Hash.new)
125
- settings = self.merge(opts, settings)
126
- self.ssh_runlist(settings, yaml['runlist'] || Array.new, ssh_options, yaml)
138
+ # run a YAML file without any consideration for command line options
139
+ def self.run_yaml(yaml_filename, ssh_options = Hash.new)
140
+ yaml = YAML.load_file(yaml_filename)
141
+ self.ssh_runlist(self.default_settings, yaml['runlist'] || Array.new,
142
+ ssh_options, yaml)
127
143
  end
128
144
 
145
+ # initiate ssh connection, perform the runlist
129
146
  def self.ssh_runlist(settings, runlist, ssh_options, yaml)
130
147
  ssh_options[:forward_agent] ||= true
131
148
  ssh_options[:port] ||= settings.fetch('port')
@@ -137,12 +154,6 @@ module Runsible
137
154
  }
138
155
  end
139
156
 
140
- def self.die!(msg, settings)
141
- self.warn(msg)
142
- self.alert("runsible:fatal:#{Process.pid}", msg, settings)
143
- exit 1
144
- end
145
-
146
157
  # execute runlist with failure handling, retries, alerting, etc.
147
158
  def self.exec_runlist(ssh, runlist, settings, yaml = Hash.new)
148
159
  runlist.each { |run|
@@ -177,6 +188,26 @@ module Runsible
177
188
  }
178
189
  end
179
190
 
191
+ # retry several times, rescuing CommandFailure
192
+ # raises on SSH channel exec failure and CommandFailure on final retry
193
+ def self.exec_retry(ssh, cmd, retries)
194
+ self.banner_wrap(cmd) {
195
+ success = false
196
+ retries.times { |i|
197
+ begin
198
+ success = self.exec(ssh, cmd)
199
+ break
200
+ rescue CommandFailure => e
201
+ $stdout.puts "#{e}; retrying shortly..."
202
+ $stderr.puts e
203
+ sleep 2
204
+ end
205
+ }
206
+ # the final retry, may blow up
207
+ success or self.exec(ssh, cmd)
208
+ }
209
+ end
210
+
180
211
  # prints remote STDOUT to local STDOUT, likewise for STDERR
181
212
  # raises on SSH channel exec failure or nonzero exit status
182
213
  def self.exec(ssh, cmd)
@@ -199,24 +230,17 @@ module Runsible
199
230
  exit_code == 0 or raise(CommandFailure, "[exit #{exit_code}] #{cmd}")
200
231
  end
201
232
 
202
- # retry several times, rescuing CommandFailure
203
- # raises on SSH channel exec failure and CommandFailure on final retry
204
- def self.exec_retry(ssh, cmd, retries)
205
- self.banner_wrap(cmd) {
206
- success = false
207
- retries.times { |i|
208
- begin
209
- success = self.exec(ssh, cmd)
210
- break
211
- rescue CommandFailure => e
212
- $stdout.puts "#{e}; retrying shortly..."
213
- $stderr.puts e
214
- sleep 2
215
- end
216
- }
217
- # the final retry, may blow up
218
- success or self.exec(ssh, cmd)
233
+
234
+ #
235
+ # Necessities
236
+ #
237
+
238
+ def self.merge(opts, settings)
239
+ Runsible::SETTINGS.keys.each { |sym|
240
+ settings[sym.to_s] = opts[sym] if opts[sym]
219
241
  }
242
+ settings['alerts'] = {} if opts.silent?
243
+ settings
220
244
  end
221
245
 
222
246
  def self.begin_banner(msg)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runsible
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.1
4
+ version: 0.1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rick Hull