machinery-tool 1.17.0 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (310) hide show
  1. checksums.yaml +4 -4
  2. data/.git_revision +1 -1
  3. data/NEWS +17 -1
  4. data/bin/machinery +1 -1
  5. data/export_helpers/merge_users_and_groups.pl.erb +1 -1
  6. data/html/comparison.html.haml +14 -9
  7. data/html/index.html.haml +5 -2
  8. data/html/landing_page.html.haml +4 -1
  9. data/html/partials/changed_managed_files.html.haml +2 -0
  10. data/html/partials/compare/alert.html.haml +1 -1
  11. data/html/partials/compare/unmanaged_file_list.html.haml +12 -0
  12. data/html/partials/config_files.html.haml +2 -0
  13. data/html/partials/landing_page/alert.html.haml +1 -1
  14. data/html/partials/unmanaged_files.html.haml +14 -0
  15. data/inspect_helpers/changed_files.sh +1 -1
  16. data/inspect_helpers/dpkg_unmanaged_files.sh +1 -1
  17. data/inspect_helpers/yum_repositories.py +1 -1
  18. data/lib/analyze_config_file_diffs_task.rb +1 -1
  19. data/lib/array.rb +1 -1
  20. data/lib/autoyast.rb +34 -34
  21. data/lib/build_task.rb +1 -1
  22. data/lib/cli.rb +21 -6
  23. data/lib/compare_task.rb +1 -1
  24. data/lib/comparison.rb +1 -1
  25. data/lib/config.rb +1 -1
  26. data/lib/config_base.rb +1 -1
  27. data/lib/config_task.rb +1 -1
  28. data/lib/constants.rb +2 -2
  29. data/lib/containerize_task.rb +1 -1
  30. data/lib/containerized_app.rb +1 -1
  31. data/lib/copy_task.rb +1 -1
  32. data/lib/current_user.rb +1 -1
  33. data/lib/deploy_task.rb +1 -1
  34. data/lib/docker_system.rb +4 -5
  35. data/lib/dpkg_database.rb +2 -2
  36. data/lib/element_filter.rb +1 -1
  37. data/lib/exceptions.rb +2 -2
  38. data/lib/export_task.rb +1 -1
  39. data/lib/exporter.rb +1 -1
  40. data/lib/file_diff.rb +1 -1
  41. data/lib/file_scope.rb +1 -1
  42. data/lib/file_validator.rb +1 -1
  43. data/lib/filter.rb +1 -1
  44. data/lib/filter_option_parser.rb +1 -1
  45. data/lib/helper.rb +1 -1
  46. data/lib/hint.rb +1 -1
  47. data/lib/html.rb +1 -1
  48. data/lib/inspect_task.rb +1 -1
  49. data/lib/inspector.rb +1 -1
  50. data/lib/json_schema_monkey_patch.rb +35 -0
  51. data/lib/json_validation_error_cleaner.rb +1 -1
  52. data/lib/json_validator.rb +1 -1
  53. data/lib/kiwi_config.rb +69 -67
  54. data/lib/list_task.rb +1 -1
  55. data/lib/local_system.rb +1 -1
  56. data/lib/logged_cheetah.rb +1 -1
  57. data/lib/machinery.rb +6 -2
  58. data/lib/machinery_helper.rb +28 -8
  59. data/lib/machinery_logger.rb +1 -1
  60. data/lib/man_task.rb +50 -5
  61. data/lib/managed_files_database.rb +24 -17
  62. data/lib/manifest.rb +3 -2
  63. data/lib/migration.rb +1 -1
  64. data/lib/mountpoints.rb +1 -1
  65. data/lib/move_task.rb +1 -1
  66. data/lib/object.rb +1 -1
  67. data/lib/remote_system.rb +2 -2
  68. data/lib/remove_task.rb +1 -1
  69. data/lib/renderer.rb +1 -1
  70. data/lib/renderer_helper.rb +1 -1
  71. data/lib/rpm.rb +1 -1
  72. data/lib/rpm_database.rb +1 -1
  73. data/lib/scope.rb +1 -1
  74. data/lib/scope_file_store.rb +1 -1
  75. data/lib/serve_html_task.rb +1 -1
  76. data/lib/server.rb +32 -2
  77. data/lib/show_task.rb +1 -1
  78. data/lib/system.rb +1 -1
  79. data/lib/system_description.rb +2 -2
  80. data/lib/system_description_memory_store.rb +1 -1
  81. data/lib/system_description_store.rb +1 -1
  82. data/lib/system_file.rb +1 -1
  83. data/lib/tarball.rb +1 -1
  84. data/lib/tee_io.rb +39 -0
  85. data/lib/try.rb +1 -1
  86. data/lib/ui.rb +1 -1
  87. data/lib/upgrade_format_task.rb +1 -1
  88. data/lib/validate_task.rb +1 -1
  89. data/lib/version.rb +2 -2
  90. data/lib/workload_mapper.rb +1 -1
  91. data/lib/workload_mapper_dsl.rb +1 -1
  92. data/lib/zypper.rb +3 -3
  93. data/machinery-helper/Rakefile +2 -8
  94. data/machinery-helper/file_utils.go +28 -0
  95. data/machinery-helper/file_utils_test.go +21 -0
  96. data/machinery-helper/machinery_helper.go +121 -8
  97. data/machinery-helper/machinery_helper_test.go +102 -0
  98. data/machinery-helper/mountpoints_test.go +33 -33
  99. data/machinery-helper/version.go +1 -1
  100. data/man/generated/machinery.1.gz +0 -0
  101. data/manual/custom_theme/base.html +42 -0
  102. data/manual/docs/CNAME +1 -0
  103. data/manual/docs/README.md +128 -0
  104. data/manual/docs/css/bootstrap.min.css +7 -0
  105. data/manual/docs/css/custom.css +788 -0
  106. data/manual/docs/css/fixed-positioning.css +45 -0
  107. data/manual/docs/custom.css +804 -0
  108. data/manual/docs/docs.md +7 -0
  109. data/manual/docs/favicon.png +0 -0
  110. data/manual/docs/hand3.png +0 -0
  111. data/manual/docs/img/arrow.png +0 -0
  112. data/manual/docs/img/background/1.png +0 -0
  113. data/manual/docs/img/background/2.png +0 -0
  114. data/manual/docs/img/background/3.png +0 -0
  115. data/manual/docs/img/background/4.png +0 -0
  116. data/manual/docs/img/background/5.png +0 -0
  117. data/manual/docs/img/background/6.png +0 -0
  118. data/manual/docs/img/background/7.png +0 -0
  119. data/manual/docs/img/bk-cloud.png +0 -0
  120. data/manual/docs/img/bk-sec-15.png +0 -0
  121. data/manual/docs/img/book.png +0 -0
  122. data/manual/docs/img/configuration-discovery.png +0 -0
  123. data/manual/docs/img/dot-line-left.png +0 -0
  124. data/manual/docs/img/dot-line-right.png +0 -0
  125. data/manual/docs/img/gear.png +0 -0
  126. data/manual/docs/img/gear2.png +0 -0
  127. data/manual/docs/img/gear3.png +0 -0
  128. data/manual/docs/img/hand.png +0 -0
  129. data/manual/docs/img/hand2.png +0 -0
  130. data/manual/docs/img/hand3.png +0 -0
  131. data/manual/docs/img/home2.png +0 -0
  132. data/manual/docs/img/moustache.png +0 -0
  133. data/manual/docs/img/navig.png +0 -0
  134. data/manual/docs/img/philo.png +0 -0
  135. data/manual/docs/img/service-migration.png +0 -0
  136. data/manual/docs/img/system-validation.png +0 -0
  137. data/manual/docs/img/ticket2.png +0 -0
  138. data/manual/docs/img/usecase-default.png +0 -0
  139. data/manual/docs/img/usecase1.png +0 -0
  140. data/manual/docs/img/usecase2.png +0 -0
  141. data/manual/docs/img/usecase3.png +0 -0
  142. data/manual/docs/img/usecase4.png +0 -0
  143. data/manual/docs/img/wheels.png +0 -0
  144. data/manual/docs/index.html +402 -0
  145. data/manual/docs/js/bootstrap.min.js +6 -0
  146. data/manual/docs/js/custom.js +148 -0
  147. data/manual/docs/js/jquery.js +4 -0
  148. data/manual/docs/js/jquery.nicescroll.min.js +116 -0
  149. data/manual/docs/js/jquery.pageslide.min.js +11 -0
  150. data/manual/docs/js/parallaxImg.js +146 -0
  151. data/manual/docs/js/skrollr.min.js +2 -0
  152. data/manual/docs/machinery-analyze.1.md +37 -0
  153. data/manual/docs/machinery-build.1.md +62 -0
  154. data/manual/docs/machinery-compare.1.md +63 -0
  155. data/manual/docs/machinery-config.1.md +45 -0
  156. data/manual/docs/machinery-copy.1.md +31 -0
  157. data/manual/docs/machinery-deploy.1.md +71 -0
  158. data/manual/docs/machinery-export-autoyast.1.md +58 -0
  159. data/manual/docs/machinery-export-kiwi.1.md +38 -0
  160. data/manual/docs/machinery-inspect-docker.1.md +108 -0
  161. data/manual/docs/machinery-inspect.1.md +145 -0
  162. data/manual/docs/machinery-list.1.md +51 -0
  163. data/manual/docs/machinery-man.1.md +16 -0
  164. data/manual/docs/machinery-move.1.md +29 -0
  165. data/manual/docs/machinery-remove.1.md +44 -0
  166. data/manual/docs/machinery-serve.1.md +45 -0
  167. data/manual/docs/machinery-show.1.md +63 -0
  168. data/manual/docs/machinery-upgrade-format.1.md +47 -0
  169. data/manual/docs/machinery-validate.1.md +34 -0
  170. data/manual/docs/machinery.ymp +114 -0
  171. data/manual/docs/machinery_main_general.1.md +139 -0
  172. data/manual/docs/machinery_main_scopes.1.md +98 -0
  173. data/manual/docs/machinery_main_usecases.1.md +49 -0
  174. data/manual/docs/machinery_security_implications.1.md +89 -0
  175. data/manual/docs/subcommand-template.1.md +46 -0
  176. data/manual/docs/wheels.png +0 -0
  177. data/manual/mkdocs.yml +30 -0
  178. data/manual/site/CNAME +1 -0
  179. data/manual/site/base.html +42 -0
  180. data/manual/site/css/bootstrap.min.css +7 -0
  181. data/manual/site/css/custom.css +788 -0
  182. data/manual/site/css/fixed-positioning.css +45 -0
  183. data/manual/site/custom.css +804 -0
  184. data/manual/site/docs/index.html +144 -0
  185. data/manual/site/favicon.png +0 -0
  186. data/manual/site/hand3.png +0 -0
  187. data/manual/site/img/arrow.png +0 -0
  188. data/manual/site/img/background/1.png +0 -0
  189. data/manual/site/img/background/2.png +0 -0
  190. data/manual/site/img/background/3.png +0 -0
  191. data/manual/site/img/background/4.png +0 -0
  192. data/manual/site/img/background/5.png +0 -0
  193. data/manual/site/img/background/6.png +0 -0
  194. data/manual/site/img/background/7.png +0 -0
  195. data/manual/site/img/bk-cloud.png +0 -0
  196. data/manual/site/img/bk-sec-15.png +0 -0
  197. data/manual/site/img/book.png +0 -0
  198. data/manual/site/img/configuration-discovery.png +0 -0
  199. data/manual/site/img/dot-line-left.png +0 -0
  200. data/manual/site/img/dot-line-right.png +0 -0
  201. data/manual/site/img/gear.png +0 -0
  202. data/manual/site/img/gear2.png +0 -0
  203. data/manual/site/img/gear3.png +0 -0
  204. data/manual/site/img/hand.png +0 -0
  205. data/manual/site/img/hand2.png +0 -0
  206. data/manual/site/img/hand3.png +0 -0
  207. data/manual/site/img/home2.png +0 -0
  208. data/manual/site/img/moustache.png +0 -0
  209. data/manual/site/img/navig.png +0 -0
  210. data/manual/site/img/philo.png +0 -0
  211. data/manual/site/img/service-migration.png +0 -0
  212. data/manual/site/img/system-validation.png +0 -0
  213. data/manual/site/img/ticket2.png +0 -0
  214. data/manual/site/img/usecase-default.png +0 -0
  215. data/manual/site/img/usecase1.png +0 -0
  216. data/manual/site/img/usecase2.png +0 -0
  217. data/manual/site/img/usecase3.png +0 -0
  218. data/manual/site/img/usecase4.png +0 -0
  219. data/manual/site/img/wheels.png +0 -0
  220. data/manual/site/index.html +402 -0
  221. data/manual/site/js/bootstrap.min.js +6 -0
  222. data/manual/site/js/custom.js +148 -0
  223. data/manual/site/js/jquery.js +4 -0
  224. data/manual/site/js/jquery.nicescroll.min.js +116 -0
  225. data/manual/site/js/jquery.pageslide.min.js +11 -0
  226. data/manual/site/js/parallaxImg.js +146 -0
  227. data/manual/site/js/skrollr.min.js +2 -0
  228. data/manual/site/machinery-analyze.1/index.html +167 -0
  229. data/manual/site/machinery-build.1/index.html +198 -0
  230. data/manual/site/machinery-compare.1/index.html +200 -0
  231. data/manual/site/machinery-config.1/index.html +175 -0
  232. data/manual/site/machinery-copy.1/index.html +164 -0
  233. data/manual/site/machinery-deploy.1/index.html +200 -0
  234. data/manual/site/machinery-export-autoyast.1/index.html +188 -0
  235. data/manual/site/machinery-export-kiwi.1/index.html +169 -0
  236. data/manual/site/machinery-inspect-docker.1/index.html +242 -0
  237. data/manual/site/machinery-inspect.1/index.html +283 -0
  238. data/manual/site/machinery-list.1/index.html +180 -0
  239. data/manual/site/machinery-man.1/index.html +148 -0
  240. data/manual/site/machinery-move.1/index.html +162 -0
  241. data/manual/site/machinery-remove.1/index.html +175 -0
  242. data/manual/site/machinery-serve.1/index.html +174 -0
  243. data/manual/site/machinery-show.1/index.html +199 -0
  244. data/manual/site/machinery-upgrade-format.1/index.html +173 -0
  245. data/manual/site/machinery-validate.1/index.html +161 -0
  246. data/manual/site/machinery.ymp +114 -0
  247. data/manual/site/machinery_main_general.1/index.html +260 -0
  248. data/manual/site/machinery_main_scopes.1/index.html +242 -0
  249. data/manual/site/machinery_main_usecases.1/index.html +182 -0
  250. data/manual/site/machinery_security_implications.1/index.html +223 -0
  251. data/manual/site/mkdocs/js/lunr-0.5.7.min.js +7 -0
  252. data/manual/site/mkdocs/js/mustache.min.js +1 -0
  253. data/manual/site/mkdocs/js/require.js +36 -0
  254. data/manual/site/mkdocs/js/search-results-template.mustache +4 -0
  255. data/manual/site/mkdocs/js/search.js +88 -0
  256. data/manual/site/mkdocs/js/text.js +390 -0
  257. data/manual/site/mkdocs/search_index.json +824 -0
  258. data/manual/site/sitemap.xml +152 -0
  259. data/manual/site/wheels.png +0 -0
  260. data/plugins/changed_managed_files/changed_managed_files_inspector.rb +1 -1
  261. data/plugins/changed_managed_files/changed_managed_files_model.rb +1 -1
  262. data/plugins/changed_managed_files/changed_managed_files_renderer.rb +1 -1
  263. data/plugins/changed_managed_files/schema/system-description-changed-managed-files.schema-v7.json +160 -0
  264. data/plugins/config_files/config_files_inspector.rb +1 -1
  265. data/plugins/config_files/config_files_model.rb +1 -1
  266. data/plugins/config_files/config_files_renderer.rb +1 -1
  267. data/plugins/config_files/schema/system-description-config-files.schema-v7.json +160 -0
  268. data/plugins/environment/environment_inspector.rb +1 -1
  269. data/plugins/environment/environment_model.rb +1 -1
  270. data/plugins/environment/schema/system-description-environment.schema-v7.json +17 -0
  271. data/plugins/groups/groups_inspector.rb +1 -1
  272. data/plugins/groups/groups_model.rb +1 -1
  273. data/plugins/groups/groups_renderer.rb +1 -1
  274. data/plugins/groups/schema/system-description-groups.schema-v7.json +49 -0
  275. data/plugins/os/os_inspector.rb +1 -1
  276. data/plugins/os/os_model.rb +1 -1
  277. data/plugins/os/os_renderer.rb +1 -1
  278. data/plugins/os/schema/system-description-os.schema-v7.json +21 -0
  279. data/plugins/packages/packages_inspector.rb +1 -1
  280. data/plugins/packages/packages_model.rb +1 -1
  281. data/plugins/packages/packages_renderer.rb +1 -1
  282. data/plugins/packages/schema/system-description-packages.schema-v7.json +115 -0
  283. data/plugins/patterns/patterns_inspector.rb +6 -6
  284. data/plugins/patterns/patterns_model.rb +1 -1
  285. data/plugins/patterns/patterns_renderer.rb +1 -1
  286. data/plugins/patterns/schema/system-description-patterns.schema-v7.json +58 -0
  287. data/plugins/repositories/repositories_inspector.rb +16 -16
  288. data/plugins/repositories/repositories_model.rb +1 -1
  289. data/plugins/repositories/repositories_renderer.rb +1 -1
  290. data/plugins/repositories/schema/system-description-repositories.schema-v7.json +165 -0
  291. data/plugins/services/schema/system-description-services.schema-v7.json +93 -0
  292. data/plugins/services/services_inspector.rb +1 -1
  293. data/plugins/services/services_model.rb +1 -1
  294. data/plugins/services/services_renderer.rb +1 -1
  295. data/plugins/unmanaged_files/schema/system-description-unmanaged-files.schema-v6.json +19 -61
  296. data/plugins/unmanaged_files/schema/system-description-unmanaged-files.schema-v7.json +124 -0
  297. data/plugins/unmanaged_files/unmanaged_files_inspector.rb +21 -436
  298. data/plugins/unmanaged_files/unmanaged_files_model.rb +2 -2
  299. data/plugins/unmanaged_files/unmanaged_files_renderer.rb +2 -2
  300. data/plugins/users/schema/system-description-users.schema-v7.json +86 -0
  301. data/plugins/users/users_inspector.rb +1 -1
  302. data/plugins/users/users_model.rb +1 -1
  303. data/plugins/users/users_renderer.rb +1 -1
  304. data/schema/migrations/migrate1to2.rb +1 -1
  305. data/schema/migrations/migrate6to7.rb +38 -0
  306. data/schema/system-description-global.schema-v7.json +43 -0
  307. data/tools/go.rb +92 -0
  308. data/tools/helper_builder.rb +16 -49
  309. metadata +182 -6
  310. data/man/generated/machinery.1.html +0 -1399
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2015 SUSE LLC
1
+ # Copyright (c) 2013-2016 SUSE LLC
2
2
  #
