runsible 0.1.2.1 → 0.1.3.1

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