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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.git_revision +1 -1
  3. data/NEWS +10 -0
  4. data/filters/default_filters.json +21 -20
  5. data/html/assets/machinery-base.js +4 -0
  6. data/html/index.html.haml +1 -1
  7. data/html/partials/changed_managed_files.html.haml +2 -2
  8. data/html/partials/compare/changed_managed_file_list.html.haml +2 -2
  9. data/html/partials/compare/changed_managed_files.html.haml +3 -3
  10. data/html/partials/compare/config_file_list.html.haml +2 -2
  11. data/html/partials/compare/config_files.html.haml +3 -3
  12. data/html/partials/compare/packages.html.haml +21 -4
  13. data/html/partials/compare/repositories.html.haml +10 -7
  14. data/html/partials/compare/repository_list_apt.html.haml +15 -0
  15. data/html/partials/compare/repository_list_yum.html.haml +35 -0
  16. data/html/partials/compare/{repository_list.html.haml → repository_list_zypp.html.haml} +0 -0
  17. data/html/partials/compare/service_list.html.haml +1 -1
  18. data/html/partials/compare/services.html.haml +3 -3
  19. data/html/partials/compare/unmanaged_file_list.html.haml +2 -2
  20. data/html/partials/compare/unmanaged_files.html.haml +1 -1
  21. data/html/partials/config_files.html.haml +39 -41
  22. data/html/partials/repositories.html.haml +1 -23
  23. data/html/partials/repositories_apt.html.haml +15 -0
  24. data/html/partials/repositories_yum.html.haml +30 -0
  25. data/html/partials/repositories_zypp.html.haml +24 -0
  26. data/html/partials/services.html.haml +2 -2
  27. data/html/partials/unmanaged_files.html.haml +2 -2
  28. data/inspect_helpers/dpkg_unmanaged_files.sh +47 -0
  29. data/inspect_helpers/yum_repositories.py +3 -5
  30. data/lib/analyze_config_file_diffs_task.rb +11 -1
  31. data/lib/array.rb +97 -35
  32. data/lib/autoyast.rb +13 -2
  33. data/lib/cli.rb +10 -2
  34. data/lib/config.rb +4 -4
  35. data/lib/dpkg_database.rb +68 -0
  36. data/lib/element_filter.rb +2 -0
  37. data/lib/file_diff.rb +2 -2
  38. data/lib/file_scope.rb +10 -49
  39. data/lib/file_validator.rb +10 -4
  40. data/lib/filter.rb +6 -6
  41. data/lib/filter_option_parser.rb +1 -1
  42. data/lib/kiwi_config.rb +13 -10
  43. data/lib/machinery.rb +2 -0
  44. data/lib/machinery_helper.rb +1 -1
  45. data/lib/managed_files_database.rb +200 -0
  46. data/lib/object.rb +5 -3
  47. data/lib/remote_system.rb +43 -10
  48. data/lib/renderer.rb +3 -4
  49. data/lib/rpm_database.rb +7 -183
  50. data/lib/scope_file_access_archive.rb +3 -3
  51. data/lib/scope_file_access_flat.rb +1 -1
  52. data/lib/server.rb +7 -2
  53. data/lib/system.rb +50 -22
  54. data/lib/system_description.rb +3 -3
  55. data/lib/version.rb +1 -1
  56. data/lib/workload_mapper.rb +2 -2
  57. data/machinery-helper/machinery_helper.go +252 -178
  58. data/machinery-helper/machinery_helper_test.go +121 -121
  59. data/machinery-helper/mountpoints.go +28 -28
  60. data/machinery-helper/tar.go +105 -104
  61. data/machinery-helper/version.go +1 -1
  62. data/man/generated/machinery.1.gz +0 -0
  63. data/man/generated/machinery.1.html +19 -8
  64. data/plugins/changed_managed_files/changed_managed_files_inspector.rb +3 -3
  65. data/plugins/changed_managed_files/changed_managed_files_model.rb +3 -1
  66. data/plugins/changed_managed_files/changed_managed_files_renderer.rb +2 -2
  67. data/plugins/changed_managed_files/schema/system-description-changed-managed-files.schema-v6.json +168 -0
  68. data/plugins/config_files/config_files_inspector.rb +4 -4
  69. data/plugins/config_files/config_files_model.rb +3 -1
  70. data/plugins/config_files/config_files_renderer.rb +2 -2
  71. data/plugins/config_files/schema/system-description-config-files.schema-v6.json +160 -0
  72. data/plugins/environment/schema/system-description-environment.schema-v6.json +17 -0
  73. data/plugins/groups/schema/system-description-groups.schema-v6.json +49 -0
  74. data/plugins/os/schema/system-description-os.schema-v6.json +21 -0
  75. data/plugins/packages/packages_inspector.rb +76 -6
  76. data/plugins/packages/packages_model.rb +31 -12
  77. data/plugins/packages/packages_renderer.rb +5 -2
  78. data/plugins/packages/schema/system-description-packages.schema-v6.json +115 -0
  79. data/plugins/patterns/patterns_inspector.rb +26 -2
  80. data/plugins/patterns/schema/system-description-patterns.schema-v6.json +58 -0
  81. data/plugins/repositories/repositories_inspector.rb +41 -14
  82. data/plugins/repositories/repositories_model.rb +55 -12
  83. data/plugins/repositories/repositories_renderer.rb +23 -7
  84. data/plugins/repositories/schema/system-description-repositories.schema-v6.json +165 -0
  85. data/plugins/services/schema/system-description-services.schema-v6.json +93 -0
  86. data/plugins/services/services_inspector.rb +88 -22
  87. data/plugins/services/services_model.rb +9 -15
  88. data/plugins/services/services_renderer.rb +2 -2
  89. data/plugins/unmanaged_files/schema/system-description-unmanaged-files.schema-v6.json +162 -0
  90. data/plugins/unmanaged_files/unmanaged_files_inspector.rb +80 -30
  91. data/plugins/unmanaged_files/unmanaged_files_model.rb +22 -18
  92. data/plugins/unmanaged_files/unmanaged_files_renderer.rb +3 -3
  93. data/plugins/users/schema/system-description-users.schema-v6.json +86 -0
  94. data/schema/migrations/migrate5to6.rb +101 -0
  95. data/schema/system-description-global.schema-v6.json +43 -0
  96. metadata +24 -4
  97. data/html/assets/landing_page/landing_page.js +0 -10