3
3
  # This program is free software; you can redistribute it and/or
4
4
  # modify it under the terms of version 3 of the GNU General Public License as
@@ -21,239 +21,18 @@ class UnmanagedFilesInspector < Inspector
21
21
  # checks if all required binaries are present
22
22
  def check_requirements(check_tar)
23
23
  @system.check_requirement(["rpm", "dpkg"], "--version")
24
- @system.check_requirement("sed", "--version")
25
- @system.check_requirement("cat", "--version")
26
- @system.check_requirement("find", "--version")
27
24
  @system.check_create_archive_dependencies if check_tar
28
25
  end
29
26
 
30
- # extract pathes from rpm database into ruby hashes
31
- def extract_rpm_database
32
- out = @system.run_command(
33
- ["rpm", "-qlav"],
34
- ["sed", "s/^\\(.\\)[^/]* /\\1 /"],
35
- :stdout => :capture
36
- )
37
-
38
- files = {}
39
- dirh = {}
40
- links = {}
41
- # result of above command is lines with type as first character, then a path
42
- # handled types are: "-" for normal files, "d" for directories, "l" for links
43
- # links have " -> " with link content after path
44
- out.each_line do |l|
45
- type = l[0]
46
- entry = l[2..-2]
47
- if type == "-"
48
- files[entry] = ""
49
- elsif type == "d"
50
- dirh[entry] = true
51
- elsif type == "l"
52
- pair = entry.split(" -> ",2)
53
- files[pair.first] = pair[1]
54
- end
55
- end
56
-
57
- process_managed_files_and_dirs(files, dirh)
58
- end
59
-
60
- def extract_dpkg_database
61
- out = @system.run_script_with_progress("dpkg_unmanaged_files.sh")
62
- parsed_data = parse_dpkg_package_files_output(out)
63
- files = parsed_data[:files]
64
- dirh = parsed_data[:directories]
65
-
66
- process_managed_files_and_dirs(files, dirh)
67
- end
68
-
69
- def process_managed_files_and_dirs(files, dirs)
70
- # make sure that all parent directories of managed rpm directories are considered
71
- # managed
72
- dirs.dup.keys.each do |d|
73
- dir = d.rpartition("/").first
74
-
75
- while !dirs.key?(dir) && dir.size > 1
76
- dirs[dir] = false
77
- dir = dir[0..dir.rindex("/") - 1]
78
- end
79
- end
80
-
81
- files.each do |f,e|
82
- dir, sep, file = f.rpartition("/")
83
-
84
- # make sure that dirs leading to a managed file are treated as if they were
85
- # in rpm database, otherwise we cannot exclude whole unmanaged trees
86
- while !dirs.key?(dir) && dir.size > 1
87
- dirs[dir] = false
88
- dir=dir[0..dir.rindex("/") - 1]
89
- end
90
-
91
- # put links to a managed directory also into directory hash
92
- if !e.empty? && dirs.key?(e)
93
- dirs[f] = false
94
- end
95
- end
96
-
97
- [files, dirs]
98
- end
99
-
100
- def parse_dpkg_package_files_output(data)
101
- result = { files: {}, directories: {} }
102
-
103
- data.each_line do |line|
104
- type, value = line.chomp.split(" ", 2)
105
-
106
- if type == "-" # file
107
- result[:files][value] = ""
108
- elsif type == "d" && value != "/." # directory
109
- result[:directories][value] = true
110
- elsif type == "l" # link
111
- pair = value.split(" -> ", 2)
112
- result[:files][pair[0]] = pair[1]
113
- end
114
- end
115
- result
116
- end
117
-
118
- def check_consistency(files, dirh)
119
- p "files=#{files.size} dirs=#{dirh.size}"
120
- p "dirs in rpmdb=#{dirh.select{|k,e| e}.size} added:#{dirh.select{|k,e| !e}.size}"
121
- list = files.select { |f| !f.start_with?("/") }
122
- p "should not happen non-abs file:#{list}" unless list.empty?
123
- list = dirh.select { |f| !f.start_with?("/") }
124
- p "should not happen non-abs dirs:#{list}" unless list.empty?
125
- end
126
-
127
- # extract metadata from extracted tar archives and put data into Object
128
- def extract_tar_metadata(osl, destdir)
129
- if Dir.exists?(destdir)
130
- tarballs = [File.join(destdir, "files.tgz")]
131
- osl.select{ |os| os.type == "dir" }.map(&:name).each do |d|
132
- base = File.dirname(d)
133
- tarballs << File.join(destdir, "trees", base, "#{File.basename(d)}.tgz")
134
- end
135
-
136
- tarballs.each do | archive|
137
- files = Tarball.new(archive).list
138
-
139
- files.each do |file|
140
- os = osl.find do |o|
141
- o.name == "/#{file[:path]}#{file[:type] == :dir ? "/" : ""}"
142
- end
143
- if !os
144
- raise Machinery::Errors::UnexpectedInputData.new(
145
- "The inspection failed because of the unexpected input data:\n#{file.inspect}\n\n" \
146
- "Please file a bug report at: https://github.com/SUSE/machinery/issues/new"
147
- )
148
- end
149
-
150
- os.user = file[:user]
151
- os.group = file[:group]
152
- if file[:type] != :link
153
- os.size = file[:size]
154
- os.mode = file[:mode]
155
- end
156
-
157
- # unmanaged dirs are trees and only have one entry in the manifest
158
- if os.type == "dir"
159
- os.size = files.map { |d| d[:size] }.reduce(:+)
160
- os.files = files.size
161
- break
162
- end
163
- end
164
- end
165
- end
166
- osl
167
- end
168
-
169
- # find paths below dir until a certain depth is reached
170
- def get_find_data(dir, depth )
171
- dep = depth - 1
172
- files = {}
173
- dirs = {}
174
-
175
- # compute command line
176
- cmd = ["find", dir, "-xdev", "-maxdepth", "1", "-maxdepth", depth.to_s]
177
- cmd += ["-printf", '%y\0%P\0%l\0']
178
-
179
- out = ""
180
- begin
181
- out = @system.run_command(
182
- *cmd,
183
- stdout: :capture,
184
- disable_logging: true,
185
- privileged: true
186
- ).force_encoding("binary")
187
- rescue Cheetah::ExecutionFailed => e
188
- out = e.stdout
189
- message = "Warning: The command find of the unmanaged-file inspector" \
190
- " ran into an issue. The error output was:\n#{e.stderr}"
191
- Machinery.logger.warn(message)
192
- Machinery::Ui.warn(message)
193
- end
194
-
195
- # find creates three field per path
196
- out.split("\0", -1).each_slice(3) do |type, raw_path, raw_link|
197
- next unless raw_path && !raw_path.empty?
198
-
199
- # Filenames can contain invalid UTF-8 characters, so we treat the data as
200
- # binary information first while splitting the raw output and then convert
201
- # the separate strings to UTF-8, replacing invalid characters with the
202
- # "REPLACEMENT CHARACTER" (U+FFFD). That way we have both the raw data
203
- # (which is needed in order to be able to access the files) and the cleaned
204
- # string which can be safely used.
205
- path = Machinery.scrub(raw_path)
206
- link = Machinery.scrub(raw_link)
207
-
208
- if [path, link].any? { |f| f.include?("\uFFFD") }
209
- broken_names = []
210
- if path.include?("\uFFFD")
211
- broken_names << "filename '#{path}'"
212
- end
213
- if link.include?("\uFFFD")
214
- broken_names << "link target '#{link}'"
215
- end
216
-
217
- warning = broken_names.join(" and ")
218
- warning += " contain#{"s" if broken_names.length == 1}"
219
- warning += " invalid UTF-8 characters. Skipping."
220
- warning[0] = warning[0].upcase
221
-
222
- Machinery.logger.warn(warning)
223
- Machinery::Ui.warn(warning)
224
- next
225
- end
226
-
227
- files[path] = link if type == "l"
228
- files[path] = "" if type == "f"
229
-
230
- # dirs at maxdepth could be non-leafs all othere are leafs
231
- dirs[path] = path.count("/") == dep if type == "d"
232
- end
233
- Machinery.logger.debug "get_find_data dir:#{dir} depth:#{depth} file:#{files.size}" \
234
- " dirs:#{dirs.size}"
235
- [files, dirs]
236
- end
237
-
238
- def max_depth
239
- 6
240
- end
241
-
242
- def start_depth
243
- 3
244
- end
245
-
246
27
  def initialize(system, description)
