qb 0.3.4 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0f1763e51cce156edf9e27cd1d09a3dce94e198
4
- data.tar.gz: '0875a043b64932a4ae624da6014ac4658229b5b3'
3
+ metadata.gz: 3cc2ccebba574aaa719a3f5705ac941e114de2a2
4
+ data.tar.gz: 100bf8785c271ba8b63c1c2214680c9427cb25f7
5
5
  SHA512:
6
- metadata.gz: 412955a91081d001642b31bb9f904ed48d2d27ff876b34525fe572276283ac23babd8f11604b4a1571ca4bc8668712e8846c83cd788f0c6696e49ccff348d31e
7
- data.tar.gz: 3e07786f03ae3d13a9eefb3ae74bd070c22af29dd844d0b807bc2152b1d16f8559d70e1de4d84aa6ab0a1bc8af3532d5aac84a4e1814351b8cf439342670b42e
6
+ metadata.gz: 1d6c107058949f748322c628a0197929c63aba877810142463e9d59f955a91847985ba53a9cc4d1aece2e0f10fd860372ee15f999d6c36ed466bd352795a414d
7
+ data.tar.gz: 498ffac648a4c5e7bbe77710b58306f2d9a35744fe9bdfb27de65b819a1a17e4f6c65f7f13cf094a085a7ab9d692816639e18158adf562e93e1e1a7cd54898c6
@@ -1,5 +1,4 @@
1
1
  [defaults]
2
2
 
3
3
  roles_path = ./dev/scratch
4
- filter_plugins = ./roles/qb.gem/filter_plugins
5
4
  retry_files_enabled = False
data/exe/qb CHANGED
@@ -13,17 +13,9 @@ require 'qb'
13
13
  require 'nrser/refinements'
14
14
  using NRSER
15
15
 
16
- require 'nrser/refinements/types'
17
- using NRSER::Types
18
-
19
-
20
- # constants
21
- # =========
22
16
 
23
17
  DEBUG_ARGS = ['-D', '--DEBUG']
24
18
 
25
- # globals
26
- # =======
27
19
 
28
20
  def set_debug! args
29
21
  if DEBUG_ARGS.any? {|arg| args.include? arg}
@@ -33,31 +25,6 @@ def set_debug! args
33
25
  end
34
26
  end
35
27
 
36
- def metadata
37
- if QB.gemspec.metadata && !QB.gemspec.metadata.empty?
38
- "metadata:\n" + QB.gemspec.metadata.map {|key, value|
39
- " #{ key }: #{ value }"
40
- }.join("\n") + "\n"
41
- end
42
- end
43
-
44
- def help
45
- puts <<-END
46
- version: #{ QB::VERSION }
47
- #{ metadata }
48
- syntax:
49
-
50
- qb ROLE [OPTIONS] DIRECTORY
51
-
52
- use `qb ROLE -h` for role options.
53
-
54
- available roles:
55
-
56
- END
57
- puts QB::Role.available
58
- puts
59
- exit 1
60
- end
61
28
 
62
29
  def main args
63
30
  set_debug! args
@@ -65,283 +32,32 @@ def main args
65
32
 
66
33
  QB.check_ansible_version
67
34
 
