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 +4 -4
- data/ansible.cfg +0 -1
- data/exe/qb +22 -306
- data/lib/qb/ansible/cmds/playbook.rb +59 -8
- data/lib/qb/cli.rb +26 -3
- data/lib/qb/cli/help.rb +56 -0
- data/lib/qb/cli/play.rb +22 -10
- data/lib/qb/cli/run.rb +291 -0
- data/lib/qb/cli/setup.rb +57 -0
- data/lib/qb/role.rb +859 -771
- data/lib/qb/version.rb +1 -1
- data/qb.gemspec +1 -1
- data/roles/qb/dev/ref/repo/git/defaults/main.yml +5 -4
- data/roles/qb/dev/ref/repo/git/tasks/main.yml +9 -0
- data/roles/qb/yarn/setup/README.md +47 -0
- data/roles/{qb.yarn_setup → qb/yarn/setup}/defaults/main.yml +1 -1
- data/roles/{qb.yarn_setup → qb/yarn/setup}/meta/main.yml +1 -1
- data/roles/{qb.yarn_setup → qb/yarn/setup}/meta/qb.yml +2 -2
- data/roles/{qb.yarn_setup → qb/yarn/setup}/tasks/distribution/MacOSX/brew_create.yml +1 -1
- data/roles/qb/yarn/setup/tasks/distribution/MacOSX/main.yml +57 -0
- data/roles/{qb.yarn_setup → qb/yarn/setup}/tasks/main.yml +1 -1
- data/roles/qb/yarn/setup/templates/yarn@M.m.p.rb.j2 +29 -0
- metadata +14 -11
- data/roles/qb.yarn_setup/tasks/distribution/MacOSX/main.yml +0 -42
- data/roles/qb.yarn_setup/templates/yarn@M.m.p.rb.j2 +0 -22
data/lib/qb/cli.rb
CHANGED
@@ -1,8 +1,33 @@
|
|
1
|
+
# Requirements
|
2
|
+
# =======================================================================
|
3
|
+
|
4
|
+
# stdlib
|
5
|
+
|
6
|
+
# deps
|
7
|
+
|
8
|
+
# package
|
9
|
+
require_relative './cli/help'
|
10
|
+
require_relative './cli/play'
|
11
|
+
require_relative './cli/run'
|
12
|
+
require_relative './cli/setup'
|
13
|
+
|
14
|
+
|
15
|
+
# Requirements
|
16
|
+
# =======================================================================
|
17
|
+
|
1
18
|
require 'nrser/refinements'
|
2
19
|
using NRSER
|
3
20
|
|
4
21
|
|
22
|
+
# Declarations
|
23
|
+
# =======================================================================
|
24
|
+
|
5
25
|
module QB; end
|
26
|
+
|
27
|
+
|
28
|
+
# Definitions
|
29
|
+
# =======================================================================
|
30
|
+
|
6
31
|
module QB::CLI
|
7
32
|
|
8
33
|
# Eigenclass (Singleton Class)
|
@@ -102,6 +127,4 @@ module QB::CLI
|
|
102
127
|
|
103
128
|
end # class << self (Eigenclass)
|
104
129
|
|
105
|
-
end
|
106
|
-
|
107
|
-
require_relative './cli/play'
|
130
|
+
end # module QB::CLI
|
data/lib/qb/cli/help.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Requirements
|
2
|
+
# =====================================================================
|
3
|
+
|
4
|
+
# package
|
5
|
+
|
6
|
+
|
7
|
+
# Declarations
|
8
|
+
# =======================================================================
|
9
|
+
|
10
|
+
module QB; end
|
11
|
+
|
12
|
+
|
13
|
+
# Definitions
|
14
|
+
# =======================================================================
|
15
|
+
|
16
|
+
module QB::CLI
|
17
|
+
|
18
|
+
# Show the help message.
|
19
|
+
#
|
20
|
+
# @todo
|
21
|
+
# We should have more types of help.
|
22
|
+
#
|
23
|
+
# @return [1]
|
24
|
+
# Error exit status - we don't want `qb ... && ...` to move on to the
|
25
|
+
# second command when we end up falling back to `help`.
|
26
|
+
#
|
27
|
+
def self.help
|
28
|
+
metadata = if QB.gemspec.metadata && !QB.gemspec.metadata.empty?
|
29
|
+
"metadata:\n" + QB.gemspec.metadata.map {|key, value|
|
30
|
+
" #{ key }: #{ value }"
|
31
|
+
}.join("\n")
|
32
|
+
end
|
33
|
+
|
34
|
+
puts <<-END
|
35
|
+
version: #{ QB::VERSION }
|
36
|
+
|
37
|
+
#{ metadata }
|
38
|
+
|
39
|
+
syntax:
|
40
|
+
|
41
|
+
qb ROLE [OPTIONS] DIRECTORY
|
42
|
+
|
43
|
+
use `qb ROLE -h` for role options.
|
44
|
+
|
45
|
+
available roles:
|
46
|
+
|
47
|
+
END
|
48
|
+
puts QB::Role.available
|
49
|
+
puts
|
50
|
+
|
51
|
+
return 1
|
52
|
+
end # .help
|
53
|
+
|
54
|
+
end # module QB::CLI
|
55
|
+
|
56
|
+
|
data/lib/qb/cli/play.rb
CHANGED
@@ -5,19 +5,25 @@
|
|
5
5
|
require 'qb/ansible/cmds/playbook'
|
6
6
|
|
7
7
|
|
8
|
+
# Declarations
|
9
|
+
# =======================================================================
|
10
|
+
|
8
11
|
module QB; end
|
9
12
|
|
10
|
-
|
13
|
+
|
14
|
+
# Definitions
|
15
|
+
# =======================================================================
|
16
|
+
|
11
17
|
module QB::CLI
|
12
18
|
|
13
19
|
# Play an Ansible playbook (like `state.yml`) in the QB environment
|
14
20
|
# (sets up path env vars, IO streams, etc.).
|
15
21
|
#
|
16
|
-
# @param [
|
17
|
-
#
|
22
|
+
# @param [Array<String>] args
|
23
|
+
# CLI arguments to use.
|
18
24
|
#
|
19
|
-
# @return [
|
20
|
-
#
|
25
|
+
# @return [Fixnum]
|
26
|
+
# The `ansible-playbook` command exit code.
|
21
27
|
#
|
22
28
|
def self.play args
|
23
29
|
if args.empty?
|
@@ -27,7 +33,7 @@ module QB::CLI
|
|
27
33
|
playbook_path = QB::Util.resolve args[0]
|
28
34
|
|
29
35
|
unless playbook_path.file?
|
30
|
-
raise "Can't find Ansible playbook at
|
36
|
+
raise "Can't find Ansible playbook at `#{ playbook_path.to_s }`"
|
31
37
|
end
|
32
38
|
|
33
39
|
# By default, we won't change directories to run the command.
|
@@ -49,11 +55,17 @@ module QB::CLI
|
|
49
55
|
end
|
50
56
|
|
51
57
|
cmd = QB::Ansible::Cmds::Playbook.new \
|
52
|
-
|
53
|
-
|
58
|
+
chdir: chdir,
|
59
|
+
playbook_path: playbook_path
|
60
|
+
|
61
|
+
status = cmd.stream
|
62
|
+
|
63
|
+
if status != 0
|
64
|
+
$stderr.puts "ERROR ansible-playbook failed."
|
65
|
+
end
|
66
|
+
|
67
|
+
exit status
|
54
68
|
|
55
69
|
end # .play
|
56
70
|
|
57
71
|
end # module QB::CLI
|
58
|
-
|
59
|
-
|
data/lib/qb/cli/run.rb
CHANGED
@@ -0,0 +1,291 @@
|
|
1
|
+
# Requirements
|
2
|
+
# =====================================================================
|
3
|
+
|
4
|
+
# package
|
5
|
+
require 'qb/cli/help'
|
6
|
+
|
7
|
+
|
8
|
+
# Declarations
|
9
|
+
# =======================================================================
|
10
|
+
|
11
|
+
module QB; end
|
12
|
+
|
13
|
+
|
14
|
+
# Definitions
|
15
|
+
# =======================================================================
|
16
|
+
|
17
|
+
module QB::CLI
|
18
|
+
|
19
|
+
# Run a QB role.
|
20
|
+
#
|
21
|
+
# @param [Array<String>] args
|
22
|
+
# CLI args to work with.
|
23
|
+
#
|
24
|
+
# @return [Fixnum]
|
25
|
+
# Exit status code from `ansible-playbook` command, unless we invoked
|
26
|
+
# help or error'd out in another way before the run (in which case `1`
|
27
|
+
# is returned).
|
28
|
+
#
|
29
|
+
def self.run args
|
30
|
+
role_arg = args.shift
|
31
|
+
QB.debug "role arg", role_arg
|
32
|
+
|
33
|
+
begin
|
34
|
+
role = QB::Role.require role_arg
|
35
|
+
rescue QB::Role::NoMatchesError => e
|
36
|
+
puts "ERROR - #{ e.message }\n\n"
|
37
|
+
# exits with status code 1
|
38
|
+
return help
|
39
|
+
rescue QB::Role::MultipleMatchesError => e
|
40
|
+
puts "ERROR - #{ e.message }\n\n"
|
41
|
+
return 1
|
42
|
+
end
|
43
|
+
|
44
|
+
QB.check_qb_version role
|
45
|
+
|
46
|
+
options = QB::Options.new role, args
|
47
|
+
|
48
|
+
QB.debug "role options set on cli", options.role_options.select {|k, o|
|
49
|
+
!o.value.nil?
|
50
|
+
}
|
51
|
+
|
52
|
+
QB.debug "qb options", options.qb
|
53
|
+
|
54
|
+
cwd = Dir.getwd
|
55
|
+
|
56
|
+
dir = nil
|
57
|
+
|
58
|
+
if role.uses_default_dir?
|
59
|
+
# get the target dir
|
60
|
+
dir = case args.length
|
61
|
+
when 0
|
62
|
+
# in this case, a dir has not been provided
|
63
|
+
#
|
64
|
+
# in some cases (like projects) the dir can be figured out in other ways:
|
65
|
+
#
|
66
|
+
|
67
|
+
if options.ask?
|
68
|
+
default = begin
|
69
|
+
role.default_dir cwd, options.role_options
|
70
|
+
rescue QB::UserInputError => e
|
71
|
+
NRSER::NO_ARG
|
72
|
+
end
|
73
|
+
|
74
|
+
QB::CLI.ask name: "target directory (`qb_dir`)",
|
75
|
+
type: t.non_empty_str,
|
76
|
+
default: default
|
77
|
+
|
78
|
+
else
|
79
|
+
role.default_dir cwd, options.role_options
|
80
|
+
end
|
81
|
+
|
82
|
+
when 1
|
83
|
+
# there is a single positional arg, which is used as dir
|
84
|
+
args[0]
|
85
|
+
|
86
|
+
else
|
87
|
+
# there are multiple positional args, which is not allowed
|
88
|
+
raise "can't supply more than one argument: #{ args.inspect }"
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
QB.debug "input_dir", dir
|
93
|
+
|
94
|
+
# normalize to expanded path (has no trailing slash)
|
95
|
+
dir = File.expand_path dir
|
96
|
+
|
97
|
+
QB.debug "normalized_dir", dir
|
98
|
+
|
99
|
+
# create the dir if it doesn't exist (so don't have to cover this in
|
100
|
+
# every role)
|
101
|
+
if role.mkdir
|
102
|
+
FileUtils.mkdir_p dir unless File.exists? dir
|
103
|
+
end
|
104
|
+
|
105
|
+
saved_options_path = Pathname.new(dir) + '.qb-options.yml'
|
106
|
+
|
107
|
+
saved_options = if saved_options_path.exist?
|
108
|
+
# convert old _ separated names to - separated
|
109
|
+
YAML.load(saved_options_path.read).map {|role_options_key, role_options|
|
110
|
+
[
|
111
|
+
role_options_key,
|
112
|
+
role_options.map {|name, value|
|
113
|
+
[QB::Options.cli_ize_name(name), value]
|
114
|
+
}.to_h
|
115
|
+
]
|
116
|
+
}.to_h.tap {|saved_options|
|
117
|
+
QB.debug "found saved options", saved_options
|
118
|
+
}
|
119
|
+
else
|
120
|
+
QB.debug "no saved options"
|
121
|
+
{}
|
122
|
+
end
|
123
|
+
|
124
|
+
if saved_options.key? role.options_key
|
125
|
+
role_saved_options = saved_options[role.options_key]
|
126
|
+
|
127
|
+
QB.debug "found saved options for role", role_saved_options
|
128
|
+
|
129
|
+
role_saved_options.each do |option_cli_name, value|
|
130
|
+
option = options.role_options[option_cli_name]
|
131
|
+
|
132
|
+
if option.value.nil?
|
133
|
+
QB.debug "setting from saved options", option: option, value: value
|
134
|
+
|
135
|
+
option.value = value
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end # unless default_dir == false
|
140
|
+
|
141
|
+
|
142
|
+
# Interactive Input
|
143
|
+
# =====================================================================
|
144
|
+
|
145
|
+
if options.ask?
|
146
|
+
# Incomplete
|
147
|
+
raise "COMING SOON!!!...?"
|
148
|
+
QB::CLI.ask_for_options role: role, options: options
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
# Validation
|
153
|
+
# =====================================================================
|
154
|
+
#
|
155
|
+
# Should have already been taken care of if we used interactive input.
|
156
|
+
#
|
157
|
+
|
158
|
+
# check that required options are present
|
159
|
+
missing = options.role_options.values.select {|option|
|
160
|
+
option.required? && option.value.nil?
|
161
|
+
}
|
162
|
+
|
163
|
+
unless missing.empty?
|
164
|
+
puts "ERROR: options #{ missing.map {|o| o.cli_name } } are required."
|
165
|
+
return 1
|
166
|
+
end
|
167
|
+
|
168
|
+
set_options = options.role_options.select {|k, o| !o.value.nil?}
|
169
|
+
|
170
|
+
QB.debug "set options", set_options
|
171
|
+
|
172
|
+
playbook_role = {'role' => role.name}
|
173
|
+
|
174
|
+
playbook_vars = {
|
175
|
+
'qb_dir' => dir,
|
176
|
+
# depreciated due to mass potential for conflict
|
177
|
+
'dir' => dir,
|
178
|
+
'qb_cwd' => cwd,
|
179
|
+
'qb_user_roles_dir' => QB::USER_ROLES_DIR.to_s,
|
180
|
+
}
|
181
|
+
|
182
|
+
set_options.values.each do |option|
|
183
|
+
playbook_role[option.var_name] = option.value
|
184
|
+
end
|
185
|
+
|
186
|
+
play =
|
187
|
+
{
|
188
|
+
'hosts' => options.qb['hosts'],
|
189
|
+
'vars' => playbook_vars,
|
190
|
+
# 'gather_subset' => ['!all'],
|
191
|
+
'gather_facts' => options.qb['facts'],
|
192
|
+
'pre_tasks' => [
|
193
|
+
{
|
194
|
+
'qb_facts' => {
|
195
|
+
'qb_dir' => dir,
|
196
|
+
}
|
197
|
+
},
|
198
|
+
],
|
199
|
+
'roles' => [
|
200
|
+
'nrser.blockinfile',
|
201
|
+
playbook_role
|
202
|
+
],
|
203
|
+
}
|
204
|
+
|
205
|
+
if options.qb['user']
|
206
|
+
play['become'] = true
|
207
|
+
play['become_user'] = options.qb['user']
|
208
|
+
end
|
209
|
+
|
210
|
+
playbook = [play]
|
211
|
+
|
212
|
+
QB.debug "playbook", playbook
|
213
|
+
|
214
|
+
env = QB::Ansible::Env.new
|
215
|
+
|
216
|
+
# stick the role path in front to make sure we get **that** role
|
217
|
+
env.roles_path.unshift role.path.expand_path.dirname
|
218
|
+
|
219
|
+
cmd = QB::Ansible::Cmds::Playbook.new \
|
220
|
+
env: env,
|
221
|
+
playbook: playbook,
|
222
|
+
role_options: options,
|
223
|
+
chdir: (File.exists?('./ansible/ansible.cfg') ? './ansible' : nil)
|
224
|
+
|
225
|
+
# print
|
226
|
+
# =====
|
227
|
+
#
|
228
|
+
# print useful stuff for debugging / running outside of qb
|
229
|
+
#
|
230
|
+
|
231
|
+
if options.qb['print'].include? 'options'
|
232
|
+
puts "SET OPTIONS:\n\n#{ YAML.dump set_options }\n\n"
|
233
|
+
end
|
234
|
+
|
235
|
+
if options.qb['print'].include? 'env'
|
236
|
+
puts "ENV:\n\n#{ YAML.dump cmd.env.to_h }\n\n"
|
237
|
+
end
|
238
|
+
|
239
|
+
if options.qb['print'].include? 'cmd'
|
240
|
+
puts "COMMAND:\n\n#{ cmd.prepare }\n\n"
|
241
|
+
end
|
242
|
+
|
243
|
+
if options.qb['print'].include? 'playbook'
|
244
|
+
puts "PLAYBOOK:\n\n#{ YAML.dump playbook }\n\n"
|
245
|
+
end
|
246
|
+
|
247
|
+
# stop here if we're not supposed to run
|
248
|
+
exit 0 if !options.qb['run']
|
249
|
+
|
250
|
+
# run
|
251
|
+
# ===
|
252
|
+
#
|
253
|
+
# stuff below here does stuff
|
254
|
+
#
|
255
|
+
|
256
|
+
# save the options back
|
257
|
+
if (
|
258
|
+
dir &&
|
259
|
+
# we set some options that we can save
|
260
|
+
set_options.values.select {|o| o.save? }.length > 0 &&
|
261
|
+
# the role says to save options
|
262
|
+
role.save_options
|
263
|
+
)
|
264
|
+
saved_options[role.options_key] = set_options.select{|key, option|
|
265
|
+
option.save?
|
266
|
+
}.map {|key, option|
|
267
|
+
[key, option.value]
|
268
|
+
}.to_h
|
269
|
+
|
270
|
+
unless saved_options_path.dirname.exist?
|
271
|
+
FileUtils.mkdir_p saved_options_path.dirname
|
272
|
+
end
|
273
|
+
|
274
|
+
saved_options_path.open('w') do |f|
|
275
|
+
f.write YAML.dump(saved_options)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
status = cmd.stream
|
280
|
+
|
281
|
+
if status != 0
|
282
|
+
$stderr.puts "ERROR ansible-playbook failed."
|
283
|
+
end
|
284
|
+
|
285
|
+
# exit status
|
286
|
+
status
|
287
|
+
end # .run
|
288
|
+
|
289
|
+
end # module QB::CLI
|
290
|
+
|
291
|
+
|