machinery-tool 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NEWS +7 -0
- data/bin/machinery +3 -1
- data/helpers/default_filters.json +24 -0
- data/helpers/yum_repositories.py +8 -2
- data/lib/autoyast.rb +8 -3
- data/lib/changed_rpm_files_helper.rb +34 -7
- data/lib/cli.rb +149 -101
- data/lib/element_filter.rb +45 -0
- data/lib/exceptions.rb +3 -2
- data/lib/filter.rb +121 -0
- data/lib/inspect_task.rb +25 -4
- data/lib/kiwi_config.rb +11 -0
- data/lib/list_task.rb +53 -26
- data/lib/local_system.rb +1 -1
- data/lib/machinery.rb +2 -0
- data/lib/manifest.rb +3 -2
- data/lib/migration.rb +2 -2
- data/lib/system_description.rb +33 -4
- data/lib/tarball.rb +5 -5
- data/lib/version.rb +1 -1
- data/lib/zypper.rb +12 -17
- data/man/generated/machinery.1.gz +0 -0
- data/man/generated/machinery.1.html +21 -4
- data/plugins/docs/changed_managed_files.md +3 -1
- data/plugins/docs/config_files.md +3 -2
- data/plugins/inspect/changed_managed_files_inspector.rb +8 -2
- data/plugins/inspect/config_files_inspector.rb +1 -1
- data/plugins/inspect/groups_inspector.rb +3 -1
- data/plugins/inspect/os_inspector.rb +2 -2
- data/plugins/inspect/packages_inspector.rb +1 -1
- data/plugins/inspect/patterns_inspector.rb +1 -1
- data/plugins/inspect/repositories_inspector.rb +1 -1
- data/plugins/inspect/services_inspector.rb +1 -1
- data/plugins/inspect/unmanaged_files_inspector.rb +17 -42
- data/plugins/inspect/users_inspector.rb +1 -1
- data/plugins/schema/v3/system-description-changed-managed-files.schema.json +1 -1
- data/plugins/schema/v3/system-description-config-files.schema.json +1 -1
- data/plugins/schema/v3/system-description-repositories.schema.json +1 -1
- data/schema/v3/system-description-global.schema.json +12 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 184d1ef94950678ea43a32a035f1b49393fcaa3a
|
4
|
+
data.tar.gz: 4e4135549b3a332ae78c453100797d8bcc121ecf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19f792e485da42fa7e8dad80d822cd0890f92ffc9cb96a89621bb86b8830388b061b8db39e96fd0afe86d3fe1d3f3a1f7728f8dc9d5788b756619831970b4e65
|
7
|
+
data.tar.gz: e692387ddaf55efb16418c5b2db7ff7be53b7d5f0ffb46a2cae6297e0ce4ad090b1455140fef1f4500d7223111f8e1ce9c705b19054cc8ed553f8d8b6e7f1ed1
|
data/NEWS
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# Machinery Release Notes
|
2
2
|
|
3
3
|
|
4
|
+
## Version 1.5.0 - Fri Mar 13 13:03:47 CET 2015 - thardeck@suse.de
|
5
|
+
|
6
|
+
* Fix issue with changes of managed files on RHEL (gh#SUSE/machinery#636)
|
7
|
+
* Add `--short` option to list command for showing a short list of all descriptions
|
8
|
+
* Improve error output for system descriptions which have outdated formats
|
9
|
+
* Add `--skip-files` option to `inspect` command for unmanaged files
|
10
|
+
|
4
11
|
## Version 1.4.0 - Wed Feb 18 16:51:43 CET 2015 - thardeck@suse.de
|
5
12
|
|
6
13
|
* Support inspection of Red Hat Enterprise Linux 6 systems
|
data/bin/machinery
CHANGED
@@ -22,7 +22,9 @@ require_relative '../lib/machinery'
|
|
22
22
|
begin
|
23
23
|
LocalSystem.validate_machinery_compatibility
|
24
24
|
Machinery.initialize_logger(ENV["MACHINERY_LOG_FILE"] || Machinery::DEFAULT_LOG_FILE)
|
25
|
-
|
25
|
+
command_log = "Executing (Version #{Machinery::VERSION}) '#{$0} #{ARGV.join(" ")}'"
|
26
|
+
command_log += " (store: #{ENV["MACHINERY_DIR"]})" if ENV["MACHINERY_DIR"]
|
27
|
+
Machinery.logger.info command_log
|
26
28
|
Cli.run(ARGV)
|
27
29
|
rescue Machinery::Errors::IncompatibleHost => e
|
28
30
|
puts e
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"inspect": [
|
3
|
+
"/unmanaged_files/files/name=/etc/passwd",
|
4
|
+
"/unmanaged_files/files/name=/etc/shadow",
|
5
|
+
"/unmanaged_files/files/name=/etc/group",
|
6
|
+
"/unmanaged_files/files/name=/tmp",
|
7
|
+
"/unmanaged_files/files/name=/var/tmp",
|
8
|
+
"/unmanaged_files/files/name=/lost+found",
|
9
|
+
"/unmanaged_files/files/name=/var/run",
|
10
|
+
"/unmanaged_files/files/name=/var/lib/rpm",
|
11
|
+
"/unmanaged_files/files/name=/.snapshots",
|
12
|
+
"/unmanaged_files/files/name=/proc",
|
13
|
+
"/unmanaged_files/files/name=/boot",
|
14
|
+
"/unmanaged_files/files/name=/etc/init.d/boot.d",
|
15
|
+
"/unmanaged_files/files/name=/etc/init.d/rc0.d",
|
16
|
+
"/unmanaged_files/files/name=/etc/init.d/rc1.d",
|
17
|
+
"/unmanaged_files/files/name=/etc/init.d/rc2.d",
|
18
|
+
"/unmanaged_files/files/name=/etc/init.d/rc3.d",
|
19
|
+
"/unmanaged_files/files/name=/etc/init.d/rc4.d",
|
20
|
+
"/unmanaged_files/files/name=/etc/init.d/rc5.d",
|
21
|
+
"/unmanaged_files/files/name=/etc/init.d/rc6.d",
|
22
|
+
"/unmanaged_files/files/name=/etc/init.d/rcS.d"
|
23
|
+
]
|
24
|
+
}
|
data/helpers/yum_repositories.py
CHANGED
@@ -17,7 +17,10 @@
|
|
17
17
|
# you may find current contact information at www.suse.com
|
18
18
|
|
19
19
|
import yum
|
20
|
-
|
20
|
+
try:
|
21
|
+
import json
|
22
|
+
except:
|
23
|
+
import simplejson as json
|
21
24
|
|
22
25
|
yb = yum.YumBase()
|
23
26
|
|
@@ -28,7 +31,10 @@ for repo in yb.repos.sort():
|
|
28
31
|
repo_dict["alias"] = repo.id
|
29
32
|
repo_dict["name"] = repo.name
|
30
33
|
repo_dict["type"] = "rpm-md"
|
31
|
-
|
34
|
+
if repo.baseurl:
|
35
|
+
repo_dict["url"] = repo.baseurl[0]
|
36
|
+
else:
|
37
|
+
repo_dict["url"] = ""
|
32
38
|
repo_dict["enabled"] = repo.enabled
|
33
39
|
repo_dict["gpgcheck"] = repo.gpgcheck
|
34
40
|
repo_dict["package_manager"] = "yum"
|
data/lib/autoyast.rb
CHANGED
@@ -74,6 +74,7 @@ class Autoyast < Exporter
|
|
74
74
|
apply_basic_network(xml)
|
75
75
|
apply_repositories(xml)
|
76
76
|
xml.software do
|
77
|
+
apply_software_settings(xml)
|
77
78
|
apply_packages(xml)
|
78
79
|
apply_patterns(xml)
|
79
80
|
end
|
@@ -102,6 +103,10 @@ class Autoyast < Exporter
|
|
102
103
|
|
103
104
|
private
|
104
105
|
|
106
|
+
def apply_software_settings(xml)
|
107
|
+
xml.install_recommended "false", "config:type" => "boolean"
|
108
|
+
end
|
109
|
+
|
105
110
|
def apply_non_interactive_mode(xml)
|
106
111
|
xml.general do
|
107
112
|
xml.mode do
|
@@ -250,7 +255,7 @@ class Autoyast < Exporter
|
|
250
255
|
xml.send("pre-scripts", "config:type" => "list") do
|
251
256
|
xml.script do
|
252
257
|
xml.source do
|
253
|
-
xml.cdata 'sed -n \'/.*autoyast2\?=\(
|
258
|
+
xml.cdata 'sed -n \'/.*autoyast2\?=\([^ ]*\)\/.*[^\s]*/s//\1/p\'' \
|
254
259
|
' /proc/cmdline > /tmp/description_url'
|
255
260
|
end
|
256
261
|
end
|
@@ -286,7 +291,7 @@ class Autoyast < Exporter
|
|
286
291
|
!@system_description.unmanaged_files.extracted
|
287
292
|
|
288
293
|
base = Pathname(@system_description.scope_file_store("unmanaged_files").path)
|
289
|
-
@chroot_scripts << <<-EOF
|
294
|
+
@chroot_scripts << <<-EOF.chomp.gsub(/^\s+/, "")
|
290
295
|
curl -o '/mnt/tmp/filter' "`cat /tmp/description_url`/unmanaged_files_#{@name}_excludes"
|
291
296
|
EOF
|
292
297
|
|
@@ -297,7 +302,7 @@ class Autoyast < Exporter
|
|
297
302
|
tarball_name = File.basename(path)
|
298
303
|
url = "`cat /tmp/description_url`#{URI.escape(File.join("/unmanaged_files", relative_path))}"
|
299
304
|
|
300
|
-
@chroot_scripts << <<-EOF
|
305
|
+
@chroot_scripts << <<-EOF.chomp.gsub(/^\s+/, "")
|
301
306
|
curl -o '/mnt/tmp/#{tarball_name}' "#{url}"
|
302
307
|
tar -C /mnt/ -X '/mnt/tmp/filter' -xf '#{File.join("/mnt/tmp", tarball_name)}'
|
303
308
|
rm '#{File.join("/mnt/tmp", tarball_name)}'
|
@@ -16,10 +16,21 @@
|
|
16
16
|
# you may find current contact information at www.suse.com
|
17
17
|
|
18
18
|
module ChangedRpmFilesHelper
|
19
|
+
def expected_tag?(character, position)
|
20
|
+
if @rpm_changes[position] == character
|
21
|
+
true
|
22
|
+
else
|
23
|
+
@unknown_tag ||= ![".", "?"].include?(@rpm_changes[position])
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
19
28
|
def parse_rpm_changes_line(line)
|
20
29
|
# rpm provides lines per config file where first 9 characters indicate which
|
21
30
|
# properties of the file are modified
|
22
|
-
rpm_changes, *fields = line.split(" ")
|
31
|
+
@rpm_changes, *fields = line.split(" ")
|
32
|
+
# nine rpm changes are known
|
33
|
+
@unknown_tag = @rpm_changes.size > 9
|
23
34
|
|
24
35
|
# For config or documentation files there's an additional field which
|
25
36
|
# contains "c" or "d"
|
@@ -27,17 +38,33 @@ module ChangedRpmFilesHelper
|
|
27
38
|
path = fields.join(" ")
|
28
39
|
|
29
40
|
changes = []
|
30
|
-
if rpm_changes == "missing"
|
41
|
+
if @rpm_changes == "missing"
|
31
42
|
changes << "deleted"
|
32
|
-
elsif rpm_changes == "........." && path.end_with?(" (replaced)")
|
43
|
+
elsif @rpm_changes == "........." && path.end_with?(" (replaced)")
|
33
44
|
changes << "replaced"
|
34
45
|
path.slice!(/ \(replaced\)$/)
|
35
46
|
else
|
36
|
-
changes << "
|
37
|
-
changes << "
|
38
|
-
changes << "
|
39
|
-
changes << "
|
47
|
+
changes << "size" if expected_tag?("S", 0)
|
48
|
+
changes << "mode" if expected_tag?("M", 1)
|
49
|
+
changes << "md5" if expected_tag?("5", 2)
|
50
|
+
changes << "device_number" if expected_tag?("D", 3)
|
51
|
+
changes << "link_path" if expected_tag?("L", 4)
|
52
|
+
changes << "user" if expected_tag?("U", 5)
|
53
|
+
changes << "group" if expected_tag?("G", 6)
|
54
|
+
changes << "time" if expected_tag?("T", 7)
|
55
|
+
changes << "capabilities" if @rpm_changes.size > 8 && expected_tag?("P", 8)
|
40
56
|
end
|
57
|
+
|
58
|
+
if @unknown_tag
|
59
|
+
changes << "other_rpm_changes"
|
60
|
+
end
|
61
|
+
|
62
|
+
if @rpm_changes.include?("?")
|
63
|
+
message = "Could not perform all tests on rpm changes for file '#{path}'."
|
64
|
+
Machinery.logger.warn(message)
|
65
|
+
Machinery::Ui.warn("Warning: #{message}")
|
66
|
+
end
|
67
|
+
|
41
68
|
[path, changes, type]
|
42
69
|
end
|
43
70
|
|
data/lib/cli.rb
CHANGED
@@ -22,9 +22,9 @@ class Cli
|
|
22
22
|
preserve_argv(true)
|
23
23
|
@version = Machinery::VERSION + " (system description format version " +
|
24
24
|
"#{SystemDescription::CURRENT_FORMAT_VERSION})"
|
25
|
-
switch :version, :
|
26
|
-
switch :debug, :
|
27
|
-
switch [:help, :h], :
|
25
|
+
switch :version, negatable: false, desc: "Show version"
|
26
|
+
switch :debug, negatable: false, desc: "Enable debug mode"
|
27
|
+
switch [:help, :h], negatable: false, desc: "Show help"
|
28
28
|
|
29
29
|
sort_help :manually
|
30
30
|
pre do |global_options,command,options,args|
|
@@ -197,13 +197,12 @@ class Cli
|
|
197
197
|
LONGDESC
|
198
198
|
arg "NAME"
|
199
199
|
command :analyze do |c|
|
200
|
-
c.flag [:operation, :o], :
|
201
|
-
:
|
200
|
+
c.flag [:operation, :o], type: String, required: true,
|
201
|
+
desc: "The analyze operation to perform", arg_name: "OPERATION"
|
202
202
|
|
203
203
|
c.action do |global_options,options,args|
|
204
204
|
name = shift_arg(args, "NAME")
|
205
|
-
|
206
|
-
description = SystemDescription.load(name, store)
|
205
|
+
description = SystemDescription.load(name, system_description_store)
|
207
206
|
|
208
207
|
case options[:operation]
|
209
208
|
when "config-file-diffs"
|
@@ -228,20 +227,22 @@ class Cli
|
|
228
227
|
LONGDESC
|
229
228
|
arg "NAME"
|
230
229
|
command :build do |c|
|
231
|
-
c.flag ["image-dir", :i], :
|
232
|
-
:
|
233
|
-
c.switch ["enable-dhcp", :d], :
|
234
|
-
:
|
235
|
-
c.switch ["enable-ssh", :s], :
|
236
|
-
:
|
230
|
+
c.flag ["image-dir", :i], type: String, required: true,
|
231
|
+
desc: "Store the image under the specified path", arg_name: "DIRECTORY"
|
232
|
+
c.switch ["enable-dhcp", :d], required: false, negatable: false,
|
233
|
+
desc: "Enable DCHP client on first network card of built image"
|
234
|
+
c.switch ["enable-ssh", :s], required: false, negatable: false,
|
235
|
+
desc: "Enable SSH service in built image"
|
237
236
|
|
238
237
|
c.action do |global_options,options,args|
|
239
238
|
name = shift_arg(args, "NAME")
|
240
|
-
|
241
|
-
description = SystemDescription.load(name, store)
|
239
|
+
description = SystemDescription.load(name, system_description_store)
|
242
240
|
|
243
241
|
task = BuildTask.new
|
244
|
-
task.build(
|
242
|
+
task.build(
|
243
|
+
description, File.expand_path(options["image-dir"]),
|
244
|
+
enable_dhcp: options["enable-dhcp"], enable_ssh: options["enable-ssh"]
|
245
|
+
)
|
245
246
|
end
|
246
247
|
end
|
247
248
|
|
@@ -259,19 +260,19 @@ class Cli
|
|
259
260
|
arg "NAME1"
|
260
261
|
arg "NAME2"
|
261
262
|
command :compare do |c|
|
262
|
-
c.flag [:scope, :s], :
|
263
|
-
:
|
264
|
-
c.flag ["exclude-scope", :e], :
|
265
|
-
:
|
266
|
-
c.switch "show-all", :
|
267
|
-
:
|
268
|
-
c.switch "pager", :
|
269
|
-
:
|
263
|
+
c.flag [:scope, :s], type: String, required: false,
|
264
|
+
desc: "Compare specified scopes", arg_name: "SCOPE_LIST"
|
265
|
+
c.flag ["exclude-scope", :e], type: String, required: false,
|
266
|
+
desc: "Exclude specified scopes", arg_name: "SCOPE_LIST"
|
267
|
+
c.switch "show-all", required: false, negatable: false,
|
268
|
+
desc: "Show also common properties"
|
269
|
+
c.switch "pager", required: false, default_value: true,
|
270
|
+
desc: "Pipe output into a pager"
|
270
271
|
|
271
272
|
c.action do |global_options,options,args|
|
272
273
|
name1 = shift_arg(args, "NAME1")
|
273
274
|
name2 = shift_arg(args, "NAME2")
|
274
|
-
store =
|
275
|
+
store = system_description_store
|
275
276
|
description1 = SystemDescription.load(name1, store)
|
276
277
|
description2 = SystemDescription.load(name2, store)
|
277
278
|
scope_list = process_scope_option(options[:scope], options["exclude-scope"])
|
@@ -298,9 +299,8 @@ class Cli
|
|
298
299
|
c.action do |global_options,options,args|
|
299
300
|
from = shift_arg(args, "FROM_NAME")
|
300
301
|
to = shift_arg(args, "TO_NAME")
|
301
|
-
store = SystemDescriptionStore.new
|
302
302
|
task = CopyTask.new
|
303
|
-
task.copy(
|
303
|
+
task.copy(system_description_store, from, to)
|
304
304
|
end
|
305
305
|
end
|
306
306
|
|
@@ -315,19 +315,18 @@ class Cli
|
|
315
315
|
LONGDESC
|
316
316
|
arg "NAME"
|
317
317
|
command :deploy do |c|
|
318
|
-
c.flag ["cloud-config", :c], :
|
319
|
-
:
|
320
|
-
c.flag ["image-dir", :i], :
|
321
|
-
:
|
322
|
-
c.switch [:insecure, :s], :
|
323
|
-
:
|
324
|
-
c.flag ["cloud-image-name", :n], :
|
325
|
-
:
|
318
|
+
c.flag ["cloud-config", :c], type: String, required: true, arg_name: "FILE",
|
319
|
+
desc: "Path to file where the cloud config (openrc.sh) is located"
|
320
|
+
c.flag ["image-dir", :i], type: String, required: false,
|
321
|
+
desc: "Directory where the image is located", arg_name: "DIRECTORY"
|
322
|
+
c.switch [:insecure, :s], required: false, negatable: false,
|
323
|
+
desc: "Explicitly allow glanceclient to perform 'insecure SSL' (https) requests."
|
324
|
+
c.flag ["cloud-image-name", :n], type: String, required: false,
|
325
|
+
desc: "Name of the image in the cloud", arg_name: "NAME"
|
326
326
|
|
327
327
|
c.action do |global_options,options,args|
|
328
328
|
name = shift_arg(args, "NAME")
|
329
|
-
|
330
|
-
description = SystemDescription.load(name, store)
|
329
|
+
description = SystemDescription.load(name, system_description_store)
|
331
330
|
|
332
331
|
task = DeployTask.new
|
333
332
|
opts = {
|
@@ -350,15 +349,14 @@ class Cli
|
|
350
349
|
LONGDESC
|
351
350
|
arg "NAME"
|
352
351
|
command "export-kiwi" do |c|
|
353
|
-
c.flag ["kiwi-dir", :k], :
|
354
|
-
:
|
355
|
-
c.switch :force, :
|
356
|
-
:
|
352
|
+
c.flag ["kiwi-dir", :k], type: String, required: true,
|
353
|
+
desc: "Location where the description will be stored", arg_name: "DIRECTORY"
|
354
|
+
c.switch :force, default_value: false, required: false, negatable: false,
|
355
|
+
desc: "Overwrite existing description"
|
357
356
|
|
358
357
|
c.action do |global_options,options,args|
|
359
358
|
name = shift_arg(args, "NAME")
|
360
|
-
|
361
|
-
description = SystemDescription.load(name, store)
|
359
|
+
description = SystemDescription.load(name, system_description_store)
|
362
360
|
exporter = KiwiConfig.new(description)
|
363
361
|
|
364
362
|
task = ExportTask.new(exporter)
|
@@ -387,8 +385,7 @@ class Cli
|
|
387
385
|
|
388
386
|
c.action do |_global_options, options, args|
|
389
387
|
name = shift_arg(args, "NAME")
|
390
|
-
|
391
|
-
description = SystemDescription.load(name, store)
|
388
|
+
description = SystemDescription.load(name, system_description_store)
|
392
389
|
exporter = Autoyast.new(description)
|
393
390
|
|
394
391
|
task = ExportTask.new(exporter)
|
@@ -412,26 +409,28 @@ class Cli
|
|
412
409
|
LONGDESC
|
413
410
|
arg "HOSTNAME"
|
414
411
|
command :inspect do |c|
|
415
|
-
c.flag [:name, :n], :
|
416
|
-
:
|
417
|
-
c.flag [:scope, :s], :
|
418
|
-
:
|
419
|
-
c.flag ["exclude-scope", :e], :
|
420
|
-
:
|
421
|
-
c.
|
422
|
-
:
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
412
|
+
c.flag [:name, :n], type: String, required: false, arg_name: "NAME",
|
413
|
+
desc: "Store system description under the specified name"
|
414
|
+
c.flag [:scope, :s], type: String, required: false,
|
415
|
+
desc: "Show specified scopes", arg_name: "SCOPE_LIST"
|
416
|
+
c.flag ["exclude-scope", :e], type: String, required: false,
|
417
|
+
desc: "Exclude specified scopes", arg_name: "SCOPE_LIST"
|
418
|
+
c.flag "skip-files", required: false, negatable: false,
|
419
|
+
desc: "Do not consider given files or directories during inspection. " \
|
420
|
+
"Either provide one file or directory name or a list of names separated by commas."
|
421
|
+
c.switch ["extract-files", :x], required: false, negatable: false,
|
422
|
+
desc: "Extract changed configuration files and unmanaged files from inspected system"
|
423
|
+
c.switch "extract-changed-config-files", required: false, negatable: false,
|
424
|
+
desc: "Extract changed configuration files from inspected system"
|
425
|
+
c.switch "extract-unmanaged-files", required: false, negatable: false,
|
426
|
+
desc: "Extract unmanaged files from inspected system"
|
427
|
+
c.switch "extract-changed-managed-files", required: false, negatable: false,
|
428
|
+
desc: "Extract changed managed files from inspected system"
|
429
|
+
c.switch :show, required: false, negatable: false,
|
430
|
+
desc: "Print inspection result"
|
431
431
|
|
432
432
|
c.action do |global_options,options,args|
|
433
433
|
host = shift_arg(args, "HOSTNAME")
|
434
|
-
store = SystemDescriptionStore.new
|
435
434
|
inspector_task = InspectTask.new
|
436
435
|
scope_list = process_scope_option(options[:scope], options["exclude-scope"])
|
437
436
|
name = options[:name] || host
|
@@ -456,14 +455,27 @@ class Cli
|
|
456
455
|
inspect_options[:extract_unmanaged_files] = true
|
457
456
|
end
|
458
457
|
|
458
|
+
if options["skip-files"] && !(scope_list & ["config_files", "changed_managed_files"]).empty?
|
459
|
+
Machinery::Ui.warn("Warning: The --skip-files option is currently only supported for the " \
|
460
|
+
"\"unmanaged-files\" scope")
|
461
|
+
end
|
462
|
+
|
463
|
+
filter = prepare_filter("inspect", options)
|
464
|
+
|
459
465
|
inspector_task.inspect_system(
|
460
|
-
|
466
|
+
system_description_store,
|
467
|
+
host,
|
468
|
+
name,
|
469
|
+
CurrentUser.new,
|
470
|
+
scope_list,
|
471
|
+
filter,
|
472
|
+
inspect_options
|
461
473
|
)
|
462
474
|
|
463
|
-
Hint.show_data(:
|
475
|
+
Hint.show_data(name: name)
|
464
476
|
|
465
477
|
if !options["extract-files"] || Inspector.all_scopes.count != scope_list.count
|
466
|
-
Hint.do_complete_inspection(:
|
478
|
+
Hint.do_complete_inspection(name: name, host: host)
|
467
479
|
end
|
468
480
|
end
|
469
481
|
end
|
@@ -478,13 +490,14 @@ class Cli
|
|
478
490
|
option.
|
479
491
|
LONGDESC
|
480
492
|
command :list do |c|
|
481
|
-
c.switch :verbose, :
|
482
|
-
:
|
493
|
+
c.switch :verbose, required: false, negatable: false,
|
494
|
+
desc: "Display additional information about origin of scopes"
|
495
|
+
c.switch :short, required: false, negatable: false,
|
496
|
+
desc: "List only description names"
|
483
497
|
|
484
498
|
c.action do |global_options,options,args|
|
485
|
-
store = SystemDescriptionStore.new
|
486
499
|
task = ListTask.new
|
487
|
-
task.list(
|
500
|
+
task.list(system_description_store, options)
|
488
501
|
end
|
489
502
|
end
|
490
503
|
|
@@ -498,16 +511,14 @@ class Cli
|
|
498
511
|
LONGDESC
|
499
512
|
arg "NAME..."
|
500
513
|
command :remove do |c|
|
501
|
-
c.switch :all, :
|
502
|
-
:
|
503
|
-
c.switch :verbose, :
|
504
|
-
:
|
514
|
+
c.switch :all, negatable: false,
|
515
|
+
desc: "Remove all system descriptions"
|
516
|
+
c.switch :verbose, required: false, negatable: false,
|
517
|
+
desc: "Explain what is being done"
|
505
518
|
|
506
519
|
c.action do |global_options,options,args|
|
507
|
-
|
508
|
-
store = SystemDescriptionStore.new
|
509
520
|
task = RemoveTask.new
|
510
|
-
task.remove(
|
521
|
+
task.remove(system_description_store, args, verbose: options[:verbose], all: options[:all])
|
511
522
|
end
|
512
523
|
end
|
513
524
|
|
@@ -524,25 +535,23 @@ class Cli
|
|
524
535
|
LONGDESC
|
525
536
|
arg "NAME"
|
526
537
|
command :show do |c|
|
527
|
-
c.flag [:scope, :s], :
|
528
|
-
:
|
529
|
-
c.flag ["exclude-scope", :e], :
|
530
|
-
:
|
531
|
-
c.switch "pager", :
|
532
|
-
:
|
533
|
-
c.switch "show-diffs", :
|
534
|
-
:
|
535
|
-
c.switch "html", :
|
536
|
-
:
|
538
|
+
c.flag [:scope, :s], type: String, required: false,
|
539
|
+
desc: "Show specified scopes", arg_name: "SCOPE_LIST"
|
540
|
+
c.flag ["exclude-scope", :e], type: String, required: false,
|
541
|
+
desc: "Exclude specified scopes", arg_name: "SCOPE_LIST"
|
542
|
+
c.switch "pager", required: false, default_value: true,
|
543
|
+
desc: "Pipe output into a pager"
|
544
|
+
c.switch "show-diffs", required: false, negatable: false,
|
545
|
+
desc: "Show diffs of configuration files changes."
|
546
|
+
c.switch "html", required: false, negatable: false,
|
547
|
+
desc: "Open system description in HTML format in your web browser."
|
537
548
|
|
538
549
|
c.action do |global_options,options,args|
|
539
550
|
name = shift_arg(args, "NAME")
|
540
551
|
if name == "localhost" && !CurrentUser.new.is_root?
|
541
552
|
Machinery::Ui.puts "You need root rights to access the system description of your locally inspected system."
|
542
553
|
end
|
543
|
-
|
544
|
-
store = SystemDescriptionStore.new
|
545
|
-
description = SystemDescription.load(name, store)
|
554
|
+
description = SystemDescription.load(name, system_description_store)
|
546
555
|
scope_list = process_scope_option(options[:scope], options["exclude-scope"])
|
547
556
|
|
548
557
|
|
@@ -569,9 +578,8 @@ class Cli
|
|
569
578
|
Machinery::Ui.puts "You need root rights to access the system description of your locally inspected system."
|
570
579
|
end
|
571
580
|
|
572
|
-
store = SystemDescriptionStore.new
|
573
581
|
task = ValidateTask.new
|
574
|
-
task.validate(
|
582
|
+
task.validate(system_description_store, name)
|
575
583
|
end
|
576
584
|
end
|
577
585
|
|
@@ -581,21 +589,20 @@ class Cli
|
|
581
589
|
LONGDESC
|
582
590
|
arg "NAME"
|
583
591
|
command "upgrade-format" do |c|
|
584
|
-
c.switch :all, :
|
585
|
-
:
|
586
|
-
c.switch :force, :
|
587
|
-
:
|
592
|
+
c.switch :all, negatable: false,
|
593
|
+
desc: "Upgrade all system descriptions"
|
594
|
+
c.switch :force, default_value: false, required: false, negatable: false,
|
595
|
+
desc: "Keep backup after migration and ingnore validation errors"
|
588
596
|
|
589
597
|
c.action do |global_options,options,args|
|
590
598
|
name = shift_arg(args, "NAME") if !options[:all]
|
591
599
|
|
592
|
-
store = SystemDescriptionStore.new
|
593
600
|
task = UpgradeFormatTask.new
|
594
601
|
task.upgrade(
|
595
|
-
|
602
|
+
system_description_store,
|
596
603
|
name,
|
597
|
-
:
|
598
|
-
:
|
604
|
+
all: options[:all],
|
605
|
+
force: options[:force]
|
599
606
|
)
|
600
607
|
end
|
601
608
|
end
|
@@ -609,8 +616,7 @@ class Cli
|
|
609
616
|
c.action do |global_options,options,args|
|
610
617
|
name = shift_arg(args, "NAME")
|
611
618
|
|
612
|
-
|
613
|
-
description = SystemDescription.load(name, store)
|
619
|
+
description = SystemDescription.load(name, system_description_store)
|
614
620
|
task = GenerateHtmlTask.new
|
615
621
|
task.generate(description)
|
616
622
|
end
|
@@ -638,4 +644,46 @@ class Cli
|
|
638
644
|
end
|
639
645
|
end
|
640
646
|
end
|
647
|
+
|
648
|
+
def self.system_description_store
|
649
|
+
if ENV.has_key?("MACHINERY_DIR")
|
650
|
+
SystemDescriptionStore.new(ENV["MACHINERY_DIR"])
|
651
|
+
else
|
652
|
+
SystemDescriptionStore.new
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
|
657
|
+
def self.prepare_filter(command, options)
|
658
|
+
filter = Filter.from_default_definition(command)
|
659
|
+
|
660
|
+
skip_files = options.delete("skip-files")
|
661
|
+
if skip_files
|
662
|
+
files = skip_files.split(/(?<!\\),/) # Do not split on escaped commas
|
663
|
+
files = files.flat_map do |file|
|
664
|
+
if file.start_with?("@")
|
665
|
+
filename = File.expand_path(file[1..-1])
|
666
|
+
|
667
|
+
if !File.exists?(filename)
|
668
|
+
raise Machinery::Errors::MachineryError.new(
|
669
|
+
"The filter file '#{filename}' does not exist."
|
670
|
+
)
|
671
|
+
end
|
672
|
+
File.read(filename).lines.map(&:strip)
|
673
|
+
else
|
674
|
+
file
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
files.reject!(&:empty?) # Ignore empty filters
|
679
|
+
files.map! { |file| file.gsub("\\@", "@") } # Unescape escaped @s
|
680
|
+
files.map! { |file| file.chomp("/") } # List directories without the trailing /, in order to
|
681
|
+
# not confuse the unmanaged files inspector
|
682
|
+
files.each do |file|
|
683
|
+
filter.add_element_filter_from_definition("/unmanaged_files/files/name=#{file}")
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
687
|
+
filter
|
688
|
+
end
|
641
689
|
end
|