68
- role_arg = args.shift
69
- QB.debug "role arg" => role_arg
70
-
71
- help if role_arg.nil? || ['-h', '--help', 'help'].include?(role_arg)
72
-
73
- return QB::CLI.play(args) if role_arg == 'play'
74
-
75
- begin
76
- role = QB::Role.require role_arg
77
- rescue QB::Role::NoMatchesError => e
78
- puts "ERROR - #{ e.message }\n\n"
79
- # exits with status code 1
80
- help
81
- rescue QB::Role::MultipleMatchesError => e
82
- puts "ERROR - #{ e.message }\n\n"
83
- exit 1
84
- end
85
-
86
- QB.check_qb_version role
87
-
88
- options = QB::Options.new role, args
89
-
90
- QB.debug "role options set on cli", options.role_options.select {|k, o|
91
- !o.value.nil?
92
- }
93
-
94
- QB.debug "qb options", options.qb
95
-
96
- cwd = Dir.getwd
97
-
98
- dir = nil
99
-
100
- unless role.meta['default_dir'] == false
101
- # get the target dir
102
- dir = case args.length
103
- when 0
104
- # in this case, a dir has not been provided
105
- #
106
- # in some cases (like projects) the dir can be figured out in other ways:
107
- #
108
-
109
- if options.ask?
110
- default = begin
111
- role.default_dir cwd, options.role_options
112
- rescue QB::UserInputError => e
113
- NRSER::NO_ARG
114
- end
115
-
116
- QB::CLI.ask name: "target directory (`qb_dir`)",
117
- type: t.non_empty_str,
118
- default: default
119
-
120
- else
121
- role.default_dir cwd, options.role_options
122
- end
123
-
124
- when 1
125
- # there is a single positional arg, which is used as dir
126
- args[0]
127
-
128
- else
129
- # there are multiple positional args, which is not allowed
130
- raise "can't supply more than one argument: #{ args.inspect }"
131
-
132
- end
133
-
134
- QB.debug "input_dir", dir
135
-
136
- # normalize to expanded path (has no trailing slash)
137
- dir = File.expand_path dir
138
-
139
- QB.debug "normalized_dir", dir
140
-
141
- # create the dir if it doesn't exist (so don't have to cover this in
142
- # every role)
143
- if role.mkdir
144
- FileUtils.mkdir_p dir unless File.exists? dir
35
+ QB.debug "Switch arg", args[0]
36
+
37
+ status = case args[0]
38
+ when nil, '-h', '--help', 'help'
39
+ QB::CLI.help
40
+ when 'play'
41
+ QB::CLI.play args.rest
42
+ when 'run'
43
+ QB::CLI.run args.rest
44
+ when 'setup'
45
+ state_args = args.rest
46
+
47
+ case state_args[0]
48
+ when nil
49
+ QB::CLI.setup
145
50
  end
146
-
147
- saved_options_path = Pathname.new(dir) + '.qb-options.yml'
148
-
149
- saved_options = if saved_options_path.exist?
150
- # convert old _ separated names to - separated
151
- YAML.load(saved_options_path.read).map {|role_options_key, role_options|
152
- [
153
- role_options_key,
154
- role_options.map {|name, value|
155
- [QB::Options.cli_ize_name(name), value]
156
- }.to_h
157
- ]
158
- }.to_h.tap {|saved_options|
159
- QB.debug "found saved options", saved_options
160
- }
161
- else
162
- QB.debug "no saved options"
163
- {}
164
- end
165
-
166
- if saved_options.key? role.options_key
167
- role_saved_options = saved_options[role.options_key]
168
-
169
- QB.debug "found saved options for role", role_saved_options
170
-
171
- role_saved_options.each do |option_cli_name, value|
172
- option = options.role_options[option_cli_name]
173
-
174
- if option.value.nil?
175
- QB.debug "setting from saved options", option: option, value: value
176
-
177
- option.value = value
178
- end
179
- end
180
- end
181
- end # unless default_dir == false
182
-
183
-
184
- # Interactive Input
185
- # =====================================================================
186
-
187
- if options.ask?
188
- # Incomplete
189
- raise "COMING SOON!!!...?"
190
- QB::CLI.ask_for_options role: role, options: options
191
- end
192
-
193
-
194
- # Validation
195
- # =====================================================================
196
- #
197
- # Should have already been taken care of if we used interactive input.
198
- #
199
-
200
- # check that required options are present
201
- missing = options.role_options.values.select {|option|
202
- option.required? && option.value.nil?
203
- }
204
-
205
- unless missing.empty?
206
- puts "ERROR: options #{ missing.map {|o| o.cli_name } } are required."
207
- exit 1
51
+ else
52
+ # default to `run` on the full args
53
+ QB::CLI.run args
208
54
  end
209
55
 
210
- set_options = options.role_options.select {|k, o| !o.value.nil?}
56
+ QB.debug "Exit status", status
211
57
 
