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
@@ -18,96 +18,96 @@
18
18
  package main
19
19
 
20
20
  import (
21
- "testing"
22
- "reflect"
23
- "os"
24
- "time"
25
- "github.com/nowk/go-fakefileinfo"
21
+ "github.com/nowk/go-fakefileinfo"
22
+ "os"
23
+ "reflect"
24
+ "testing"
25
+ "time"
26
26
  )
27
27
 
28
28
  func doTestParseRpmLine(t *testing.T, line string, expectedFileType string, expectedFileName string, expectedLinkTarget string) {
29
- fileType, fileName, linkTarget := parseRpmLine(line)
30
-
31
- if fileType != expectedFileType {
32
- t.Errorf("parseRpmLine('%s') file type = '%s', want '%s'", line, fileType, expectedFileType)
33
- }
34
- if fileName != expectedFileName {
35
- t.Errorf("parseRpmLine('%s') file name = '%s', want '%s'", line, fileName, expectedFileName)
36
- }
37
- if linkTarget != expectedLinkTarget {
38
- t.Errorf("parseRpmLine('%s') file type = '%s', want '%s'", line, linkTarget, expectedLinkTarget)
39
- }
29
+ fileType, fileName, linkTarget := parseRpmLine(line)
30
+
31
+ if fileType != expectedFileType {
32
+ t.Errorf("parseRpmLine('%s') file type = '%s', want '%s'", line, fileType, expectedFileType)
33
+ }
34
+ if fileName != expectedFileName {
35
+ t.Errorf("parseRpmLine('%s') file name = '%s', want '%s'", line, fileName, expectedFileName)
36
+ }
37
+ if linkTarget != expectedLinkTarget {
38
+ t.Errorf("parseRpmLine('%s') file type = '%s', want '%s'", line, linkTarget, expectedLinkTarget)
39
+ }
40
40
  }
41
41
 
42
42
  func TestParseRpmLineFile(t *testing.T) {
43
- line := "-rw-r--r-- 1 root root 18234080 Mar 31 11:40 /usr/lib64/libruby2.0-static.a"
43
+ line := "-rw-r--r-- 1 root root 18234080 Mar 31 11:40 /usr/lib64/libruby2.0-static.a"
44
44
 
45
- expectedFileType := "-"
46
- expectedFileName := "/usr/lib64/libruby2.0-static.a"
47
- expectedLinkTarget := ""
45
+ expectedFileType := "-"
46
+ expectedFileName := "/usr/lib64/libruby2.0-static.a"
47
+ expectedLinkTarget := ""
48
48
 
49
- doTestParseRpmLine(t, line, expectedFileType, expectedFileName, expectedLinkTarget)
49
+ doTestParseRpmLine(t, line, expectedFileType, expectedFileName, expectedLinkTarget)
50
50
  }
51
51
 
52
52
  func TestParseRpmLineDir(t *testing.T) {
53
- line := "drwxr-xr-x 2 root root 0 Mar 31 11:45 /usr/include/ruby-2.0.0/x86_64-linux/ruby"
53
+ line := "drwxr-xr-x 2 root root 0 Mar 31 11:45 /usr/include/ruby-2.0.0/x86_64-linux/ruby"
54
54
 
55
- expectedFileType := "d"
56
- expectedFileName := "/usr/include/ruby-2.0.0/x86_64-linux/ruby"
57
- expectedLinkTarget := ""
55
+ expectedFileType := "d"
56
+ expectedFileName := "/usr/include/ruby-2.0.0/x86_64-linux/ruby"
57
+ expectedLinkTarget := ""
58
58
 
59
- doTestParseRpmLine(t, line, expectedFileType, expectedFileName, expectedLinkTarget)
59
+ doTestParseRpmLine(t, line, expectedFileType, expectedFileName, expectedLinkTarget)
60
60
  }
61
61
 
62
62
  func TestParseRpmLineLink(t *testing.T) {
63
- line := "lrwxrwxrwx 1 root root 19 Mar 31 11:45 /usr/lib64/libruby2.0.so -> libruby2.0.so.2.0.0"
63
+ line := "lrwxrwxrwx 1 root root 19 Mar 31 11:45 /usr/lib64/libruby2.0.so -> libruby2.0.so.2.0.0"
64
64
 
65
- expectedFileType := "l"
66
- expectedFileName := "/usr/lib64/libruby2.0.so"
67
- expectedLinkTarget := "libruby2.0.so.2.0.0"
65
+ expectedFileType := "l"
66
+ expectedFileName := "/usr/lib64/libruby2.0.so"
67
+ expectedLinkTarget := "libruby2.0.so.2.0.0"
68
68
 
69
- doTestParseRpmLine(t, line, expectedFileType, expectedFileName, expectedLinkTarget)
69
+ doTestParseRpmLine(t, line, expectedFileType, expectedFileName, expectedLinkTarget)
70
70
  }