247
28
  @system = system
248
29
  @description = description
249
30
  end
250
31
 
251
32
  def inspect(filter, options = {})
252
- do_extract = options && options[:extract_unmanaged_files]
33
+ do_extract = options[:extract_unmanaged_files]
253
34
  check_requirements(do_extract)
254
35
 
255
- determine_package_manager
256
-
257
36
  scope = UnmanagedFilesScope.new
258
37
 
259
38
  file_store_tmp = @description.scope_file_store("unmanaged_files.tmp")
@@ -271,40 +50,26 @@ class UnmanagedFilesInspector < Inspector
271
50
  end
272
51
 
273
52
  helper = MachineryHelper.new(@system)
53
+
274
54
  if helper_usable?(helper)
275
- run_helper_inspection(helper, file_filter, do_extract, file_store_tmp, file_store_final,
276
- scope)
277
- else
278
- run_inspection(file_filter, options, do_extract, file_store_tmp, file_store_final, scope)
279
- end
280
- end
55
+ helper_options = {}
56
+ helper_options[:do_extract] = do_extract
57
+ helper_options[:extract_metadata] = options[:extract_metadata]
281
58
 
282
- def determine_package_manager
283
- if @system.has_command?("rpm")
284
- @package_manager = "rpm"
285
- elsif @system.has_command?("dpkg")
286
- @package_manager = "dpkg"
59
+ run_helper_inspection(helper, file_filter, file_store_tmp, file_store_final,
60
+ scope, helper_options)
61
+ else
62
+ raise Machinery::Errors::MissingRequirement.new(
63
+ "There is no machinery-helper available for the remote system architecture #{@system.arch}."
64
+ )
287
65
  end