212
- QB.debug "set options", set_options
213
-
214
- playbook_role = {'role' => role.name}
215
-
216
- playbook_vars = {
217
- 'qb_dir' => dir,
218
- # depreciated due to mass potential for conflict
219
- 'dir' => dir,
220
- 'qb_cwd' => cwd,
221
- 'qb_user_roles_dir' => QB::USER_ROLES_DIR.to_s,
222
- }
223
-
224
- set_options.values.each do |option|
225
- playbook_role[option.var_name] = option.value
226
- end
227
-
228
- play =
229
- {
230
- 'hosts' => options.qb['hosts'],
231
- 'vars' => playbook_vars,
232
- # 'gather_subset' => ['!all'],
233
- 'gather_facts' => options.qb['facts'],
234
- 'pre_tasks' => [
235
- {
236
- 'qb_facts' => {
237
- 'qb_dir' => dir,
238
- }
239
- },
240
- ],
241
- 'roles' => [
242
- 'nrser.blockinfile',
243
- playbook_role
244
- ],
245
- }
246
-
247
- if options.qb['user']
248
- play['become'] = true
249
- play['become_user'] = options.qb['user']
250
- end
251
-
252
- playbook = [play]
253
-
254
- QB.debug "playbook", playbook
255
-
256
- env = QB::Ansible::Env.new
257
-
258
- # stick the role path in front to make sure we get **that** role
259
- env.roles_path.unshift role.path.expand_path.dirname
260
-
261
- cmd = QB::Ansible::Cmds::Playbook.new \
262
- env: env,
263
- playbook: playbook,
264
- role_options: options,
265
- chdir: (File.exists?('./ansible/ansible.cfg') ? './ansible' : nil)
266
-
267
- # print
268
- # =====
269
- #
270
- # print useful stuff for debugging / running outside of qb
271
- #
272
-
273
- if options.qb['print'].include? 'options'
274
- puts "SET OPTIONS:\n\n#{ YAML.dump set_options }\n\n"
275
- end
276
-
277
- if options.qb['print'].include? 'env'
278
- puts "ENV:\n\n#{ YAML.dump cmd.env.to_h }\n\n"
279
- end
280
-
281
- if options.qb['print'].include? 'cmd'
282
- puts "COMMAND:\n\n#{ cmd.prepare }\n\n"
283
- end
284
-
285
- if options.qb['print'].include? 'playbook'
286
- puts "PLAYBOOK:\n\n#{ YAML.dump playbook }\n\n"
287
- end
288
-
289
- # stop here if we're not supposed to run
290
- exit 0 if !options.qb['run']
291
-
292
- # run
293
- # ===
294
- #
295
- # stuff below here does stuff
296
- #
297
-
298
- # save the options back
299
- if (
300
- dir &&
301
- # we set some options that we can save
302
- set_options.values.select {|o| o.save? }.length > 0 &&
303
- # the role says to save options
304
- role.save_options
305
- )
306
- saved_options[role.options_key] = set_options.select{|key, option|
307
- option.save?
308
- }.map {|key, option|
309
- [key, option.value]
310
- }.to_h
311
-
312
- unless saved_options_path.dirname.exist?
313
- FileUtils.mkdir_p saved_options_path.dirname
314
- end
315
-
316
- saved_options_path.open('w') do |f|
317
- f.write YAML.dump(saved_options)
318
- end
319
- end
320
-
321
- QB::Util::Bundler.with_clean_env do
322
- # boot up stdio out services so that ansible modules can stream to our
323
- # stdout and stderr to print stuff (including debug lines) in real-time
324
- stdio_out_services = {'out' => $stdout, 'err' => $stderr}.
325
- map {|name, dest|
326
- QB::Util::STDIO::OutService.new(name, dest).tap { |s| s.open! }
327
- }
328
-
329
- # and an in service so that modules can prompt for user input
330
- user_in_service = QB::Util::STDIO::InService.new('in', $stdin).
331
- tap { |s| s.open! }
332
-
333
- status = cmd.stream
334
-
335
- # close the stdio services
336
- stdio_out_services.each {|s| s.close! }
337
- user_in_service.close!
338
-
339
- if status != 0
340
- $stderr.puts "ERROR ansible-playbook failed."
341
- end
342
-
343
- exit status
344
- end
58
+ # exit status
59
+ exit status
345
60
  end
346
61
 
62
+
347
63
  main(ARGV) # if __FILE__ == $0 # doesn't work with gem stub or something?