71
71
 
72
72
  func TestParseRpmLineFileSpaces(t *testing.T) {
73
- line := "-rw-r--r-- 1 root root 61749 Jun 26 01:56 /usr/share/kde4/templates/kipiplugins_photolayoutseditor/data/templates/a4/h/Flipping Tux Black.ple"
73
+ line := "-rw-r--r-- 1 root root 61749 Jun 26 01:56 /usr/share/kde4/templates/kipiplugins_photolayoutseditor/data/templates/a4/h/Flipping Tux Black.ple"
74
74
 
75
- expectedFileType := "-"
76
- expectedFileName := "/usr/share/kde4/templates/kipiplugins_photolayoutseditor/data/templates/a4/h/Flipping Tux Black.ple"
77
- expectedLinkTarget := ""
75
+ expectedFileType := "-"
76
+ expectedFileName := "/usr/share/kde4/templates/kipiplugins_photolayoutseditor/data/templates/a4/h/Flipping Tux Black.ple"
77
+ expectedLinkTarget := ""
78
78
 
79
- doTestParseRpmLine(t, line, expectedFileType, expectedFileName, expectedLinkTarget)
79
+ doTestParseRpmLine(t, line, expectedFileType, expectedFileName, expectedLinkTarget)
80
80
  }
81
81
 
82
82
  func TestAddImplicitlyManagedDirs(t *testing.T) {
83
- filesOriginal := map[string]string{
84
- "/abc/def/ghf/somefile": "",
85
- "/zzz": "/abc/def",
86
- }
87
- dirsOriginal := map[string]bool{
88
- "/abc/def": true,
89
- }
90
- dirsExpected := map[string]bool{
91
- "/abc": false,
92
- "/abc/def": true,
93
- "/abc/def/ghf": false,
94
- "/zzz": false,
95
- }
96
-
97
- dirs := dirsOriginal
98
-
99
- addImplicitlyManagedDirs(dirs, filesOriginal)
100
-
101
- if !reflect.DeepEqual(dirs, dirsExpected) {
102
- t.Errorf("addImplicitlyManagedDirs('%v') = '%v', want '%v'", dirsOriginal, dirs, dirsExpected)
103
- }
83
+ filesOriginal := map[string]string{
84
+ "/abc/def/ghf/somefile": "",
85
+ "/zzz": "/abc/def",
86
+ }
87
+ dirsOriginal := map[string]bool{
88
+ "/abc/def": true,
89
+ }
90
+ dirsExpected := map[string]bool{
91
+ "/abc": false,
92
+ "/abc/def": true,
93
+ "/abc/def/ghf": false,
94
+ "/zzz": false,
95
+ }
96
+
97
+ dirs := dirsOriginal
98
+
99
+ addImplicitlyManagedDirs(dirs, filesOriginal)
100
+
101
+ if !reflect.DeepEqual(dirs, dirsExpected) {
102
+ t.Errorf("addImplicitlyManagedDirs('%v') = '%v', want '%v'", dirsOriginal, dirs, dirsExpected)
103
+ }
104
104
  }
105
105
 
