machinery-tool 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS +12 -0
  3. data/export_helpers/autoyast_export_readme.md +48 -0
  4. data/{kiwi_helpers → export_helpers}/kiwi_export_readme.md +0 -0
  5. data/{kiwi_helpers → export_helpers}/merge_users_and_groups.pl.erb +0 -0
  6. data/{kiwi_helpers → export_helpers}/unmanaged_files_build_excludes +2 -0
  7. data/html/index.html.haml +1 -0
  8. data/lib/analyze_config_file_diffs_task.rb +11 -5
  9. data/lib/autoyast.rb +157 -7
  10. data/lib/build_task.rb +0 -10
  11. data/lib/cli.rb +14 -13
  12. data/lib/compare_task.rb +8 -1
  13. data/lib/exceptions.rb +1 -0
  14. data/lib/export_task.rb +12 -1
  15. data/lib/exporter.rb +24 -0
  16. data/lib/html.rb +1 -1
  17. data/lib/inspect_task.rb +5 -4
  18. data/lib/kiwi_config.rb +14 -11
  19. data/lib/list_task.rb +1 -1
  20. data/lib/local_system.rb +2 -1
  21. data/lib/machinery.rb +6 -0
  22. data/lib/manifest.rb +88 -0
  23. data/lib/migration.rb +2 -1
  24. data/lib/scope_file_store.rb +72 -0
  25. data/lib/system_description.rb +83 -52
  26. data/lib/system_description_memory_store.rb +28 -0
  27. data/lib/system_description_store.rb +74 -63
  28. data/lib/ui.rb +1 -1
  29. data/lib/validate_task.rb +1 -1
  30. data/lib/version.rb +1 -1
  31. data/lib/zypper.rb +40 -15
  32. data/man/generated/machinery.1.gz +0 -0
  33. data/man/generated/machinery.1.html +1144 -0
  34. data/plugins/inspect/changed_managed_files_inspector.rb +6 -4
  35. data/plugins/inspect/config_files_inspector.rb +4 -3
  36. data/plugins/inspect/patterns_inspector.rb +12 -1
  37. data/plugins/inspect/unmanaged_files_inspector.rb +31 -19
  38. data/plugins/model/os_model.rb +3 -1
  39. data/plugins/model/repositories_model.rb +3 -0
  40. data/plugins/show/config_files_renderer.rb +1 -4
  41. metadata +128 -122
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c161742e300133d4d5a6514ddfe3e4284fc29b52
4
- data.tar.gz: 28c974344534d7ad4df48e43dce31b60125bb1b1
3
+ metadata.gz: f3e26096068d827b9178938a39eead5000562a09
4
+ data.tar.gz: 78c08edb97fc7993b173cf477821f6eee75bb27c
5
5
  SHA512:
6
- metadata.gz: ddd663cea68dfa8a41b8cd8921c91436a5e70a049439ee5b628b4d628f427ef4375923f9b33e967e4d6604ba487950cad0ebed0e2b62291ba66fed49ebfa1087
7
- data.tar.gz: 285ed630148abb78038681ed823dd2079501a18ecd64d0882e642300c8d6f648b62dfb7f672e8efd4dcdfc1fc3131401cf82e88f09c6d3cdb6c886423f69302f
6
+ metadata.gz: 370cb5832ee25886ade589381967014b8bb8d746d9b3451fcd52e30d08ff32ce4a71670ab2c2debfa451d8c2673f5dc7fd5e7fbf66db76e616af7e1753d2fbfa
7
+ data.tar.gz: 74487bdaf7324bc54bf8b1a62f0437d69086570a1f61de8f7517c7c6c7d2c6debfdd8f83c60954432be28c40fa2505831bf910a80aecdcb1db879157aac582f5
data/NEWS CHANGED
@@ -1,6 +1,18 @@
1
1
  # Machinery Release Notes
2
2
 
3
3
 
