machinery-tool 1.4.0 → 1.5.0
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/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
|