machinery-tool 1.16.4 → 1.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.git_revision +1 -1
- data/NEWS +10 -0
- data/filters/default_filters.json +21 -20
- data/html/assets/machinery-base.js +4 -0
- data/html/index.html.haml +1 -1
- data/html/partials/changed_managed_files.html.haml +2 -2
- data/html/partials/compare/changed_managed_file_list.html.haml +2 -2
- data/html/partials/compare/changed_managed_files.html.haml +3 -3
- data/html/partials/compare/config_file_list.html.haml +2 -2
- data/html/partials/compare/config_files.html.haml +3 -3
- data/html/partials/compare/packages.html.haml +21 -4
- data/html/partials/compare/repositories.html.haml +10 -7
- data/html/partials/compare/repository_list_apt.html.haml +15 -0
- data/html/partials/compare/repository_list_yum.html.haml +35 -0
- data/html/partials/compare/{repository_list.html.haml → repository_list_zypp.html.haml} +0 -0
- data/html/partials/compare/service_list.html.haml +1 -1
- data/html/partials/compare/services.html.haml +3 -3
- data/html/partials/compare/unmanaged_file_list.html.haml +2 -2
- data/html/partials/compare/unmanaged_files.html.haml +1 -1
- data/html/partials/config_files.html.haml +39 -41
- data/html/partials/repositories.html.haml +1 -23
- data/html/partials/repositories_apt.html.haml +15 -0
- data/html/partials/repositories_yum.html.haml +30 -0
- data/html/partials/repositories_zypp.html.haml +24 -0
- data/html/partials/services.html.haml +2 -2
- data/html/partials/unmanaged_files.html.haml +2 -2
- data/inspect_helpers/dpkg_unmanaged_files.sh +47 -0
- data/inspect_helpers/yum_repositories.py +3 -5
- data/lib/analyze_config_file_diffs_task.rb +11 -1
- data/lib/array.rb +97 -35
- data/lib/autoyast.rb +13 -2
- data/lib/cli.rb +10 -2
- data/lib/config.rb +4 -4
- data/lib/dpkg_database.rb +68 -0
- data/lib/element_filter.rb +2 -0
- data/lib/file_diff.rb +2 -2
- data/lib/file_scope.rb +10 -49
- data/lib/file_validator.rb +10 -4
- data/lib/filter.rb +6 -6
- data/lib/filter_option_parser.rb +1 -1
- data/lib/kiwi_config.rb +13 -10
- data/lib/machinery.rb +2 -0
- data/lib/machinery_helper.rb +1 -1
- data/lib/managed_files_database.rb +200 -0
- data/lib/object.rb +5 -3
- data/lib/remote_system.rb +43 -10
- data/lib/renderer.rb +3 -4
- data/lib/rpm_database.rb +7 -183
- data/lib/scope_file_access_archive.rb +3 -3
- data/lib/scope_file_access_flat.rb +1 -1
- data/lib/server.rb +7 -2
- data/lib/system.rb +50 -22
- data/lib/system_description.rb +3 -3
- data/lib/version.rb +1 -1
- data/lib/workload_mapper.rb +2 -2
- data/machinery-helper/machinery_helper.go +252 -178
- data/machinery-helper/machinery_helper_test.go +121 -121
- data/machinery-helper/mountpoints.go +28 -28
- data/machinery-helper/tar.go +105 -104
- data/machinery-helper/version.go +1 -1
- data/man/generated/machinery.1.gz +0 -0
- data/man/generated/machinery.1.html +19 -8
- data/plugins/changed_managed_files/changed_managed_files_inspector.rb +3 -3
- data/plugins/changed_managed_files/changed_managed_files_model.rb +3 -1
- data/plugins/changed_managed_files/changed_managed_files_renderer.rb +2 -2
- data/plugins/changed_managed_files/schema/system-description-changed-managed-files.schema-v6.json +168 -0
- data/plugins/config_files/config_files_inspector.rb +4 -4
- data/plugins/config_files/config_files_model.rb +3 -1
- data/plugins/config_files/config_files_renderer.rb +2 -2
- data/plugins/config_files/schema/system-description-config-files.schema-v6.json +160 -0
- data/plugins/environment/schema/system-description-environment.schema-v6.json +17 -0
- data/plugins/groups/schema/system-description-groups.schema-v6.json +49 -0
- data/plugins/os/schema/system-description-os.schema-v6.json +21 -0
- data/plugins/packages/packages_inspector.rb +76 -6
- data/plugins/packages/packages_model.rb +31 -12
- data/plugins/packages/packages_renderer.rb +5 -2
- data/plugins/packages/schema/system-description-packages.schema-v6.json +115 -0
- data/plugins/patterns/patterns_inspector.rb +26 -2
- data/plugins/patterns/schema/system-description-patterns.schema-v6.json +58 -0
- data/plugins/repositories/repositories_inspector.rb +41 -14
- data/plugins/repositories/repositories_model.rb +55 -12
- data/plugins/repositories/repositories_renderer.rb +23 -7
- data/plugins/repositories/schema/system-description-repositories.schema-v6.json +165 -0
- data/plugins/services/schema/system-description-services.schema-v6.json +93 -0
- data/plugins/services/services_inspector.rb +88 -22
- data/plugins/services/services_model.rb +9 -15
- data/plugins/services/services_renderer.rb +2 -2
- data/plugins/unmanaged_files/schema/system-description-unmanaged-files.schema-v6.json +162 -0
- data/plugins/unmanaged_files/unmanaged_files_inspector.rb +80 -30
- data/plugins/unmanaged_files/unmanaged_files_model.rb +22 -18
- data/plugins/unmanaged_files/unmanaged_files_renderer.rb +3 -3
- data/plugins/users/schema/system-description-users.schema-v6.json +86 -0
- data/schema/migrations/migrate5to6.rb +101 -0
- data/schema/system-description-global.schema-v6.json +43 -0
- metadata +24 -4
- data/html/assets/landing_page/landing_page.js +0 -10
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
3
|
+
|
4
|
+
"type": "object",
|
5
|
+
"required": ["locale"],
|
6
|
+
"properties": {
|
7
|
+
"locale": {
|
8
|
+
"type": "string",
|
9
|
+
"minLength": 1
|
10
|
+
},
|
11
|
+
"system_type": {
|
12
|
+
"type": "string",
|
13
|
+
"enum": ["local", "remote", "docker"]
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
3
|
+
|
4
|
+
"type": "object",
|
5
|
+
"required": [
|
6
|
+
"_elements"
|
7
|
+
],
|
8
|
+
"properties": {
|
9
|
+
"_attributes": {
|
10
|
+
"type": "object"
|
11
|
+
},
|
12
|
+
"_elements": {
|
13
|
+
"type": "array",
|
14
|
+
"items": {
|
15
|
+
"type": "object",
|
16
|
+
"required": [
|
17
|
+
"name",
|
18
|
+
"password",
|
19
|
+
"gid",
|
20
|
+
"users"
|
21
|
+
],
|
22
|
+
"properties": {
|
23
|
+
"name": {
|
24
|
+
"type": "string",
|
25
|
+
"minLength": 1
|
26
|
+
},
|
27
|
+
"password": {
|
28
|
+
"type": "string"
|
29
|
+
},
|
30
|
+
"gid": {
|
31
|
+
"type": [
|
32
|
+
"integer",
|
33
|
+
"null"
|
34
|
+
],
|
35
|
+
"minimum": 0
|
36
|
+
},
|
37
|
+
"users": {
|
38
|
+
"type": "array",
|
39
|
+
"items": {
|
40
|
+
"type": "string",
|
41
|
+
"minLength": 1
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
3
|
+
|
4
|
+
"type": "object",
|
5
|
+
"required": ["name", "version", "architecture"],
|
6
|
+
"properties": {
|
7
|
+
"name": {
|
8
|
+
"type": ["string", "null"],
|
9
|
+
"minLength": 1
|
10
|
+
},
|
11
|
+
"version": {
|
12
|
+
"type": ["string", "null"],
|
13
|
+
"minLength": 1
|
14
|
+
},
|
15
|
+
"architecture": {
|
16
|
+
"type": ["string", "null"],
|
17
|
+
"minLength": 1
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
@@ -23,9 +23,26 @@ class PackagesInspector < Inspector
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def inspect(_filter, _options = {})
|
26
|
-
@system.check_requirement("rpm", "--version")
|
26
|
+
@system.check_requirement(["rpm", "dpkg"], "--version")
|
27
27
|
|
28
|
-
|
28
|
+
if @system.has_command?("rpm")
|
29
|
+
inspect_rpm
|
30
|
+
elsif @system.has_command?("dpkg")
|
31
|
+
@system.check_requirement("apt-cache", "--version")
|
32
|
+
inspect_dpkg
|
33
|
+
end
|
34
|
+
|
35
|
+
@description
|
36
|
+
end
|
37
|
+
|
38
|
+
def summary
|
39
|
+
"Found #{@description.packages.length} packages."
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def inspect_rpm
|
45
|
+
packages = Machinery::Array.new
|
29
46
|
rpm_data = @system.run_command(
|
30
47
|
"rpm","-qa","--qf",
|
31
48
|
"%{NAME}|%{VERSION}|%{RELEASE}|%{ARCH}|%{VENDOR}|%{SIGMD5}$",
|
@@ -36,7 +53,7 @@ class PackagesInspector < Inspector
|
|
36
53
|
rpm_data.scan(/(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\$/).reject do |name, *attrs|
|
37
54
|
name =~ /^gpg-pubkey$/
|
38
55
|
end.each do |name, version, release, arch, vendor, checksum|
|
39
|
-
packages <<
|
56
|
+
packages << RpmPackage.new(
|
40
57
|
:name => name,
|
41
58
|
:version => version,
|
42
59
|
:release => release,
|
@@ -46,10 +63,63 @@ class PackagesInspector < Inspector
|
|
46
63
|
)
|
47
64
|
end
|
48
65
|
|
49
|
-
@description.packages = PackagesScope.new(
|
66
|
+
@description.packages = PackagesScope.new(
|
67
|
+
packages.sort_by(&:name),
|
68
|
+
package_system: "rpm"
|
69
|
+
)
|
50
70
|
end
|
51
71
|
|
52
|
-
def
|
53
|
-
|
72
|
+
def inspect_dpkg
|
73
|
+
dpkg_data = @system.run_command(
|
74
|
+
"dpkg", "-l", stdout: :capture
|
75
|
+
)
|
76
|
+
|
77
|
+
lines = dpkg_data.lines.reject { |line| !line.start_with?("ii ") }
|
78
|
+
|
79
|
+
packages = lines.map do |line|
|
80
|
+
name, version, arch = line.split[1..3]
|
81
|
+
version_segments = version.split("-")
|
82
|
+
release = version_segments.pop if version_segments.length > 1
|
83
|
+
version = version_segments.join("-")
|
84
|
+
|
85
|
+
DpkgPackage.new(
|
86
|
+
name: name,
|
87
|
+
version: version,
|
88
|
+
release: release,
|
89
|
+
arch: arch
|
90
|
+
)
|
91
|
+
end
|
92
|
+
packages.each_slice(100) do |packages_slice|
|
93
|
+
apt_cache_output = @system.run_command(
|
94
|
+
"apt-cache",
|
95
|
+
"show",
|
96
|
+
*packages_slice.map { |p| "#{p.name}=#{[p.version, p.release].compact.join("-")}" },
|
97
|
+
stdout: :capture
|
98
|
+
)
|
99
|
+
|
100
|
+
apt_cache_elements = Hash[
|
101
|
+
*apt_cache_output.split("\n\n").flat_map do |element|
|
102
|
+
name = element[/Package: (\w+)$/, 1]
|
103
|
+
[name, element]
|
104
|
+
end
|
105
|
+
]
|
106
|
+
|
107
|
+
packages_slice.each do |package|
|
108
|
+
name = package.name.sub(/:[^:]+$/, "")
|
109
|
+
apt_cache_element = apt_cache_elements[name]
|
110
|
+
if apt_cache_element
|
111
|
+
checksum = apt_cache_element[/MD5sum: (\w+)\n/, 1]
|
112
|
+
vendor = apt_cache_element[/Origin: (\w+)\n/, 1]
|
113
|
+
end
|
114
|
+
package.checksum = checksum || ""
|
115
|
+
package.vendor = vendor || ""
|
116
|
+
package.release ||= ""
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
@description.packages = PackagesScope.new(
|
121
|
+
packages.sort_by(&:name),
|
122
|
+
package_system: "dpkg"
|
123
|
+
)
|
54
124
|
end
|
55
125
|
end
|
@@ -19,22 +19,41 @@
|
|
19
19
|
class Package < Machinery::Object
|
20
20
|
end
|
21
21
|
|
22
|
+
class RpmPackage < Package
|
23
|
+
end
|
24
|
+
|
25
|
+
class DpkgPackage < Package
|
26
|
+
end
|
27
|
+
|
22
28
|
class PackagesScope < Machinery::Array
|
23
29
|
include Machinery::Scope
|
24
30
|
|
25
|
-
|
31
|
+
has_attributes :package_system
|
32
|
+
has_elements class: DpkgPackage, if: { package_system: "dpkg" }
|
33
|
+
has_elements class: RpmPackage, if: { package_system: "rpm" }
|
26
34
|
|
27
35
|
def compare_with(other)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
only_self,
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
if self.package_system != other.package_system
|
37
|
+
[self, other, nil, nil]
|
38
|
+
else
|
39
|
+
only_self = self - other
|
40
|
+
only_other = other - self
|
41
|
+
common = self & other
|
42
|
+
changed = Machinery::Scope.extract_changed_elements(only_self, only_other, :name)
|
43
|
+
changed = nil if changed.empty?
|
44
|
+
|
45
|
+
[
|
46
|
+
package_list_to_scope(only_self),
|
47
|
+
package_list_to_scope(only_other),
|
48
|
+
changed,
|
49
|
+
package_list_to_scope(common)
|
50
|
+
].map { |e| (e && !e.empty?) ? e : nil }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def package_list_to_scope(packages)
|
57
|
+
self.class.new(packages, package_system: package_system) unless packages.elements.empty?
|
39
58
|
end
|
40
59
|
end
|
@@ -23,13 +23,14 @@ class PackagesRenderer < Renderer
|
|
23
23
|
def content(description)
|
24
24
|
return unless description.packages
|
25
25
|
|
26
|
-
if description.packages.empty?
|
26
|
+
if description.packages.elements.empty?
|
27
27
|
puts "There are no packages."
|
28
28
|
end
|
29
29
|
|
30
30
|
list do
|
31
31
|
description.packages.each do |p|
|
32
|
-
|
32
|
+
vendor = !p.vendor.empty? ? p.vendor : "N/A"
|
33
|
+
item [p.name, p.version, p.release].reject(&:empty?).join("-") + ".#{p.arch} (#{vendor})"
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -37,6 +38,8 @@ class PackagesRenderer < Renderer
|
|
37
38
|
# In the comparison case we only want to show the package name, not all details like version,
|
38
39
|
# architecture etc.
|
39
40
|
def compare_content_only_in(description)
|
41
|
+
return if description.packages.empty?
|
42
|
+
|
40
43
|
list do
|
41
44
|
description.packages.each do |p|
|
42
45
|
item "#{p.name}"
|
@@ -0,0 +1,115 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
3
|
+
"type": "object",
|
4
|
+
"required": [
|
5
|
+
"_elements"
|
6
|
+
],
|
7
|
+
"oneOf": [
|
8
|
+
{
|
9
|
+
"properties": {
|
10
|
+
"_attributes": {
|
11
|
+
"type": "object",
|
12
|
+
"required": [
|
13
|
+
"package_system"
|
14
|
+
],
|
15
|
+
"properties": {
|
16
|
+
"package_system": {
|
17
|
+
"enum": ["rpm"]
|
18
|
+
}
|
19
|
+
}
|
20
|
+
},
|
21
|
+
"_elements": {
|
22
|
+
"type": "array",
|
23
|
+
"items": {
|
24
|
+
"type": "object",
|
25
|
+
"required": [
|
26
|
+
"name",
|
27
|
+
"version",
|
28
|
+
"release",
|
29
|
+
"arch",
|
30
|
+
"vendor",
|
31
|
+
"checksum"
|
32
|
+
],
|
33
|
+
"properties": {
|
34
|
+
"name": {
|
35
|
+
"type": "string",
|
36
|
+
"minLength": 1
|
37
|
+
},
|
38
|
+
"version": {
|
39
|
+
"type": "string",
|
40
|
+
"minLength": 1
|
41
|
+
},
|
42
|
+
"release": {
|
43
|
+
"type": "string"
|
44
|
+
},
|
45
|
+
"arch": {
|
46
|
+
"type": "string",
|
47
|
+
"minLength": 1
|
48
|
+
},
|
49
|
+
"vendor": {
|
50
|
+
"type": "string"
|
51
|
+
},
|
52
|
+
"checksum": {
|
53
|
+
"type": "string",
|
54
|
+
"pattern": "^[a-f0-9]+$"
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
},
|
61
|
+
{
|
62
|
+
"properties": {
|
63
|
+
"_attributes": {
|
64
|
+
"type": "object",
|
65
|
+
"required": [
|
66
|
+
"package_system"
|
67
|
+
],
|
68
|
+
"properties": {
|
69
|
+
"package_system": {
|
70
|
+
"enum": ["dpkg"]
|
71
|
+
}
|
72
|
+
}
|
73
|
+
},
|
74
|
+
"_elements": {
|
75
|
+
"type": "array",
|
76
|
+
"items": {
|
77
|
+
"type": "object",
|
78
|
+
"required": [
|
79
|
+
"name",
|
80
|
+
"version",
|
81
|
+
"release",
|
82
|
+
"arch",
|
83
|
+
"vendor",
|
84
|
+
"checksum"
|
85
|
+
],
|
86
|
+
"properties": {
|
87
|
+
"name": {
|
88
|
+
"type": "string",
|
89
|
+
"minLength": 1
|
90
|
+
},
|
91
|
+
"version": {
|
92
|
+
"type": "string",
|
93
|
+
"minLength": 1
|
94
|
+
},
|
95
|
+
"release": {
|
96
|
+
"type": "string"
|
97
|
+
},
|
98
|
+
"arch": {
|
99
|
+
"type": "string",
|
100
|
+
"minLength": 1
|
101
|
+
},
|
102
|
+
"vendor": {
|
103
|
+
"type": "string"
|
104
|
+
},
|
105
|
+
"checksum": {
|
106
|
+
"type": "string",
|
107
|
+
"pattern": "^[a-f0-9]*$"
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
]
|
115
|
+
}
|
@@ -26,10 +26,20 @@ class PatternsInspector < Inspector
|
|
26
26
|
if @system.has_command?("zypper")
|
27
27
|
@patterns_supported = true
|
28
28
|
inspect_with_zypper
|
29
|
+
elsif @system.has_command?("dpkg")
|
30
|
+
if @system.has_command?("tasksel")
|
31
|
+
@patterns_supported = true
|
32
|
+
inspect_with_tasksel
|
33
|
+
else
|
34
|
+
@patterns_supported = false
|
35
|
+
@status = "For a patterns inspection please install the package tasksel " \
|
36
|
+
"on the inspected system."
|
37
|
+
@description.patterns = PatternsScope.new
|
38
|
+
end
|
29
39
|
else
|
30
40
|
@patterns_supported = false
|
41
|
+
@status = "Patterns are not supported on this system."
|
31
42
|
@description.patterns = PatternsScope.new
|
32
|
-
"Patterns are not supported on this system."
|
33
43
|
end
|
34
44
|
end
|
35
45
|
|
@@ -37,7 +47,7 @@ class PatternsInspector < Inspector
|
|
37
47
|
if @patterns_supported
|
38
48
|
"Found #{@description.patterns.count} patterns."
|
39
49
|
else
|
40
|
-
|
50
|
+
@status
|
41
51
|
end
|
42
52
|
end
|
43
53
|
|
@@ -74,4 +84,18 @@ class PatternsInspector < Inspector
|
|
74
84
|
|
75
85
|
@description.patterns = PatternsScope.new(patterns)
|
76
86
|
end
|
87
|
+
|
88
|
+
def inspect_with_tasksel
|
89
|
+
tasksel_out = @system.run_command("tasksel", "--list-tasks", stdout: :capture)
|
90
|
+
tasklist = tasksel_out.lines.map(&:chomp)
|
91
|
+
installed = tasklist.select { |line| line.start_with?("i") }
|
92
|
+
installed.map! { |l| l.split[1] }
|
93
|
+
patterns = installed.map do |pattern|
|
94
|
+
Pattern.new(
|
95
|
+
name: pattern
|
96
|
+
)
|
97
|
+
end.uniq.sort_by(&:name)
|
98
|
+
|
99
|
+
@description.patterns = PatternsScope.new(patterns)
|
100
|
+
end
|
77
101
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
3
|
+
|
4
|
+
"type": "object",
|
5
|
+
"required": [
|
6
|
+
"_elements"
|
7
|
+
],
|
8
|
+
"properties": {
|
9
|
+
"_attributes": {
|
10
|
+
"type": "object"
|
11
|
+
},
|
12
|
+
"_elements": {
|
13
|
+
"oneof": [
|
14
|
+
{
|
15
|
+
"type": "array",
|
16
|
+
"items": {
|
17
|
+
"type": "object",
|
18
|
+
"required": [
|
19
|
+
"name",
|
20
|
+
"version",
|
21
|
+
"release"
|
22
|
+
],
|
23
|
+
"properties": {
|
24
|
+
"name": {
|
25
|
+
"type": "string",
|
26
|
+
"minLength": 1
|
27
|
+
},
|
28
|
+
"version": {
|
29
|
+
"type": "string",
|
30
|
+
"minLength": 1
|
31
|
+
},
|
32
|
+
"release": {
|
33
|
+
"type": "string",
|
34
|
+
"minLength": 1
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"type": "array",
|
41
|
+
"items": {
|
42
|
+
"type": "object",
|
43
|
+
"required": [
|
44
|
+
"name"
|
45
|
+
],
|
46
|
+
"properties": {
|
47
|
+
"name": {
|
48
|
+
"type": "string",
|
49
|
+
"minLength": 1
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
]
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|