4
+ ## Version 1.2.0 - Mon Dec 22 15:06:20 CET 2014 - aduffeck@suse.de
5
+
6
+ * Added AutoYaST export for system descriptions
7
+ * Handle zypper locks gracefully (gh#SUSE/machinery#415)
8
+ * Prevent scopes from being inspected multiple times (gh#SUSE/machinery#303)
9
+ * Keep already extracted results after canceling an inspection (gh#SUSE/machinery#364)
10
+ * Don't fail on file validation errors, but report them as warnings (gh#SUSE/machinery#391)
11
+ * List scopes more natural with a space after comma (gh#SUSE/machinery#356)
12
+ * Use UTF-8 for displaying HTML report (gh#SUSE/machinery#429)
13
+ * Do not ignore Btrfs subvolumes during unmanaged-files inspection (gh#SUSE/machinery#427)
14
+ * Store KIWI and AutoYaST exports in subdirectories
15
+
4
16
  ## Version 1.1.1 - Tue Dec 02 13:24:38 CET 2014 - thardeck@suse.de
5
17
 
6
18
  * Skip Gnome Virtual File System mounts on inspection (issue #393)
@@ -0,0 +1,48 @@
1
+ # README for AutoYaST export from Machinery
2
+
3
+ This directory contains an AutoYaST configuration that was exported by
4
+ Machinery.
5
+
6
+ The user is expected to be familiar with using AutoYaST.
7
+
8
+ ## Using the AutoYaST export
9
+
10
+ The export directory contains both the AutoYaST profile and additional data that
11
+ is required during installation. This directory needs to be made available to
12
+ the installer via network, e.g. by running:
13
+
14
+ cd /path/to/autoyast_export; python -m SimpleHTTPServer
15
+
16
+ You can then point the installer to the profile by specifying the AutoYaST
17
+ option on the kernel command line.
18
+
19
+ For SLES12 and openSUSE 13.2:
20
+
21
+ autoyast2=http://192.168.121.1:8000/autoinst.xml
22
+
23
+ For SLES11:
24
+
25
+ autoyast=http://192.168.121.1:8000/autoinst.xml netsetup=dhcp
26
+
27
+ ## Changing permissions of the AutoYaST export
28
+
29
+ By default the AutoYaST export is only accessible by the user. This is also the
30
+ case for all sub directories.
31
+
32
+ The installation via for example an HTTP server is only possible if all files
33
+ and sub directories are readable by the HTTP server user.
34
+ To make the export directory readable for all users run:
35
+
36
+ chmod -R a+rX /path/to/autoyast_export
37
+
38
+ ## Reference
39
+
40
+ Additional information regarding AutoYaST is available in the official documentation:
41
+
42
+ For SLES12:
43
+
44
+ https://www.suse.com/documentation/sles-12/singlehtml/book_autoyast/book_autoyast.html
45
+
46
+ For SLES11
47
+
48
+ https://www.suse.com/documentation/sles11/singlehtml/book_autoyast/book_autoyast.html
@@ -3,3 +3,5 @@ etc/passwd*
3
3
  etc/shadow*
4
4
  etc/group*
5
5
  etc/fstab
6
+ lib/mkinitrd
7
+ etc/udev/rules.d/70-persistent-net.rules
data/html/index.html.haml CHANGED
@@ -3,6 +3,7 @@
3
3
  %head
4
4
  %title
5
5
  = description.name + " - Machinery System Description"
6
+ %meta{:charset => 'utf-8'}/
6
7
  %link{:href => "assets/machinery-base.css", :rel => "stylesheet", :type => "text/css"}/
7
8
  %link{:href => "assets/machinery.css", :rel => "stylesheet", :type => "text/css"}/
8
9
  %script{:src => "assets/jquery-2.1.1.min.js"}
@@ -17,15 +17,20 @@
17
17
 
18
18
  class AnalyzeConfigFileDiffsTask
19
19
  def analyze(description)
20
- description.assert_scopes("repositories", "config_files")
20
+ description.assert_scopes(
21
+ "repositories",
22
+ "config_files",
23
+ "os"
24
+ )
21
25
  if !description.scope_extracted?("config_files")
22
26
  raise Machinery::Errors::MissingExtractedFiles.new(description, ["config_files"])
23
27
  end
24
28
 
25
29
  with_repositories(description) do |zypper|
26
- description.initialize_file_store("config-file-diffs")
27
- diffs_path = description.file_store("config-file-diffs")
28
- extracted_files_path = description.file_store("config_files")
30
+ file_store = description.scope_file_store("config-file-diffs")
31
+ file_store.create
32
+ diffs_path = file_store.path
33
+ extracted_files_path = description.scope_file_store("config_files").path
29
34
 
30
35
  Machinery::Ui.puts "Generating diffs..."
31
36
  cnt = 1
@@ -90,7 +95,8 @@ class AnalyzeConfigFileDiffsTask
90
95
 
91
96
  def with_repositories(description, &block)
92
97
  Machinery::Ui.puts "Setting up repository access..."
93
- Zypper.isolated do |zypper|
98
+ arch = description.os.architecture
99
+ Zypper.isolated(arch: arch) do |zypper|
94
100
  begin
95
101
  remote_repos = description.repositories.reject do |repo|
96
102
  repo.url.start_with?("cd://") || repo.url.start_with?("dvd://")
data/lib/autoyast.rb CHANGED
@@ -15,13 +15,44 @@
15
15
  # To contact SUSE about this file by physical or electronic mail,
16
16
  # you may find current contact information at www.suse.com
17
17
 
18
- class Autoyast
18
+ class Autoyast < Exporter
19
19
  def initialize(description)
20
+ @chroot_scripts = []
20
21
  @system_description = description
22
+ @system_description.assert_scopes(
23
+ "repositories",
24
+ "packages"
25
+ )
21
26
  end
22
27
 
23
28
  def write(output_dir)
29
+ FileUtils.cp(
30
+ File.join(Machinery::ROOT, "export_helpers/unmanaged_files_build_excludes"),
31
+ output_dir
32
+ )
33
+ # Filter log files to prevent an issue with hanging gzip during installation
34
+ File.open(File.join(output_dir, "unmanaged_files_build_excludes"), "a") do |file|
35
+ file.puts "var/log/*"
36
+ end
37
+ FileUtils.chmod(0600, File.join(output_dir, "unmanaged_files_build_excludes"))
38
+ FileUtils.cp(
39
+ File.join(Machinery::ROOT, "export_helpers/autoyast_export_readme.md"),
40
+ File.join(output_dir, "README.md")
41
+ )
42
+ Dir["#{@system_description.description_path}/*"].each do |content|
43
+ FileUtils.cp_r(content, output_dir, preserve: true)
44
+ end
24
45
  File.write(File.join(output_dir, "autoinst.xml"), profile)
46
+ FileUtils.chmod(0600, File.join(output_dir, "autoinst.xml"))
47
+ Machinery::Ui.puts(
48
+ "Note: The permssions of the AutoYaST directory are restricted to be" \
49
+ " only accessible by the current user. Further instructions are" \
50
+ " provided by the README.md in the exported directory."
51
+ )
52
+ end
53
+
54
+ def export_name
55
+ "#{@system_description.name}-autoyast"
25
56
  end
26
57
 
27
58
  def profile
@@ -31,6 +62,8 @@ class Autoyast
31
62
  "xmlns" => "http://www.suse.com/1.0/yast2ns",
32
63
  "xmlns:config" => "http://www.suse.com/1.0/configns"
33
64
  ) do
65
+ apply_non_interactive_mode(xml)
66
+ apply_basic_network(xml)
34
67
  apply_repositories(xml)
35
68
  xml.software do
36
69
  apply_packages(xml)
@@ -39,6 +72,20 @@ class Autoyast
39
72
  apply_users(xml)
40
73
  apply_groups(xml)
41
74
  apply_services(xml)
75
+
76
+ apply_extracted_files("config_files")
77
+ apply_extracted_files("changed_managed_files")
78
+ apply_unmanaged_files
79
+ xml.scripts do
80
+ apply_url_extraction(xml)
81
+ xml.send("chroot-scripts", "config:type" => "list") do
82
+ xml.script do
83
+ xml.source do
84
+ xml.cdata @chroot_scripts.join("\n")
85
+ end
86
+ end
87
+ end
88
+ end
42
89
  end
43
90
  end
44
91
 
@@ -47,19 +94,55 @@ class Autoyast
47
94
 
48
95
  private
49
96
 
97
+ def apply_non_interactive_mode(xml)
98
+ xml.general do
99
+ xml.mode do
100
+ xml.confirm "false", "config:type" => "boolean"
101
+ end
102
+ end
103
+ end
104
+
105
+ def apply_basic_network(xml)
106
+ xml.networking do
107
+ xml.keep_install_network "true", "config:type" => "boolean"
108
+ end
109
+ end
110
+
50
111
  def apply_repositories(xml)
51
112
  return if !@system_description.repositories
52
113
 
53
114
  xml.send("add-on") do
54
115
  xml.add_on_products("config:type" => "list") do
55
116
  @system_description.repositories.each do |repository|
56
- xml.listentry do
57
- xml.media_url repository.url
58
- xml.name repository.alias
117
+ if repository.enabled && !repository.external_medium?
118
+ xml.listentry do
119
+ xml.media_url repository.url
120
+ xml.name repository.alias
121
+ end
59
122
  end
60
123
  end
61
124
  end
62
125
  end
126
+
127
+ @system_description.repositories.each do |repository|
128
+ # Disabled repositories or external media can't be added by AutoYaST so we add them manually
129
+ if !repository.enabled || repository.external_medium?
130
+ zypper_ar = "zypper -n ar --name='#{repository.name}'"
131
+ zypper_ar << " --type='#{repository.type}'" if repository.type
132
+ zypper_ar << " --disable" if !repository.enabled
133
+ zypper_ar << " '#{repository.url}' '#{repository.alias}'"
134
+ @chroot_scripts << zypper_ar.strip
135
+ end
136
+
137
+ zypper_mr = "zypper -n mr --priority=#{repository.priority} '#{repository.alias}'"
138
+ zypper_mr << " --name='#{repository.name}'"
139
+ if repository.autorefresh
140
+ zypper_mr << " --refresh"
141
+ else
142
+ zypper_mr << " --no-refresh"
143
+ end
144
+ @chroot_scripts << zypper_mr.strip
145
+ end
63
146
  end
64
147
 
65
148
  def apply_packages(xml)
@@ -125,20 +208,28 @@ class Autoyast
125
208
  end
126
209
 
127
210
  def apply_services(xml)
211
+ return if !@system_description.services
212
+
128
213
  xml.send("services-manager") do
129
- xml.services do
214
+ xml.services("config:type" => "list") do
130
215
  @system_description.services.services.each do |service|
216
+ name = service.name
217
+ if @system_description.services.init_system == "systemd"
218
+ # Yast can only handle services right now
219
+ next if !(name =~ /\.service$/)
220
+ name = name.gsub(/\.service$/, "")
221
+ end
131
222
  # systemd service states like "masked" and "static" are
132
223
  # not supported by Autoyast
133
224
  if service.enabled?
134
225
  xml.service do
135
- xml.service_name service.name
226
+ xml.service_name name
136
227
  xml.service_status "enable"
137
228
  end
138
229
  end
139
230
  if service.disabled?
140
231
  xml.service do
141
- xml.service_name service.name
232
+ xml.service_name name
142
233
  xml.service_status "disable"
143
234
  end
144
235
  end
@@ -146,4 +237,63 @@ class Autoyast
146
237
  end
147
238
  end
148
239
  end
240
+
241
+ def apply_url_extraction(xml)
242
+ xml.send("pre-scripts", "config:type" => "list") do
243
+ xml.script do
244
+ xml.source do
245
+ xml.cdata 'sed -n \'/.*autoyast2\?=\(.*\)\/.*[^\s]*/s//\1/p\'' \
246
+ ' /proc/cmdline > /tmp/description_url'
247
+ end
248
+ end
249
+ end
250
+ end
251
+
252
+ def apply_extracted_files(scope)
253
+ return if !@system_description[scope] || !@system_description[scope].extracted
254
+
255
+ base = Pathname(@system_description.scope_file_store(scope).path)
256
+ Dir["#{base}/**/*"].sort.each do |path|
257
+ next if File.directory?(path)
258
+
259
+ relative_path = Pathname(path).relative_path_from(base).to_s
260
+ url = "`cat /tmp/description_url`/#{URI.escape(File.join(scope, relative_path))}"
261
+
262
+ @chroot_scripts << "mkdir -p '#{File.join("/mnt", File.dirname(relative_path))}'"
263
+ @chroot_scripts << "curl -o '#{File.join("/mnt", relative_path)}' \"#{url}\""
264
+ end
265
+
266
+ @system_description[scope].files.map do |file|
267
+ if file.user
268
+ @chroot_scripts << "chown #{file.user}:#{file.group} '#{File.join("/mnt", file.name)}'"
269
+ end
270
+ if file.mode
271
+ @chroot_scripts << "chmod #{file.mode} '#{File.join("/mnt", file.name)}'"
272
+ end
273
+ end
274
+ end
275
+
276
+ def apply_unmanaged_files
277
+ return if !@system_description.unmanaged_files ||
278
+ !@system_description.unmanaged_files.extracted
279
+
280
+ base = Pathname(@system_description.scope_file_store("unmanaged_files").path)
281
+ @chroot_scripts << <<-EOF
282
+ curl -o '/mnt/tmp/filter' "`cat /tmp/description_url`/unmanaged_files_build_excludes"
283
+ EOF
284
+
285
+ Dir["#{base}/**/*.tgz"].sort.each do |path|
286
+ next if !path.end_with?(".tgz")
287
+
288
+ relative_path = Pathname(path).relative_path_from(base).to_s
289
+ tarball_name = File.basename(path)
290
+ url = "`cat /tmp/description_url`#{URI.escape(File.join("/unmanaged_files", relative_path))}"
291
+
292
+ @chroot_scripts << <<-EOF
293
+ curl -o '/mnt/tmp/#{tarball_name}' "#{url}"
294
+ tar -C /mnt/ -X '/mnt/tmp/filter' -xf '#{File.join("/mnt/tmp", tarball_name)}'
295
+ rm '#{File.join("/mnt/tmp", tarball_name)}'
296
+ EOF
297
+ end
298
+ end
149
299
  end
data/lib/build_task.rb CHANGED
@@ -28,16 +28,6 @@ class BuildTask
28
28
  config = KiwiConfig.new(system_description, options)
29
29
  config.write(tmp_config_dir)
30
30
 
31
- if system_description["unmanaged_files"]
32
- filters = File.read(
33
- File.join(Machinery::ROOT, "kiwi_helpers/unmanaged_files_build_excludes")
34
- )
35
- Machinery::Ui.puts "\nUnmanaged files following these patterns are not added " \
36
- "to the built image:"
37
- Machinery::Ui.puts filters
38
- Machinery::Ui.puts "\n"
39
- end
40
-
41
31
  FileUtils.mkdir_p(output_path)
42
32
  if tmp_image_dir.start_with?("/tmp/") && tmp_config_dir.start_with?("/tmp/")
43
33
  tmp_script = write_kiwi_wrapper(tmp_config_dir, tmp_image_dir,
data/lib/cli.rb CHANGED
@@ -179,7 +179,7 @@ class Cli
179
179
  )
180
180
  end
181
181
 
182
- scopes
182
+ scopes.uniq
183
183
  end
184
184
 
185
185
  AVAILABLE_SCOPE_LIST = Machinery::Ui.internal_scope_list_to_string(
@@ -203,7 +203,7 @@ class Cli
203
203
  c.action do |global_options,options,args|
204
204
  name = shift_arg(args, "NAME")
205
205
  store = SystemDescriptionStore.new
206
- description = store.load(name)
206
+ description = SystemDescription.load(name, store)
207
207
 
208
208
  case options[:operation]
209
209
  when "config-file-diffs"
@@ -238,7 +238,7 @@ class Cli
238
238
  c.action do |global_options,options,args|
239
239
  name = shift_arg(args, "NAME")
240
240
  store = SystemDescriptionStore.new
241
- description = store.load(name)
241
+ description = SystemDescription.load(name, store)
242
242
 
243
243
  task = BuildTask.new
244
244
  task.build(description, File.expand_path(options["image-dir"]), {:enable_dhcp => options["enable-dhcp"], :enable_ssh => options["enable-ssh"]})
@@ -272,8 +272,8 @@ class Cli
272
272
  name1 = shift_arg(args, "NAME1")
273
273
  name2 = shift_arg(args, "NAME2")
274
274
  store = SystemDescriptionStore.new
275
- description1 = store.load(name1)
276
- description2 = store.load(name2)
275
+ description1 = SystemDescription.load(name1, store)
276
+ description2 = SystemDescription.load(name2, store)
277
277
  scope_list = process_scope_option(options[:scope], options["exclude-scope"])
278
278
 
279
279
  task = CompareTask.new
@@ -327,7 +327,7 @@ class Cli
327
327
  c.action do |global_options,options,args|
328
328
  name = shift_arg(args, "NAME")
329
329
  store = SystemDescriptionStore.new
330
- description = store.load(name)
330
+ description = SystemDescription.load(name, store)
331
331
 
332
332
  task = DeployTask.new
333
333
  opts = {
@@ -345,8 +345,8 @@ class Cli
345
345
  long_desc <<-LONGDESC
346
346
  Export system description as KIWI image description.
347
347
 
348
- The description will be placed in the given location. The image format in the
349
- description is 'vmx'.
348
+ The description will be placed in a subdirectory at the given location. The image format in
349
+ the description is 'vmx'.
350
350
  LONGDESC
351
351
  arg "NAME"
352
352
  command "export-kiwi" do |c|
@@ -358,7 +358,7 @@ class Cli
358
358
  c.action do |global_options,options,args|
359
359
  name = shift_arg(args, "NAME")
360
360
  store = SystemDescriptionStore.new
361
- description = store.load(name)
361
+ description = SystemDescription.load(name, store)
362
362
  exporter = KiwiConfig.new(description)
363
363
 
364
364
  task = ExportTask.new(exporter)
@@ -375,7 +375,8 @@ class Cli
375
375
  long_desc <<-LONGDESC
376
376
  Export system description as AutoYaST profile
377
377
 
378
- The profile will be placed in the location given by the 'autoyast-dir' option.
378
+ The profile will be placed in a subdirectory at the given location by the 'autoyast-dir'
379
+ option.
379
380
  LONGDESC
380
381
  arg "NAME"
381
382
  command "export-autoyast" do |c|
@@ -387,7 +388,7 @@ class Cli
387
388
  c.action do |_global_options, options, args|
388
389
  name = shift_arg(args, "NAME")
389
390
  store = SystemDescriptionStore.new
390
- description = store.load(name)
391
+ description = SystemDescription.load(name, store)
391
392
  exporter = Autoyast.new(description)
392
393
 
393
394
  task = ExportTask.new(exporter)
@@ -544,7 +545,7 @@ class Cli
544
545
  end
545
546
 
546
547
  store = SystemDescriptionStore.new
547
- description = store.load(name)
548
+ description = SystemDescription.load(name, store)
548
549
  scope_list = process_scope_option(options[:scope], options["exclude-scope"])
549
550
 
550
551
 
@@ -605,7 +606,7 @@ class Cli
605
606
  name = shift_arg(args, "NAME")
606
607
 
607
608
  store = SystemDescriptionStore.new
608
- description = store.load(name)
609
+ description = SystemDescription.load(name, store)
609
610
  task = GenerateHtmlTask.new
610
611
  task.generate(description)
611
612
  end