106
106
  func TestAssembleJSON(t *testing.T) {
107
- unmanagedFilesMap := map[string]string{
108
- "name": "/usr/share/go_rulez", "type":"file",
109
- }
110
- want := `{
107
+ unmanagedFilesMap := map[string]string{
108
+ "name": "/usr/share/go_rulez", "type": "file",
109
+ }
110
+ want := `{
111
111
  "extracted": false,
112
112
  "files": {
113
113
  "name": "/usr/share/go_rulez",
@@ -115,78 +115,78 @@ func TestAssembleJSON(t *testing.T) {
115
115
  }
116
116
  }`
117
117
 
118
- json := assembleJSON(unmanagedFilesMap)
119
- if !reflect.DeepEqual(json, want) {
120
- t.Errorf("assembleJSON() = '%v', want '%v'", json, want)
121
- }
118
+ json := assembleJSON(unmanagedFilesMap)
119
+ if !reflect.DeepEqual(json, want) {
120
+ t.Errorf("assembleJSON() = '%v', want '%v'", json, want)
121
+ }
122
122
  }
123
123
 
124
124
  func TestRespectManagedDirsInUnmanagedDirs(t *testing.T) {
125
- unmanagedFiles := make(map[string]string)
126
- wantUnmanagedFiles := make(map[string]string)
127
-
128
- /*
129
- We mock the readDir method and return following directory structure:
130
- /
131
- /managed_dir/
132
- /managed_dir/unmanaged_dir/
133
- /managed_dir/unmanaged_dir/managed_dir/
134
- */
135
- readDir = func(dir string) ([]os.FileInfo, error) {
136
- dirs := make([]os.FileInfo, 0, 1)
137
- var fi os.FileInfo
138
- switch dir {
139
- case "/":
140
- fi = fakefileinfo.New("managed_dir", int64(123), os.ModeType, time.Now(), true, nil)
141
- case "/managed_dir/":
142
- fi = fakefileinfo.New("unmanaged_dir", int64(123), os.ModeType, time.Now(), true, nil)
143
- case "/managed_dir/unmanaged_dir/":
144
- fi = fakefileinfo.New("managed_dir", int64(123), os.ModeType, time.Now(), true, nil)
145
- }
146
- dirs = append (dirs, fi)
147
- return dirs, nil
148
- }
149
-
150
- rpmFiles := make(map[string]string)
151
- ignoreList := make(map[string]bool)
152
-
153
- rpmDirs := map[string]bool{
154
- "/managed_dir": true,
155
- "/managed_dir/unmanaged_dir/managed_dir": true,
156
- }
157
-
158
- findUnmanagedFiles("/", rpmFiles, rpmDirs, unmanagedFiles, ignoreList)
159
-
160
- if !reflect.DeepEqual(unmanagedFiles, wantUnmanagedFiles) {
161
- t.Errorf("findUnmanagedFiles() = '%v', want '%v'", unmanagedFiles, wantUnmanagedFiles)
162
- }
125
+ unmanagedFiles := make(map[string]string)
126
+ wantUnmanagedFiles := make(map[string]string)
127
+
128
+ /*
129
+ We mock the readDir method and return following directory structure:
130
+ /
131
+ /managed_dir/
132
+ /managed_dir/unmanaged_dir/
133
+ /managed_dir/unmanaged_dir/managed_dir/
134
+ */
135
+ readDir = func(dir string) ([]os.FileInfo, error) {
136
+ dirs := make([]os.FileInfo, 0, 1)
137
+ var fi os.FileInfo
138
+ switch dir {
139
+ case "/":
140
+ fi = fakefileinfo.New("managed_dir", int64(123), os.ModeType, time.Now(), true, nil)
141
+ case "/managed_dir/":
142
+ fi = fakefileinfo.New("unmanaged_dir", int64(123), os.ModeType, time.Now(), true, nil)
143
+ case "/managed_dir/unmanaged_dir/":
144
+ fi = fakefileinfo.New("managed_dir", int64(123), os.ModeType, time.Now(), true, nil)
145
+ }
146
+ dirs = append(dirs, fi)
147
+ return dirs, nil
148
+ }
149
+
150
+ rpmFiles := make(map[string]string)
151
+ ignoreList := make(map[string]bool)
152
+
153
+ rpmDirs := map[string]bool{
154
+ "/managed_dir": true,
155
+ "/managed_dir/unmanaged_dir/managed_dir": true,
156
+ }
157
+
158
+ findUnmanagedFiles("/", rpmFiles, rpmDirs, unmanagedFiles, ignoreList)
159
+
160
+ if !reflect.DeepEqual(unmanagedFiles, wantUnmanagedFiles) {
161
+ t.Errorf("findUnmanagedFiles() = '%v', want '%v'", unmanagedFiles, wantUnmanagedFiles)
162
+ }
163
163
  }
164
164
 
165
165
  func TestHasManagedDirs(t *testing.T) {
166
- rpmDirs := map[string]bool{
167
- "/managed_dir": true,
168
- "/managed_dir/unmanaged_dir/sub_dir/managed_dir": true,
169
- }
166
+ rpmDirs := map[string]bool{
167
+ "/managed_dir": true,
168
+ "/managed_dir/unmanaged_dir/sub_dir/managed_dir": true,
169
+ }
170
170
 
171
- hasDirs := hasManagedDirs("/managed_dir/unmanaged_dir", rpmDirs)
172
- want := true
171
+ hasDirs := hasManagedDirs("/managed_dir/unmanaged_dir", rpmDirs)
172
+ want := true
173
173
 
174
- if hasDirs != want {
175
- t.Errorf("hasManagedDirs() = '%v', want '%v'", hasDirs, want)
176
- }
174
+ if hasDirs != want {
175
+ t.Errorf("hasManagedDirs() = '%v', want '%v'", hasDirs, want)
176
+ }
177
177
 
178
178
  }
179
179
 
180
180
  func TestSubdirIsNotAccidentallyConsideredManaged(t *testing.T) {
181
- rpmDirs := map[string]bool{
182
- "/usr": true,
183
- "/usr/foobar": true,
184
- }
181
+ rpmDirs := map[string]bool{
182
+ "/usr": true,
183
+ "/usr/foobar": true,
184
+ }
185
185
 
186
- hasDirs := hasManagedDirs("/usr/foo", rpmDirs)
187
- want := false
186
+ hasDirs := hasManagedDirs("/usr/foo", rpmDirs)
187
+ want := false
188
188
 
189
- if hasDirs != want {
190
- t.Errorf("hasManagedDirs() = '%v', want '%v'", hasDirs, want)
191
- }
189
+ if hasDirs != want {
190
+ t.Errorf("hasManagedDirs() = '%v', want '%v'", hasDirs, want)
191
+ }
192
192
  }
@@ -18,9 +18,9 @@
18
18
  package main
19
19
 
20
20
  import (
21
- "io/ioutil"
22
- "strings"
23
- "sort"
21
+ "io/ioutil"
22
+ "sort"
23
+ "strings"
24
24
  )
25
25
 
26
26
  // this specifies the path of the process mounts. This needs to be
@@ -29,53 +29,53 @@ var ProcMountsPath = "/proc/mounts"
29
29
 
30
30
  var remoteFileSystems = []string{"autofs", "cifs", "nfs", "nfs4"}
31
31
  var specialFileSystems = []string{"proc", "sysfs", "devtmpfs", "tmpfs", "rpc_pipefs", "fuse.gvfs-fuse-daemon"}
32
- var localFileSystems = []string{"ext2", "ext3", "ext4", "reiserfs", "btrfs", "vfat", "xfs", "jfs"}
32
+ var localFileSystems = []string{"ext2", "ext3", "ext4", "reiserfs", "btrfs", "vfat", "xfs", "jfs"}
33
33
 
34
34
  func parseMounts() map[string]string {
35
- mount, _ := ioutil.ReadFile(ProcMountsPath)
36
- mounts := make(map[string]string)
35
+ mount, _ := ioutil.ReadFile(ProcMountsPath)
36
+ mounts := make(map[string]string)
37
37
 
38
- lines := strings.Split(string(mount), "\n")
38
+ lines := strings.Split(string(mount), "\n")
39
39
 
40
- for _, line := range(lines) {
41
- elements := strings.Split(line, " ")
40
+ for _, line := range lines {
41
+ elements := strings.Split(line, " ")
42
42
 
43
- if len(elements) >= 3 {
44
- mounts[elements[1]] = elements[2]
45
- }
46
- }
43
+ if len(elements) >= 3 {
44
+ mounts[elements[1]] = elements[2]
45
+ }
46
+ }
47
47
 
48
- return mounts
48
+ return mounts
49
49
  }
50
50
 
51
- func selectFileSystems(allMounts map[string]string, fileSystems[]string) []string {
52
- mounts := []string{}
51
+ func selectFileSystems(allMounts map[string]string, fileSystems []string) []string {
52
+ mounts := []string{}
53
53
 
54
- for path, fs := range(allMounts) {
55
- for _, specialFs := range fileSystems {
56
- if specialFs == fs {
57
- mounts = append(mounts, path)
58
- }
59
- }
60
- }
61
- sort.Strings(mounts)
54
+ for path, fs := range allMounts {
55
+ for _, specialFs := range fileSystems {
56
+ if specialFs == fs {
57
+ mounts = append(mounts, path)
58
+ }
59
+ }
60
+ }
61
+ sort.Strings(mounts)
62
62
 
63
- return mounts
63
+ return mounts
64
64
  }
65
65
 
66
66
  // SpecialMounts returns an array of all special mount paths like
67
67
  // proc or sysfs
68
68
  func SpecialMounts() []string {
69
- return selectFileSystems(parseMounts(), specialFileSystems)
69
+ return selectFileSystems(parseMounts(), specialFileSystems)
70
70
  }
71
71
 
72
72
  // LocalMounts returns an array of all local mount paths
73
73
  func LocalMounts() []string {
74
- return selectFileSystems(parseMounts(), localFileSystems)
74
+ return selectFileSystems(parseMounts(), localFileSystems)
75
75
  }
76
76
 
77
77
  // RemoteMounts returns an array of all remote mount paths
78
78
  // (for example NFS mount points)
79
79
  func RemoteMounts() []string {
80
- return selectFileSystems(parseMounts(), remoteFileSystems)
80
+ return selectFileSystems(parseMounts(), remoteFileSystems)
81
81
  }
@@ -18,27 +18,28 @@
18
18
  package main
19
19
 
20
20
  import (
21
- "flag"
22
- "os"
23
- "io"
24
- "bufio"
25
- "strings"
26
- "archive/tar"
27
- "compress/gzip"
28
- "fmt"
29
- "path/filepath"
30
- "os/user"
31
- "strconv"
32
- "os/exec"
21
+ "archive/tar"
22
+ "bufio"
23
+ "compress/gzip"
24
+ "flag"
25
+ "fmt"
26
+ "io"
27
+ "os"
28
+ "os/exec"
29
+ "os/user"
30
+ "path/filepath"
31
+ "strconv"
32
+ "strings"
33
33
  )
34
34
 
35
35
  type stringArrayFlag []string
36
+
36
37
  func (i *stringArrayFlag) String() string {
37
- return "exclude"
38
+ return "exclude"
38
39
  }
39
40
  func (i *stringArrayFlag) Set(value string) error {
40
- *i = append(*i, value)
41
- return nil
41
+ *i = append(*i, value)
42
+ return nil
42
43
  }
43
44
 
44
45
  var excludeList = make(map[string]bool)
@@ -46,97 +47,97 @@ var gzipWriter = gzip.NewWriter(os.Stdout)
46
47
  var tarWriter = tar.NewWriter(gzipWriter)
47
48
 
48
49
  func addPath(path string, info os.FileInfo, err error) error {
49
- if err != nil {
50
- return err
51
- }
52
-
53
- if stat, err := os.Lstat(path); err == nil {
54
- if _, ok := excludeList[strings.TrimRight(path, "/")]; ok {
55
- return nil
56
- }
57
-
58
- linkTarget := ""
59
- if(stat.Mode() & os.ModeSymlink != 0) {
60
- if linkTarget, err= os.Readlink(path); err != nil {
61
- return err
62
- }
63
- }
64
- header, err := tar.FileInfoHeader(stat, linkTarget)
65
- header.Name = strings.TrimLeft(path, "/")
66
- if err != nil {
67
- return err
68
- }
69
-
70
- username, err := user.LookupId(strconv.Itoa(header.Uid))
71
- if err != nil {
72
- return err
73
- }
74
- header.Uname = username.Username
75
-
76
- groupname, err := exec.Command("bash", "-c",
77
- fmt.Sprintf("getent group %d | cut -d: -f1", header.Gid)).Output()
78
- if err != nil {
79
- return err
80
- }
81
- header.Gname = strings.TrimSpace(string(groupname))
82
-
83
- if err := tarWriter.WriteHeader(header); err != nil {
84
- return err
85
- }
86
-
87
- if stat.Mode().IsRegular() {
88
- file, err := os.Open(path)
89
- if err != nil {
90
- return err
91
- }
92
- defer file.Close()
93
-
94
- if _, err := io.Copy(tarWriter, file); err != nil {
95
- return err
96
- }
97
- }
98
- }
99
- return nil
50
+ if err != nil {
51
+ return err
52
+ }
53
+
54
+ if stat, err := os.Lstat(path); err == nil {
55
+ if _, ok := excludeList[strings.TrimRight(path, "/")]; ok {
56
+ return nil
57
+ }
58
+
59
+ linkTarget := ""
60
+ if stat.Mode()&os.ModeSymlink != 0 {
61
+ if linkTarget, err = os.Readlink(path); err != nil {
62
+ return err
63
+ }
64
+ }
65
+ header, err := tar.FileInfoHeader(stat, linkTarget)
66
+ header.Name = strings.TrimLeft(path, "/")
67
+ if err != nil {
68
+ return err
69
+ }
70
+
71
+ username, err := user.LookupId(strconv.Itoa(header.Uid))
72
+ if err != nil {
73
+ return err
74
+ }
75
+ header.Uname = username.Username
76
+
77
+ groupname, err := exec.Command("bash", "-c",
78
+ fmt.Sprintf("getent group %d | cut -d: -f1", header.Gid)).Output()
79
+ if err != nil {
80
+ return err
81
+ }
82
+ header.Gname = strings.TrimSpace(string(groupname))
83
+
84
+ if err := tarWriter.WriteHeader(header); err != nil {
85
+ return err
86
+ }
87
+
88
+ if stat.Mode().IsRegular() {
89
+ file, err := os.Open(path)
90
+ if err != nil {
91
+ return err
92
+ }
93
+ defer file.Close()
94
+
95
+ if _, err := io.Copy(tarWriter, file); err != nil {
96
+ return err
97
+ }
98
+ }
99
+ }
100
+ return nil
100
101
  }
101
102
 
102
103
  // Tar represents the "tar" command for the machinery-helper
103
104
  func Tar(args []string) {
104
- var files []string
105
- tarCommand := flag.NewFlagSet("tar", flag.ExitOnError)
106
- tarCommand.Bool("create", true, "Create an tar archive")
107
- tarCommand.Bool("gzip", true, "Compress archive using GZip")
108
- tarCommand.Bool("null", true, "Read null-terminated names")
109
- filesFromFlag := tarCommand.String("files-from", "", "Where to take the file list from")
110
-
111
- var excludeFlag stringArrayFlag
112
- tarCommand.Var(&excludeFlag, "exclude", "Read null-terminated names")
113
-
114
- tarCommand.Parse(args)
115
- for _, path := range(excludeFlag) {
116
- excludeList[path] = true
117
- }
118
-
119
- if(*filesFromFlag == "-") {
120
- reader := bufio.NewReader(os.Stdin)
121
-
122
- for {
123
- s, err := reader.ReadString('\x00')
124
-
125
- files = append(files, strings.TrimRight(strings.TrimSpace(s), "\x00"))
126
-
127
- if err == io.EOF {
128
- break
129
- }
130
- }
131
- } else {
132
- files = tarCommand.Args()
133
- }
134
-
135
- for i := range files {
136
- if err := filepath.Walk(files[i], addPath); err != nil {
137
- fmt.Fprintln(os.Stderr, "Error:", err)
138
- }
139
- }
140
- defer gzipWriter.Close()
141
- defer tarWriter.Close()
105
+ var files []string
106
+ tarCommand := flag.NewFlagSet("tar", flag.ExitOnError)
107
+ tarCommand.Bool("create", true, "Create an tar archive")
108
+ tarCommand.Bool("gzip", true, "Compress archive using GZip")
109
+ tarCommand.Bool("null", true, "Read null-terminated names")
110
+ filesFromFlag := tarCommand.String("files-from", "", "Where to take the file list from")
111
+
112
+ var excludeFlag stringArrayFlag
113
+ tarCommand.Var(&excludeFlag, "exclude", "Read null-terminated names")
114
+
115
+ tarCommand.Parse(args)
116
+ for _, path := range excludeFlag {
117
+ excludeList[path] = true
118
+ }
119
+
120
+ if *filesFromFlag == "-" {
121
+ reader := bufio.NewReader(os.Stdin)
122
+
123
+ for {
124
+ s, err := reader.ReadString('\x00')
125
+
126
+ files = append(files, strings.TrimRight(strings.TrimSpace(s), "\x00"))
127
+
128
+ if err == io.EOF {
129
+ break
130
+ }
131
+ }
132
+ } else {
133
+ files = tarCommand.Args()
134
+ }
135
+
136
+ for i := range files {
137
+ if err := filepath.Walk(files[i], addPath); err != nil {
138
+ fmt.Fprintln(os.Stderr, "Error:", err)
139
+ }
140
+ }
141
+ defer gzipWriter.Close()
142
+ defer tarWriter.Close()
142
143
  }