@@ -26,7 +26,7 @@
26
26
  # The sub directories storing the data for specific scopes are handled by the
27
27
  # ScopeFileStore class.
28
28
  class SystemDescription < Machinery::Object
29
- CURRENT_FORMAT_VERSION = 5
29
+ CURRENT_FORMAT_VERSION = 6
30
30
  EXTRACTABLE_SCOPES = [
31
31
  "changed_managed_files",
32
32
  "config_files",
@@ -285,7 +285,7 @@ class SystemDescription < Machinery::Object
285
285
  end
286
286
 
287
287
  def runs_service?(name)
288
- self["services"].services.any? { |service| service.name == "#{name}.service" }
288
+ self["services"].any? { |service| service.name == "#{name}.service" }
289
289
  end
290
290
 
291
291
  def has_file?(name)
@@ -300,7 +300,7 @@ class SystemDescription < Machinery::Object
300
300
  def read_config(path, key)
301
301
  EXTRACTABLE_SCOPES.each do |scope|
302
302
  if scope_extracted?(scope)
303
- file = self[scope].files.find { |f| f.name == path }
303
+ file = self[scope].find { |f| f.name == path }
304
304
  return parse_variable_assignment(file.content, key) if file
305
305
  end
306
306
  end
data/lib/version.rb CHANGED
@@ -17,6 +17,6 @@
17
17
 
18
18
  module Machinery
19
19
 
20
- VERSION = "1.16.4"
20
+ VERSION = "1.17.0"
21
21
 
22
22
  end
@@ -98,8 +98,8 @@ class WorkloadMapper
98
98
  system_description.unmanaged_files.export_files_as_tarballs(dir)
99
99
  workloads.each do |workload, config|
100
100
  config.fetch("data", {}).each do |origin, destination|
101
- file = system_description.unmanaged_files.files.find { |f| f.name == origin }
102
- file ||= system_description.config_files.files.find { |f| f.name == origin }
101
+ file = system_description.unmanaged_files.find { |f| f.name == origin }
102
+ file ||= system_description.config_files.find { |f| f.name == origin }
103
103
  if file && file.directory?
104
104
  tgz_file = File.join(dir, "trees", "#{origin.chop}.tgz")
105
105
  output_path = File.join(path, workload, destination)
@@ -18,211 +18,285 @@
18
18
  package main
19
19
 
20
20
  import (
21
- "os/exec"
22
- "bytes"
23
- "log"
24
- "strings"
25
- "io/ioutil"
26
- "encoding/json"
27
- "os"
28
- "sort"
29
- "fmt"
30
- "path/filepath"
31
- "unicode/utf8"
32
- "flag"
21
+ "bytes"
22
+ "encoding/json"
23
+ "flag"
24
+ "fmt"
25
+ "io/ioutil"
26
+ "log"
27
+ "os"
28
+ "os/exec"
29
+ "path/filepath"
30
+ "regexp"
31
+ "sort"
32
+ "strings"
33
+ "unicode/utf8"
33
34
  )
34
35
 
35
- func getRpms() []string {
36
- cmd := exec.Command("rpm", "-qlav")
37
- var out bytes.Buffer
38
- cmd.Stdout = &out
39
- err := cmd.Run()
40
- if err != nil {
41
- log.Fatal(err)
42
- }
43
-
44
- f := func(c rune) bool {
45
- return c == '\n'
46
- }
47
- packages := strings.FieldsFunc(out.String(), f)
48
- return packages
36
+ func getDpkgContent() []string {
37
+ cmd := exec.Command("bash", "-c", "dpkg --get-selections | grep -v deinstall | awk '{print $1}'")
38
+ var out bytes.Buffer
39
+ cmd.Stdout = &out
40
+ err := cmd.Run()
41
+ if err != nil {
42
+ log.Fatal(err)
43
+ }
44
+
45
+ var files []string
46
+
47
+ for _, pkg := range strings.Split(out.String(), "\n") {
48
+ cmd := exec.Command("dpkg", "-L", pkg)
49
+ var out1 bytes.Buffer
50
+ cmd.Stdout = &out1
51
+ cmd.Run()
52
+ if err != nil {
53
+ log.Fatal(err)
54
+ }
55
+
56
+ files = append(files, strings.Split(out1.String(), "\n")...)
57
+ }
58
+
59
+ return files
60
+ }
61
+
62
+ func getRpmContent() []string {
63
+ cmd := exec.Command("rpm", "-qlav")
64
+ var out bytes.Buffer
65
+ cmd.Stdout = &out
66
+ err := cmd.Run()
67
+ if err != nil {
68
+ log.Fatal(err)
69
+ }
70
+
71
+ f := func(c rune) bool {
72
+ return c == '\n'
73
+ }
74
+ files := strings.FieldsFunc(out.String(), f)
75
+ return files
49
76
  }
50
77
 
51
78
  func parseRpmLine(line string) (fileType string, fileName string, linkTarget string) {
52
- fileType = line[0:1]
53
-
54
- index := strings.Index(line, "/")
55
- if index < 0 {
56
- panic(line)
57
- }
58
- file := line[index:]
59
- fields := strings.Split(file, " -> ")
60
- if len(fields) == 2 {
61
- fileName = fields[0]
62
- linkTarget = fields[1]
63
- } else {
64
- fileName = file
65
- }
66
- return
79
+ fileType = line[0:1]
80
+
81
+ index := strings.Index(line, "/")
82
+ if index < 0 {
83
+ panic(line)
84
+ }
85
+ file := line[index:]
86
+ fields := strings.Split(file, " -> ")
87
+ if len(fields) == 2 {
88
+ fileName = fields[0]
89
+ linkTarget = fields[1]
90
+ } else {
91
+ fileName = file
92
+ }
93
+ return
67
94
  }
68
95
 
69
96
  func addImplicitlyManagedDirs(dirs map[string]bool, files map[string]string) {
70
- for file, target := range files {
71
- for i:= 1; i < len(file); i++ {
72
- if file[i] == '/' {
73
- topdir := file[:i]
74
- if _, ok := dirs[topdir]; !ok {
75
- dirs[topdir] = false
76
- }
77
- }
78
- }
79
-
80
- if target != "" {
81
- if _, ok := dirs[target]; ok {
82
- dirs[file] = false
83
- }
84
- }
85
- }
86
- return
97
+ for file, target := range files {
98
+ for i := 1; i < len(file); i++ {
99
+ if file[i] == '/' {
100
+ topdir := file[:i]
101
+ if _, ok := dirs[topdir]; !ok {
102
+ dirs[topdir] = false
103
+ }
104
+ }
105
+ }
106
+
107
+ if target != "" {
108
+ if _, ok := dirs[target]; ok {
109
+ dirs[file] = false
110
+ }
111
+ }
112
+ }
113
+ return
114
+ }
115
+
116
+ func getManagedFilesDpkg() (map[string]string, map[string]bool) {
117
+ files := make(map[string]string)
118
+ dirs := make(map[string]bool)
119
+
120
+ for _, file := range getDpkgContent() {
121
+ if len(file) > 0 {
122
+ reg := regexp.MustCompile(`/(?:$|(.+?)(?:(/.[^.]*$)|$))`)
123
+ segs := reg.FindAllString(file, -1)
124
+ if len(segs) > 0 {
125
+ fileInfo, err := os.Lstat(segs[0])
126
+
127
+ if err == nil {
128
+ if fileInfo.IsDir() {
129
+ dirs[segs[0]] = true
130
+ } else {
131
+ files[segs[0]] = ""
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ return files, dirs
139
+ }
140
+ func getManagedFilesRpm() (map[string]string, map[string]bool) {
141
+ files := make(map[string]string)
142
+ dirs := make(map[string]bool)
143
+
144
+ for _, pkg := range getRpmContent() {
145
+ if pkg != "(contains no files)" {
146
+ fileType, fileName, linkTarget := parseRpmLine(pkg)
147
+ switch fileType {
148
+ case "-":
149
+ files[fileName] = ""
150
+ case "d":
151
+ dirs[fileName] = true
152
+ case "l":
153
+ files[fileName] = linkTarget
154
+ }
155
+ }
156
+ }
157
+
158
+ addImplicitlyManagedDirs(dirs, files)
159
+
160
+ return files, dirs
161
+ }
162
+
163
+ func hasExecutable(name string) bool {
164
+ _, err := exec.LookPath(name)
165
+ if err != nil {
166
+ return false
167
+ }
168
+
169
+ return true
87
170
  }
88
171
 
89
172
  func getManagedFiles() (map[string]string, map[string]bool) {
90
- files := make(map[string]string)
91
- dirs := make(map[string]bool)
92
-
93
- for _, pkg := range getRpms() {
94
- if pkg != "(contains no files)" {
95
- fileType, fileName, linkTarget := parseRpmLine(pkg)
96
- switch fileType {
97
- case "-":
98
- files[fileName] = ""
99
- case "d":
100
- dirs[fileName] = true
101
- case "l":
102
- files[fileName] = linkTarget
103
- }
104
- }
105
- }
106
-
107
- addImplicitlyManagedDirs(dirs, files)
108
-
109
- return files, dirs
173
+ files := make(map[string]string)
174
+ dirs := make(map[string]bool)
175
+
176
+ switch {
177
+ case hasExecutable("rpm"):
178
+ files, dirs = getManagedFilesRpm()
179
+ case hasExecutable("dpkg"):
180
+ files, dirs = getManagedFilesDpkg()
181
+ }
182
+
183
+ return files, dirs
110
184
  }
111
185
 
112
186
  func assembleJSON(unmanagedFilesMap interface{}) string {
113
- jsonMap := map[string]interface{}{ "extracted": false, "files": unmanagedFilesMap }
114
- json, _ := json.MarshalIndent(jsonMap, " ", " ")
115
- return string(json)
187
+ jsonMap := map[string]interface{}{"extracted": false, "files": unmanagedFilesMap}
188
+ json, _ := json.MarshalIndent(jsonMap, " ", " ")
189
+ return string(json)
116
190
  }
117
191
 
118
192
  var readDir = func(dir string) ([]os.FileInfo, error) {
119
- return ioutil.ReadDir(dir)
193
+ return ioutil.ReadDir(dir)
120
194
  }
121
195
 
122
196
  func hasManagedDirs(dir string, rpmDirs map[string]bool) bool {
123
- for rpmDir := range rpmDirs {
124
- if strings.HasPrefix(rpmDir, dir + "/") {
125
- return true
126
- }
127
- }
128
- return false
197
+ for rpmDir := range rpmDirs {
198
+ if strings.HasPrefix(rpmDir, dir+"/") {
199
+ return true
200
+ }
201
+ }
202
+ return false
129
203
  }
130
204
 
131
205
  func findUnmanagedFiles(dir string, rpmFiles map[string]string, rpmDirs map[string]bool,
132
- unmanagedFiles map[string]string, ignoreList map[string]bool) {
133
- files, _ := readDir(dir)
134
- for _, f := range files {
135
- fileName := dir + f.Name()
136
- if !utf8.ValidString(fileName) {
137
- fmt.Fprintln(os.Stderr, fileName, "contains invalid UTF-8 characters. Skipping.")
138
- } else {
139
- if _, ok := ignoreList[fileName]; !ok {
140
- if f.IsDir() {
141
- if _, ok := rpmDirs[fileName]; ok {
142
- findUnmanagedFiles(fileName + "/", rpmFiles, rpmDirs, unmanagedFiles, ignoreList)
143
- } else {
144
- if !hasManagedDirs(fileName, rpmDirs) {
145
- unmanagedFiles[fileName + "/"] = "dir"
146
- }
147
- }
148
- } else {
149
- if _, ok := rpmFiles[fileName]; !ok {
150
- if f.Mode() &
151
- (os.ModeSocket | os.ModeNamedPipe | os.ModeDevice | os.ModeCharDevice) != 0 {
152
- // Ignore sockets, named pipes and devices
153
- } else if f.Mode() & os.ModeSymlink == os.ModeSymlink {
154
- unmanagedFiles[fileName] = "link"
155
- } else {
156
- unmanagedFiles[fileName] = "file"
157
- }
158
- }
159
- }
160
- }
161
- }
162
- }
206
+ unmanagedFiles map[string]string, ignoreList map[string]bool) {
207
+ files, _ := readDir(dir)
208
+ for _, f := range files {
209
+ fileName := dir + f.Name()
210
+ if !utf8.ValidString(fileName) {
211
+ fmt.Fprintln(os.Stderr, fileName, "contains invalid UTF-8 characters. Skipping.")
212
+ } else {
213
+ if _, ok := ignoreList[fileName]; !ok {
214
+ if f.IsDir() {
215
+ if _, ok := rpmDirs[fileName]; ok {
216
+ findUnmanagedFiles(fileName+"/", rpmFiles, rpmDirs, unmanagedFiles, ignoreList)
217
+ } else {
218
+ if !hasManagedDirs(fileName, rpmDirs) {
219
+ unmanagedFiles[fileName+"/"] = "dir"
220
+ }
221
+ }
222
+ } else {
223
+ if _, ok := rpmFiles[fileName]; !ok {
224
+ if f.Mode()&
225
+ (os.ModeSocket|os.ModeNamedPipe|os.ModeDevice|os.ModeCharDevice) != 0 {
226
+ // Ignore sockets, named pipes and devices
227
+ } else if f.Mode()&os.ModeSymlink == os.ModeSymlink {
228
+ unmanagedFiles[fileName] = "link"
229
+ } else {
230
+ unmanagedFiles[fileName] = "file"
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ }
163
237
  }
164
238
 
165
239
  func printVersion() {
166
- fmt.Println("Version:", VERSION)
167
- os.Exit(0)
240
+ fmt.Println("Version:", VERSION)
241
+ os.Exit(0)
168
242
  }
169
243
 
170
244
  func main() {
171
- // check for tar extraction
172
- if len(os.Args) >= 2 {
173
- switch os.Args[1] {
174
- case "tar":
175
- Tar(os.Args[2:])
176
- os.Exit(0)
177
- }
178
- }
179
-
180
- // parse CLI arguments
181
- var versionFlag = flag.Bool("version", false, "shows the version number")
182
- flag.Parse()
183
-
184
- // show version
185
- if (*versionFlag == true) {
186
- printVersion()
187
- }
188
-
189
- // fetch unmanaged files
190
- unmanagedFiles := make(map[string]string)
191
- thisBinary, _ := filepath.Abs(os.Args[0])
192
-
193
- ignoreList := map[string]bool{
194
- thisBinary: true,
195
- }
196
- for _, mount := range RemoteMounts() {
197
- ignoreList[mount] = true
198
- }
199
- for _, mount := range SpecialMounts() {
200
- ignoreList[mount] = true
201
- }
202
-
203
- for _, mount := range RemoteMounts() {
204
- unmanagedFiles[mount + "/"] = "remote_dir"
205
- }
206
-
207
- rpmFiles, rpmDirs := getManagedFiles()
208
- findUnmanagedFiles("/", rpmFiles, rpmDirs, unmanagedFiles, ignoreList)
209
-
210
- files := make([]string, len(unmanagedFiles))
211
- i := 0
212
- for k := range unmanagedFiles {
213
- files[i] = k
214
- i++
215
- }
216
- sort.Strings(files)
217
-
218
- unmanagedFilesMap := make([]map[string]string, len(unmanagedFiles))
219
- for j := range files {
220
- entry := make(map[string]string)
221
- entry["name"] = files[j]
222
- entry["type"] = unmanagedFiles[files[j]]
223
- unmanagedFilesMap[j] = entry
224
- }
225
-
226
- json := assembleJSON(unmanagedFilesMap)
227
- fmt.Println(json)
245
+ // check for tar extraction
246
+ if len(os.Args) >= 2 {
247
+ switch os.Args[1] {
248
+ case "tar":
249
+ Tar(os.Args[2:])
250
+ os.Exit(0)
251
+ }
252
+ }
253
+
254
+ // parse CLI arguments
255
+ var versionFlag = flag.Bool("version", false, "shows the version number")
256
+ flag.Parse()
257
+
258
+ // show version
259
+ if *versionFlag == true {
260
+ printVersion()
261
+ }
262
+
263
+ // fetch unmanaged files
264
+ unmanagedFiles := make(map[string]string)
265
+ thisBinary, _ := filepath.Abs(os.Args[0])
266
+
267
+ ignoreList := map[string]bool{
268
+ thisBinary: true,
269
+ }
270
+ for _, mount := range RemoteMounts() {
271
+ ignoreList[mount] = true
272
+ }
273
+ for _, mount := range SpecialMounts() {
274
+ ignoreList[mount] = true
275
+ }
276
+
277
+ for _, mount := range RemoteMounts() {
278
+ unmanagedFiles[mount+"/"] = "remote_dir"
279
+ }
280
+
281
+ managedFiles, managedDirs := getManagedFiles()
282
+ findUnmanagedFiles("/", managedFiles, managedDirs, unmanagedFiles, ignoreList)
283
+
284
+ files := make([]string, len(unmanagedFiles))
285
+ i := 0
286
+ for k := range unmanagedFiles {
287
+ files[i] = k
288
+ i++
289
+ }
290
+ sort.Strings(files)
291
+
292
+ unmanagedFilesMap := make([]map[string]string, len(unmanagedFiles))
293
+ for j := range files {
294
+ entry := make(map[string]string)
295
+ entry["name"] = files[j]
296
+ entry["type"] = unmanagedFiles[files[j]]
297
+ unmanagedFilesMap[j] = entry
298
+ }
299
+
300
+ json := assembleJSON(unmanagedFilesMap)
301
+ fmt.Println(json)
228
302
  }