qb 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|