288
66
  end
289
67
 
290
68
  def helper_usable?(helper)
291
- if !helper.can_help?
292
- Machinery::Ui.puts(
293
- "Note: Using traditional inspection because there is no helper binary for" \
294
- " architecture '#{@system.arch}' available."
295
- )
296
- elsif @system.respond_to?(:remote_user) && @system.remote_user != "root"
297
- Machinery::Ui.puts(
298
- "Note: Using traditional inspection because only 'root' is supported as remote user."
299
- )
300
- elsif ["rpm", "dpkg"].include?(@package_manager)
301
- return true
302
- end
303
-
304
- false
69
+ helper.can_help?
305
70
  end
306
71
 
307
- def run_helper_inspection(helper, filter, do_extract, file_store_tmp, file_store_final, scope)
72
+ def run_helper_inspection(helper, filter, file_store_tmp, file_store_final, scope, options)
308
73
  begin
309
74
  helper.inject_helper
310
75
  if !helper.has_compatible_version?
@@ -314,10 +79,13 @@ class UnmanagedFilesInspector < Inspector
314
79
  )
315
80
  end
316
81
 
317
- helper.run_helper(scope)
82
+ args = []
83
+ args.push("--extract-metadata") if options[:extract_metadata] || options[:do_extract]
84
+
85
+ helper.run_helper(scope, *args)
318
86
  scope.delete_if { |f| filter.matches?(f.name) }