@@ -7,13 +7,18 @@ require 'yaml'
7
7
  # deps
8
8
  require 'cmds'
9
9
 
10
+ # package
11
+ require 'qb/util/bundler'
12
+ require 'qb/util/stdio'
13
+
10
14
 
11
15
  module QB; end
12
16
  module QB::Ansible; end
13
17
  module QB::Ansible::Cmds; end
14
18
 
15
19
 
16
- # @todo document QB::Ansible::Playbook class.
20
+ # A command object that runs a playbook with all the QB specialness.
21
+ #
17
22
  class QB::Ansible::Cmds::Playbook < ::Cmds
18
23
  DEFAULT_PLAYBOOK_PATH = '.qb-playbook.yml'
19
24
 
@@ -82,19 +87,36 @@ class QB::Ansible::Cmds::Playbook < ::Cmds
82
87
  attr_reader :role_options
83
88
 
84
89
 
90
+ # Hash of extra variables that will be JSON encoded and passed to
91
+ # `ansible-playbook` via the `--extra-vars` CLI option.
92
+ #
93
+ # @return [Hash]
94
+ #
95
+ attr_reader :extra_vars
96
+
97
+
85
98
  # Constructor
86
99
  # ======================================================================
87
100
 
88
101
  # Instantiate a new `QB::Ansible::Playbook`.
89
- def initialize playbook_path: DEFAULT_PLAYBOOK_PATH,
90
- playbook: nil,
91
- role_options: nil,
92
- exe: DEFAULT_EXE,
102
+ #
103
+ # @param [Hash] extra_vars:
104
+ # Extra variables that will be JSON encoded and passed to
105
+ # `ansible-playbook` via the `--extra-vars` option.
106
+ #
107
+ # Available as the {#extra_vars} attribute.
108
+ #
109
+ def initialize chdir: nil,
93
110
  env: QB::Ansible::Env.new,
111
+ exe: DEFAULT_EXE,
112
+ extra_vars: {},
94
113
  format: :pretty,
95
- chdir: nil,
114
+ playbook: nil,
115
+ playbook_path: DEFAULT_PLAYBOOK_PATH,
116
+ role_options: nil,
96
117
  **other_cmds_opts
97
118
  @exe = exe.to_s
119
+ @extra_vars = extra_vars
98
120
  @role_options = role_options
99
121
  @playbook = playbook
100
122
 
@@ -140,6 +162,11 @@ class QB::Ansible::Cmds::Playbook < ::Cmds
140
162
  cmd_options['inventory-file'] = play['hosts']
141
163
  end
142
164
 
165
+ # Add extra vars if we have any.
166
+ unless @extra_vars.empty?
167
+ cmd_options['extra-vars'] = JSON.dump @extra_vars
168
+ end
169
+
143
170
  cmd_options
144
171
  end # cmd_options
145
172
 
@@ -182,10 +209,34 @@ class QB::Ansible::Cmds::Playbook < ::Cmds
182
209
  protected
183
210
  # ========================================================================
184
211
 
212
+ # @return [Fixnum]
213
+ #
185
214
  def spawn *args, **kwds, &input_block
186
215
  before_spawn
187
- super *args, **kwds, &input_block
188
- end
216
+
217
+ QB::Util::Bundler.with_clean_env do
218
+ # boot up stdio out services so that ansible modules can stream to our
219
+ # stdout and stderr to print stuff (including debug lines) in real-time
220
+ stdio_out_services = {'out' => $stdout, 'err' => $stderr}.
221
+ map {|name, dest|
222
+ QB::Util::STDIO::OutService.new(name, dest).tap { |s| s.open! }
223
+ }
224
+
225
+ # and an in service so that modules can prompt for user input
226
+ user_in_service = QB::Util::STDIO::InService.new('in', $stdin).
227
+ tap { |s| s.open! }
228
+
229
+ status = super *args, **kwds, &input_block
230
+
231
+ # close the stdio services
232
+ stdio_out_services.each {|s| s.close! }
233
+ user_in_service.close!
234
+
235
+ # and return the status
236
+ status
237
+ end
238
+
239
+ end # #spawn
189
240
 
190
241
  # end protected
191
242