qb 0.3.3 → 0.3.4
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 +4 -4
- data/exe/qb +10 -91
- data/lib/qb/ansible.rb +2 -0
- data/lib/qb/ansible/cmds/playbook.rb +193 -0
- data/lib/qb/ansible/config_file.rb +10 -5
- data/lib/qb/ansible/env.rb +63 -3
- data/lib/qb/ansible/module.rb +194 -0
- data/lib/qb/ansible_module.rb +2 -182
- data/lib/qb/cli/play.rb +28 -2
- data/lib/qb/cli/run.rb +0 -0
- data/lib/qb/role.rb +1 -1
- data/lib/qb/util.rb +21 -5
- data/lib/qb/util/stdio.rb +52 -0
- data/lib/qb/version.rb +1 -1
- data/library/path_facts +1 -1
- data/library/stream +1 -1
- data/node_modules/.bin/semver +1 -1
- data/qb.gemspec +2 -2
- data/roles/nrser.blockinfile/tests/expected/test-follow/link2.txt +1 -1
- data/roles/nrser.blockinfile/tests/fixtures/test-follow/link0.txt +1 -1
- data/roles/nrser.blockinfile/tests/fixtures/test-follow/link1.txt +1 -1
- data/roles/nrser.blockinfile/tests/fixtures/test-follow/link2.txt +1 -1
- data/roles/nrser.blockinfile/tests/roles/yaegashi.blockinfile +1 -1
- data/roles/qb.bump/library/bump +2 -2
- data/roles/qb.git_submodule_update/library/git_submodule_update +1 -1
- data/roles/qb.gitignore/files/gitignore/Clojure.gitignore +1 -1
- data/roles/qb.gitignore/files/gitignore/Fortran.gitignore +1 -1
- data/roles/qb.role/meta/qb.yml +1 -1
- data/roles/qb.role/templates/library/module.rb.j2 +1 -1
- data/roles/qb/gem/release/tasks/main.yml +98 -39
- metadata +10 -8
- data/lib/qb/ansible/playbook.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0f1763e51cce156edf9e27cd1d09a3dce94e198
|
4
|
+
data.tar.gz: '0875a043b64932a4ae624da6014ac4658229b5b3'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 412955a91081d001642b31bb9f904ed48d2d27ff876b34525fe572276283ac23babd8f11604b4a1571ca4bc8668712e8846c83cd788f0c6696e49ccff348d31e
|
7
|
+
data.tar.gz: 3e07786f03ae3d13a9eefb3ae74bd070c22af29dd844d0b807bc2152b1d16f8559d70e1de4d84aa6ab0a1bc8af3532d5aac84a4e1814351b8cf439342670b42e
|
data/exe/qb
CHANGED
@@ -253,92 +253,16 @@ def main args
|
|
253
253
|
|
254
254
|
QB.debug "playbook", playbook
|
255
255
|
|
256
|
-
|
257
|
-
QB.debug playbook_path: playbook_path.to_s
|
256
|
+
env = QB::Ansible::Env.new
|
258
257
|
|
259
|
-
|
260
|
-
|
261
|
-
# stick the role path in front to make sure we get **that** role
|
262
|
-
role.path.expand_path.dirname,
|
263
|
-
|
264
|
-
# then include the full role search path
|
265
|
-
|
266
|
-
# NOTE this includes role paths pulled from a call-site local
|
267
|
-
# ansible.cfg
|
268
|
-
QB::Role.search_path,
|
269
|
-
].
|
270
|
-
flatten. # since QB::Role.search_path is an Array
|
271
|
-
select(&:directory?).
|
272
|
-
map(&:realpath). # so uniq works
|
273
|
-
uniq, # drop dups (seems to keep first instance so preserves priority)
|
274
|
-
|
275
|
-
ANSIBLE_LIBRARY: [
|
276
|
-
QB::ROOT.join('library'),
|
277
|
-
],
|
278
|
-
|
279
|
-
ANSIBLE_FILTER_PLUGINS: [
|
280
|
-
QB::ROOT.join('plugins', 'filter_plugins'),
|
281
|
-
],
|
282
|
-
|
283
|
-
ANSIBLE_LOOKUP_PLUGINS: [
|
284
|
-
QB::ROOT.join('plugins', 'lookup_plugins'),
|
285
|
-
],
|
286
|
-
}
|
287
|
-
|
288
|
-
cmd_options = options.ansible.clone
|
258
|
+
# stick the role path in front to make sure we get **that** role
|
259
|
+
env.roles_path.unshift role.path.expand_path.dirname
|
289
260
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
end
|
297
|
-
|
298
|
-
if options.qb['tags']
|
299
|
-
cmd_options['tags'] = options.qb['tags']
|
300
|
-
end
|
301
|
-
|
302
|
-
cmd_template = <<-END
|
303
|
-
ansible-playbook
|
304
|
-
|
305
|
-
<%= cmd_options %>
|
306
|
-
|
307
|
-
<% if verbose %>
|
308
|
-
-<%= 'v' * verbose %>
|
309
|
-
<% end %>
|
310
|
-
|
311
|
-
<%= playbook_path %>
|
312
|
-
END
|
313
|
-
|
314
|
-
cmd_options = {
|
315
|
-
env: env.map {|k, v| [k, v.is_a?(Array) ? v.join(':') : v]}.to_h,
|
316
|
-
|
317
|
-
kwds: {
|
318
|
-
cmd_options: cmd_options,
|
319
|
-
|
320
|
-
verbose: options.qb['verbose'],
|
321
|
-
|
322
|
-
playbook_path: playbook_path.to_s,
|
323
|
-
},
|
324
|
-
|
325
|
-
format: :pretty,
|
326
|
-
}
|
327
|
-
|
328
|
-
# If ./ansible/ansible.cfg exists chdir into there for the run.
|
329
|
-
#
|
330
|
-
# We already look for that dir and add the role paths to the role path
|
331
|
-
# specified to `ansible-playbook`, but though there might be a way to make
|
332
|
-
# `ansible-playbook` perform as desired while retaining the current directory
|
333
|
-
# (which would be preferable - I don't like switching directories on people)
|
334
|
-
# for the moment it seems like the easiest way to get it to properly use
|
335
|
-
# things like vars and relative paths in `./ansible/ansible.cfg` is to
|
336
|
-
# change directories into `./ansible`, so that's what we're doing here:
|
337
|
-
if File.exists? './ansible/ansible.cfg'
|
338
|
-
cmd_options[:chdir] = './ansible'
|
339
|
-
end
|
340
|
-
|
341
|
-
cmd = Cmds.new cmd_template, cmd_options
|
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)
|
342
266
|
|
343
267
|
# print
|
344
268
|
# =====
|
@@ -351,8 +275,7 @@ def main args
|
|
351
275
|
end
|
352
276
|
|
353
277
|
if options.qb['print'].include? 'env'
|
354
|
-
|
355
|
-
puts "ENV:\n\n#{ dump }\n\n"
|
278
|
+
puts "ENV:\n\n#{ YAML.dump cmd.env.to_h }\n\n"
|
356
279
|
end
|
357
280
|
|
358
281
|
if options.qb['print'].include? 'cmd'
|
@@ -372,10 +295,6 @@ def main args
|
|
372
295
|
# stuff below here does stuff
|
373
296
|
#
|
374
297
|
|
375
|
-
playbook_path.open('w') do |f|
|
376
|
-
f.write YAML.dump(playbook)
|
377
|
-
end
|
378
|
-
|
379
298
|
# save the options back
|
380
299
|
if (
|
381
300
|
dir &&
|
@@ -418,7 +337,7 @@ def main args
|
|
418
337
|
user_in_service.close!
|
419
338
|
|
420
339
|
if status != 0
|
421
|
-
puts "ERROR ansible-playbook failed."
|
340
|
+
$stderr.puts "ERROR ansible-playbook failed."
|
422
341
|
end
|
423
342
|
|
424
343
|
exit status
|
data/lib/qb/ansible.rb
CHANGED
@@ -0,0 +1,193 @@
|
|
1
|
+
# Requirements
|
2
|
+
# =====================================================================
|
3
|
+
|
4
|
+
# stdlib
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
# deps
|
8
|
+
require 'cmds'
|
9
|
+
|
10
|
+
|
11
|
+
module QB; end
|
12
|
+
module QB::Ansible; end
|
13
|
+
module QB::Ansible::Cmds; end
|
14
|
+
|
15
|
+
|
16
|
+
# @todo document QB::Ansible::Playbook class.
|
17
|
+
class QB::Ansible::Cmds::Playbook < ::Cmds
|
18
|
+
DEFAULT_PLAYBOOK_PATH = '.qb-playbook.yml'
|
19
|
+
|
20
|
+
# Default executable to use, just uses a bare `ansible-playbook`, letting
|
21
|
+
# shell path resolution do it's thing.
|
22
|
+
DEFAULT_EXE = 'ansible-playbook'
|
23
|
+
|
24
|
+
TEMPLATE = <<-END
|
25
|
+
<%= exe %>
|
26
|
+
|
27
|
+
<%= cmd_options %>
|
28
|
+
|
29
|
+
<% if verbose %>
|
30
|
+
-<%= 'v' * verbose %>
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
<%= playbook_path %>
|
34
|
+
END
|
35
|
+
|
36
|
+
# Constants
|
37
|
+
# ======================================================================
|
38
|
+
|
39
|
+
|
40
|
+
# Class Methods
|
41
|
+
# ======================================================================
|
42
|
+
|
43
|
+
|
44
|
+
# Attributes
|
45
|
+
# ======================================================================
|
46
|
+
|
47
|
+
# Path to the playbook. If a `playbook:` keyword argument is provided to
|
48
|
+
# the constructor, then this is the path it will be written to before
|
49
|
+
#
|
50
|
+
# @return [String, Pathname]
|
51
|
+
#
|
52
|
+
attr_reader :playbook_path
|
53
|
+
|
54
|
+
|
55
|
+
# Whatever to use for the `ansible-playbook` executable.
|
56
|
+
#
|
57
|
+
# @return [String]
|
58
|
+
#
|
59
|
+
attr_reader :exe
|
60
|
+
|
61
|
+
|
62
|
+
# Optional playbook object to write and run.
|
63
|
+
#
|
64
|
+
# @return [nil]
|
65
|
+
# If we should expect to find the playbook already at {#playbook_path}.
|
66
|
+
#
|
67
|
+
# @return [Hash]
|
68
|
+
# If we will be writing a YAML dump of this object to {#playbook_path}
|
69
|
+
# before runnning.
|
70
|
+
#
|
71
|
+
attr_reader :playbook
|
72
|
+
|
73
|
+
|
74
|
+
# Optional role options if running a role.
|
75
|
+
#
|
76
|
+
# @return [nil]
|
77
|
+
# If we're not running a role.
|
78
|
+
#
|
79
|
+
# @return [QB::Options]
|
80
|
+
# If we are running a role.
|
81
|
+
#
|
82
|
+
attr_reader :role_options
|
83
|
+
|
84
|
+
|
85
|
+
# Constructor
|
86
|
+
# ======================================================================
|
87
|
+
|
88
|
+
# 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,
|
93
|
+
env: QB::Ansible::Env.new,
|
94
|
+
format: :pretty,
|
95
|
+
chdir: nil,
|
96
|
+
**other_cmds_opts
|
97
|
+
@exe = exe.to_s
|
98
|
+
@role_options = role_options
|
99
|
+
@playbook = playbook
|
100
|
+
|
101
|
+
# Resolve whatever path we got to an absolute.
|
102
|
+
@playbook_path = QB::Util.resolve playbook_path
|
103
|
+
|
104
|
+
super TEMPLATE,
|
105
|
+
format: format,
|
106
|
+
chdir: chdir,
|
107
|
+
**other_cmds_opts
|
108
|
+
|
109
|
+
# Overwrite `@env` because `super` freezes it.
|
110
|
+
@env = env
|
111
|
+
end # #initialize
|
112
|
+
|
113
|
+
|
114
|
+
# Instance Methods
|
115
|
+
# ======================================================================
|
116
|
+
|
117
|
+
# @return [Hash<String => Object>]
|
118
|
+
# Hash of CLI options for `ansible-playbook` based off {#role_options}
|
119
|
+
# and {#playbook}.
|
120
|
+
#
|
121
|
+
def cmd_options
|
122
|
+
cmd_options = {}
|
123
|
+
|
124
|
+
if role_options
|
125
|
+
# Merge in any Ansible options collected.
|
126
|
+
cmd_options.merge! role_options.ansible
|
127
|
+
|
128
|
+
# Add tags if we have them
|
129
|
+
if role_options.qb['tags']
|
130
|
+
cmd_options['tags'] = role_options.qb['tags']
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Add inventory file if we have it in QB options for the role.
|
135
|
+
if role_options && role_options.qb['inventory']
|
136
|
+
cmd_options['inventory-file'] = role_options.qb['inventory']
|
137
|
+
elsif playbook && playbook[0]['hosts'] != ['localhost']
|
138
|
+
# TODO I'm not totally sure why this is here, but I copied it over from
|
139
|
+
# `//exe/qb`...? Get overridden below anyways if
|
140
|
+
cmd_options['inventory-file'] = play['hosts']
|
141
|
+
end
|
142
|
+
|
143
|
+
cmd_options
|
144
|
+
end # cmd_options
|
145
|
+
|
146
|
+
|
147
|
+
# Dynamically form the keywords from instance variables.
|
148
|
+
#
|
149
|
+
# @return [Hash{Symbol => Object}]
|
150
|
+
#
|
151
|
+
def kwds
|
152
|
+
{
|
153
|
+
exe: exe,
|
154
|
+
verbose: (role_options && role_options.qb['verbose']),
|
155
|
+
playbook_path: playbook_path.to_s,
|
156
|
+
cmd_options: cmd_options,
|
157
|
+
}
|
158
|
+
end # #kwds
|
159
|
+
|
160
|
+
|
161
|
+
# Override so we can call `#to_h` in case `env` is {QB::Ansible::Env}.
|
162
|
+
def env
|
163
|
+
@env.to_h
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
# Stuff to do before being run, like write {#playbook} to {#path} (unless
|
168
|
+
# {#playbook} is `nil`).
|
169
|
+
#
|
170
|
+
# @return [nil]
|
171
|
+
#
|
172
|
+
def before_spawn
|
173
|
+
# Write the playbook to the path first if one was provided.
|
174
|
+
unless playbook.nil?
|
175
|
+
playbook_path.open('w') { |f|
|
176
|
+
f.write YAML.dump(playbook)
|
177
|
+
}
|
178
|
+
end
|
179
|
+
end # #before_write
|
180
|
+
|
181
|
+
|
182
|
+
protected
|
183
|
+
# ========================================================================
|
184
|
+
|
185
|
+
def spawn *args, **kwds, &input_block
|
186
|
+
before_spawn
|
187
|
+
super *args, **kwds, &input_block
|
188
|
+
end
|
189
|
+
|
190
|
+
# end protected
|
191
|
+
|
192
|
+
end # class QB::Ansible::Playbook
|
193
|
+
|
@@ -95,17 +95,22 @@ class QB::Ansible::ConfigFile < ParseConfig
|
|
95
95
|
# =====================================================================
|
96
96
|
|
97
97
|
|
98
|
-
#
|
98
|
+
# Test if a file path *looks* like it points to an Ansible config file -
|
99
|
+
# a file with {FILE_NAME} as the basename.
|
100
|
+
#
|
101
|
+
# *Explicitly does not check if the file actually exists and is a file.*
|
102
|
+
# This is because we need this test to differentiate role search path
|
103
|
+
# elements that are meant to point to Ansible config files from those that
|
104
|
+
# aren't in {QB::Role.search_path}.
|
99
105
|
#
|
100
106
|
# @param [String, Pathname] file_path
|
101
107
|
#
|
102
|
-
#
|
103
108
|
# @return [Boolean]
|
104
|
-
# `true`
|
109
|
+
# `true` if `path`'s basename is {FILE_NAME}.
|
105
110
|
#
|
106
|
-
def self.
|
111
|
+
def self.end_with_config_file? file_path
|
107
112
|
File.basename(file_path).to_s == FILE_NAME
|
108
|
-
end # .
|
113
|
+
end # .end_with_config_file?
|
109
114
|
|
110
115
|
|
111
116
|
# Attributes
|
data/lib/qb/ansible/env.rb
CHANGED
@@ -3,7 +3,7 @@ module QB::Ansible; end
|
|
3
3
|
|
4
4
|
|
5
5
|
# @todo document QB::Ansible::Env class.
|
6
|
-
class QB::Ansible::Env
|
6
|
+
class QB::Ansible::Env
|
7
7
|
|
8
8
|
# Constants
|
9
9
|
# ======================================================================
|
@@ -24,26 +24,86 @@ class QB::Ansible::Env < Hash
|
|
24
24
|
# @todo Document return value.
|
25
25
|
#
|
26
26
|
def self.to_var_name name
|
27
|
-
"#{ VAR_NAME_PREFIX }_
|
27
|
+
"#{ VAR_NAME_PREFIX }_#{ name.to_s.upcase }"
|
28
28
|
end # .to_var_name
|
29
29
|
|
30
30
|
|
31
31
|
|
32
|
-
# Attributes
|
32
|
+
# Instance Attributes
|
33
33
|
# ======================================================================
|
34
34
|
|
35
35
|
|
36
|
+
# @!attribute [r] roles_path
|
37
|
+
# @return [Array<Pathname>]
|
38
|
+
attr_reader :roles_path
|
39
|
+
|
40
|
+
|
41
|
+
# @!attribute [r] library
|
42
|
+
# @return [Array<Pathname>]
|
43
|
+
attr_reader :library
|
44
|
+
|
45
|
+
|
46
|
+
# @!attribute [r] filter_plugins
|
47
|
+
# @return [Array<Pathname>]
|
48
|
+
attr_reader :filter_plugins
|
49
|
+
|
50
|
+
|
51
|
+
# @!attribute [r] lookup_plugins
|
52
|
+
# @return [Array<Pathname>]
|
53
|
+
attr_reader :lookup_plugins
|
54
|
+
|
55
|
+
|
36
56
|
# Constructor
|
37
57
|
# ======================================================================
|
38
58
|
|
39
59
|
# Instantiate a new `QB::Ansible::Env`.
|
40
60
|
def initialize
|
61
|
+
# NOTE this includes role paths pulled from a call-site local
|
62
|
+
# ansible.cfg
|
63
|
+
@roles_path = QB::Role.search_path. # since QB::Role.search_path is an Array
|
64
|
+
select(&:directory?).
|
65
|
+
map(&:realpath). # so uniq works
|
66
|
+
uniq # drop dups (seems to keep first instance so preserves priority)
|
67
|
+
|
68
|
+
@library = [
|
69
|
+
QB::ROOT.join('library'),
|
70
|
+
]
|
41
71
|
|
72
|
+
@filter_plugins = [
|
73
|
+
QB::ROOT.join('plugins', 'filter_plugins'),
|
74
|
+
]
|
75
|
+
|
76
|
+
@lookup_plugins = [
|
77
|
+
QB::ROOT.join('plugins', 'lookup_plugins'),
|
78
|
+
]
|
42
79
|
end # #initialize
|
43
80
|
|
44
81
|
|
45
82
|
# Instance Methods
|
46
83
|
# ======================================================================
|
47
84
|
|
85
|
+
# @todo Document to_h method.
|
86
|
+
#
|
87
|
+
# @param [type] arg_name
|
88
|
+
# @todo Add name param description.
|
89
|
+
#
|
90
|
+
# @return [return_type]
|
91
|
+
# @todo Document return value.
|
92
|
+
#
|
93
|
+
def to_h
|
94
|
+
[
|
95
|
+
:roles_path,
|
96
|
+
:library,
|
97
|
+
:filter_plugins,
|
98
|
+
:lookup_plugins
|
99
|
+
].map { |name|
|
100
|
+
value = self.send(name)
|
101
|
+
|
102
|
+
value = value.join(':') if value.is_a?(Array)
|
103
|
+
|
104
|
+
[self.class.to_var_name(name), value]
|
105
|
+
}.to_h
|
106
|
+
end # #to_h
|
107
|
+
|
48
108
|
|
49
109
|
end # class QB::Ansible::Env
|