319
87
 
320
- if do_extract
88
+ if options[:do_extract]
321
89
  mount_points = MountPoints.new(@system)
322
90
  excluded_trees = mount_points.remote + mount_points.special
323
91
 
@@ -333,14 +101,15 @@ class UnmanagedFilesInspector < Inspector
333
101
  show_extraction_progress(files.count + count)
334
102
  end
335
103
 
336
- scope = extract_tar_metadata(scope, file_store_tmp.path)
337
104
  file_store_final.remove
338
105
  file_store_tmp.rename(file_store_final.store_name)
339
106
  scope.scope_file_store = file_store_final
340
107
  scope.extracted = true
108
+ scope.has_metadata = true
341
109
  else
342
110
  file_store_final.remove
343
111
  scope.extracted = false
112
+ scope.has_metadata = !!options[:extract_metadata]
344
113
  end
345
114
  ensure
346
115
  helper.remove_helper
@@ -349,178 +118,6 @@ class UnmanagedFilesInspector < Inspector
349
118
  @description["unmanaged_files"] = scope
350
119
  end
351
120
 
352
- def run_inspection(file_filter, options, do_extract, file_store_tmp, file_store_final, scope)
353
- mount_points = MountPoints.new(@system)
354
-
355
- if @package_manager == "rpm"
356
- inspected_files, inspected_dirs = extract_rpm_database
357
- elsif @package_manager == "dpkg"
358
- inspected_files, inspected_dirs = extract_dpkg_database
359
- end
360
-
361
- # Btrfs subvolumes and local mounts need to be inspected separately because
362
- # they are not part of the `get_find_data` return data
363
- local_filesystems = mount_points.local + btrfs_subvolumes
364
-
365
- unmanaged_files = []
366
- unmanaged_trees = []
367
- excluded_files = []
368
- unmanaged_links = {}
369
- remote_dirs = mount_points.remote
370
- special_dirs = mount_points.special
371
-
372
-
373
- remote_dirs.delete_if { |e| file_filter.matches?(e) }
374
-
375
- excluded_files += remote_dirs
376
- excluded_files += special_dirs
377
-
378
- if options[:verbose] && !remote_dirs.empty?
379
- warning = "The content of the following remote directories is ignored:" \
380
- " #{remote_dirs.uniq.join(", ")}."
381
- Machinery.logger.warn(warning)
382
- Machinery::Ui.warn(warning)
383
- end
384
- if options[:verbose] && !special_dirs.empty?
385
- warning = "The content of the following special directories is ignored:" \
386
- " #{special_dirs.uniq.join(", ")}."
387
- Machinery.logger.warn(warning)
388
- Machinery::Ui.warn(warning)
389
- end
390
-
391
- dirs_todo = ["/"]
392
- start = start_depth
393
- max = max_depth
394
- find_count = 0
395
- sub_tree_containing_remote_fs = []
396
-
397
- while !dirs_todo.empty?
398
- find_dir = dirs_todo.first
399
-
400
- # determine files and directories below find_dir until a certain depth
401
- depth = local_filesystems.include?(find_dir) ? start : max
402
- files, dirs = get_find_data(find_dir, depth)
403
- find_count += 1
404
- find_dir += "/" if find_dir.size > 1
405
- if !local_filesystems.empty?
406
- # force all mount points to be non-leave directories (find is called with -xdev)
407
- local_filesystems.each do |mp|
408
- path = mp.sub(/^\//, "")
409
- dirs[path] = true if dirs.key?(path)
410
- end
411
- local_filesystems.reject! { |mp| dirs.has_key?(mp) }
412
- end
413
- if find_dir == "/"
414
- dirs.reject! do |dir|
415
- file_filter.matches?("/" + dir)
416
- end
417
-
418
- files.reject! do |dir|
419
- file_filter.matches?("/" + dir)
420
- end
421
- end
422
- managed, unmanaged = dirs.keys.partition { |d| inspected_dirs.key?(find_dir + d) }
423
-
424
- # unmanaged dirs lead to removal of files and dirs below that dir
425
- while !unmanaged.empty?
426
- dir = unmanaged.shift
427
-
428
- # Ignore special mounts, e.g. procfs mounts in a chroot
429
- next if special_dirs.include?(find_dir + dir)
430
-
431
- # save into list of unmanaged trees
432
- if !remote_dirs.include?(find_dir + dir)
433
- unmanaged_trees << find_dir + dir
434
- end
435
- dir = File.join(dir, "/")
436
-
437
- # find sub trees containing remote file systems
438
- remote_dirs.each do |remote_dir|
439
- if unmanaged.include?(remote_dir[1..-1])
440
- sub_tree_containing_remote_fs << remote_dir
441
- unmanaged = unmanaged.drop_while{ |d| d.start_with?(remote_dir[1...-1]) }
442
- end
443
- end
444
- # remove all possible further references starting with this subdir
445
- unmanaged = unmanaged.drop_while{ |d| d.start_with?(dir) }
446
- files.reject!{ |d| d.start_with?(dir) }
447
- end
448
-
449
- # remove all (currently known) leaf directories
450
- managed.select!{ |d| dirs[d] }
451
-
452
- # update list for still to handle directories
453
- dirs_todo.shift
454
- managed.map!{ |d| find_dir + d }
455
- dirs_todo.push(*managed)
456
-
457
- # unmanaged files are simply stored
458
- managed, unmanaged = files.keys.partition { |d| inspected_files.key?(find_dir + d) }
459
- links = unmanaged.reject { |d| files[d].empty? }
460
- unmanaged.map!{ |d| find_dir + d }
461
- unmanaged_files.push(*unmanaged)
462
- links.each { |d| unmanaged_links[find_dir + d] = "" }
463
-
464
- count = unmanaged_files.length + unmanaged_trees.length
465
- progress = Machinery::pluralize(
466
- count, " -> Found %d file or tree...", " -> Found %d files and trees...",
467
- )
468
- Machinery::Ui.progress(progress)
469
- end
470
- Machinery.logger.debug "inspect unmanaged files find calls:#{find_count} files:#{unmanaged_files.size} trees:#{unmanaged_trees.size}"
471
-
472
- processed_files = run_extraction(unmanaged_files, unmanaged_trees, unmanaged_links,
473
- excluded_files, remote_dirs, do_extract, file_store_tmp, file_store_final, scope)
474
-
475
- scope.extracted = !!do_extract
476
- scope += processed_files.sort_by(&:name)
477
- @description["unmanaged_files"] = scope
478
- end
479
-
480
- def run_extraction(unmanaged_files, unmanaged_trees, unmanaged_links, excluded_files, remote_dirs,
481
- do_extract, file_store_tmp, file_store_final, scope)
482
- begin
483
- if do_extract
484
- file_store_tmp.remove
485
- file_store_tmp.create
486
-
487
- scope.retrieve_files_from_system_as_archive(@system,
488
- unmanaged_files, excluded_files)
489
- show_extraction_progress(unmanaged_files.count)
490
-
491
- scope.retrieve_trees_from_system_as_archive(@system,
492
- unmanaged_trees, excluded_files) do |count|
493
- show_extraction_progress(unmanaged_files.count + count)
494
- end
495
- else
496
- file_store_final.remove
497
- end
498
- osl = unmanaged_files.map do |p|
499
- type = unmanaged_links.has_key?(p) ? "link" : "file"
500
- UnmanagedFile.new(name: p, type: type)
501
- end
502
- osl += unmanaged_trees.map { |p| UnmanagedFile.new( name: p + "/", type: "dir") }
503
- if do_extract
504
- osl = extract_tar_metadata(osl, file_store_tmp.path)
505
- file_store_final.remove
506
- file_store_tmp.rename(file_store_final.store_name)
507
- scope.scope_file_store = file_store_final
508
- end
509
- rescue SignalException => e
510
- # Handle SIGHUP(1), SIGINT(2) and SIGTERM(15) gracefully
511
- if [1, 2, 15].include?(e.signo)
512
- Machinery::Ui.warn "Interrupted by user. The partly extracted unmanaged-files are available" \
513
- " under '#{@description.file_store(file_store_tmp)}'"
514
- end
515
- raise
516
- end
517
- remote_dirs.each do |remote_dir|
518
- osl << UnmanagedFile.new( name: remote_dir + "/", type: "remote_dir")
519
- end
520
-
521
- osl
522
- end
523
-
524
121
  def summary
525
122
  "#{@description.unmanaged_files.extracted ? "Extracted" : "Found"} " +
526
123
  "#{@description.unmanaged_files.count} unmanaged files and trees."
@@ -534,16 +131,4 @@ class UnmanagedFilesInspector < Inspector
534
131
  )
535
132
  Machinery::Ui.progress(progress)
536
133
  end
537
-
538
- def btrfs_subvolumes
539
- if @system.has_command?("/sbin/btrfs")
540
- @system.run_command(
541
- ["/sbin/btrfs", "subvolume", "list", "/"],
542
- ["awk", "{print $NF}"],
543
- stdout: :capture
544
- ).split
545
- else
546
- []
547
- end
548
- end
549
134
  end