machinery-tool 1.13.0 → 1.14.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.
- checksums.yaml +4 -4
- data/.git_revision +1 -0
- data/NEWS +10 -0
- data/bin/machinery +7 -1
- data/{helpers → filters}/default_filters.json +0 -0
- data/{helpers → filters}/filter-packages-for-build.yaml +0 -0
- data/{helpers → inspect_helpers}/changed_files.sh +0 -0
- data/{helpers → inspect_helpers}/yum_repositories.py +0 -0
- data/lib/cli.rb +136 -52
- data/lib/compare_task.rb +1 -1
- data/lib/constants.rb +1 -1
- data/lib/docker_system.rb +135 -0
- data/lib/exceptions.rb +3 -2
- data/lib/filter.rb +1 -1
- data/lib/hint.rb +8 -2
- data/lib/inspect_task.rb +3 -3
- data/lib/kiwi_config.rb +2 -2
- data/lib/list_task.rb +14 -7
- data/lib/local_system.rb +20 -2
- data/lib/machinery.rb +2 -0
- data/lib/machinery_helper.rb +17 -14
- data/lib/move_task.rb +22 -0
- data/lib/remote_system.rb +4 -0
- data/lib/scope_file_access_archive.rb +10 -0
- data/lib/scope_file_access_flat.rb +4 -0
- data/lib/show_task.rb +1 -1
- data/lib/system.rb +16 -2
- data/lib/system_description.rb +19 -9
- data/lib/system_description_store.rb +10 -0
- data/lib/version.rb +1 -1
- data/lib/workload_mapper.rb +2 -1
- data/machinery-helper/README.md +13 -0
- data/machinery-helper/Rakefile +124 -0
- data/machinery-helper/machinery_helper.go +228 -0
- data/machinery-helper/machinery_helper_test.go +192 -0
- data/machinery-helper/mountpoints.go +81 -0
- data/machinery-helper/mountpoints_test.go +74 -0
- data/machinery-helper/tar.go +142 -0
- data/machinery-helper/version.go +5 -0
- data/man/generated/machinery.1.gz +0 -0
- data/man/generated/machinery.1.html +43 -6
- data/plugins/changed_managed_files/changed_managed_files_inspector.rb +1 -1
- data/plugins/config_files/config_files_inspector.rb +1 -1
- data/plugins/config_files/config_files_renderer.rb +1 -1
- data/plugins/environment/environment_inspector.rb +2 -2
- data/plugins/environment/schema/system-description-environment.schema-v5.json +4 -0
- data/plugins/os/os_inspector.rb +23 -11
- data/plugins/repositories/repositories_inspector.rb +1 -1
- data/plugins/services/services_inspector.rb +6 -1
- data/plugins/unmanaged_files/unmanaged_files_inspector.rb +35 -30
- data/plugins/unmanaged_files/unmanaged_files_model.rb +12 -6
- data/workload_mapper/docker-registry/clue.rb +0 -2
- data/workload_mapper/docker-registry/compose-template.yml +2 -1
- data/workload_mapper/docker-registry/container/Dockerfile +1 -1
- data/workload_mapper/mariadb/clue.rb +1 -0
- data/workload_mapper/mariadb/compose-template.yml +2 -2
- data/workload_mapper/rails/compose-template.yml +0 -1
- data/workload_mapper/rails/container/Dockerfile +3 -4
- data/workload_mapper/wordpress/clue.rb +13 -0
- data/workload_mapper/wordpress/compose-template.yml +5 -0
- data/workload_mapper/wordpress/config/wp-config.php +38 -0
- data/workload_mapper/wordpress/container/Dockerfile +25 -0
- data/workload_mapper/wordpress/container/apache2/listen.conf +1 -0
- data/workload_mapper/wordpress/container/apache2/wordpress_vhost.conf +21 -0
- data/workload_mapper/wordpress/setup/setup.rb.erb +67 -0
- metadata +26 -8
- data/helpers/inspector_files.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b08cffd58243c0597dfd04d3eda40b7decf833a
|
4
|
+
data.tar.gz: 771159d8c4b48a44fb59d653ed0021af78f5210b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1435204f235b9abbccd1815f16c8dcae31d226b94bbf84f34e642eb8c5c973cfaaf7ba0182eb20d606d253902e27a374477fb2d18df29ac3a33512cd5d0052ba
|
7
|
+
data.tar.gz: 9d2083f79fe8d6c32e65d6234638040c644f82b370285d648f721ebcd0290b912e524f8c94c90d9e56e2fd4a769bcd6a2b4afe89b36fd09585648205c924bbda
|
data/.git_revision
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
9787fc1eff835522740423ff35c98b78205b31cb
|
data/NEWS
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
# Machinery Release Notes
|
2
2
|
|
3
3
|
|
4
|
+
## Version 1.14.0 - Tue Oct 06 21:26:12 CEST 2015 - thardeck@suse.de
|
5
|
+
|
6
|
+
* The machinery-helper is now built during gem-installation on x86_64
|
7
|
+
machines if Go is available. The RPM package is still shipped with
|
8
|
+
a precompiled version.
|
9
|
+
* Allow limiting the `list` command output to certain system descriptions
|
10
|
+
by passing them along as argument (gh#SUSE/machinery#1398)
|
11
|
+
* Add `move` command to rename system descriptions (gh#SUSE/machinery#1397)
|
12
|
+
* Add inspection of RPM based Docker containers
|
13
|
+
|
4
14
|
## Version 1.13.0 - Tue Sep 15 18:06:00 CEST 2015 - thardeck@suse.de
|
5
15
|
|
6
16
|
* Fix: Show `Files extracted` status in `compare --html` when both
|
data/bin/machinery
CHANGED
@@ -20,9 +20,15 @@
|
|
20
20
|
require_relative '../lib/machinery'
|
21
21
|
|
22
22
|
begin
|
23
|
+
if Dir.exist?(File.join(Machinery::ROOT, ".git"))
|
24
|
+
Dir.chdir(File.join(Machinery::ROOT, "machinery-helper")) do
|
25
|
+
Cheetah.run("rake", "build")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
23
29
|
LocalSystem.validate_machinery_compatibility
|
24
30
|
Machinery.initialize_logger(ENV["MACHINERY_LOG_FILE"] || Machinery::DEFAULT_LOG_FILE)
|
25
|
-
command_log = "Executing (Version #{Machinery::VERSION}) '#{$
|
31
|
+
command_log = "Executing (Version #{Machinery::VERSION}) '#{$PROGRAM_NAME} #{ARGV.join(" ")}'"
|
26
32
|
command_log += " (store: #{ENV["MACHINERY_DIR"]})" if ENV["MACHINERY_DIR"]
|
27
33
|
Machinery.logger.info command_log
|
28
34
|
Cli.run(ARGV)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/cli.rb
CHANGED
@@ -43,11 +43,17 @@ class Cli
|
|
43
43
|
post do |global_options,command,options,args|
|
44
44
|
if command.is_a?(GLI::Commands::Help) && !global_options[:version] && ARGV == ["help"]
|
45
45
|
|
46
|
+
Machinery::Ui.puts "\nFor more detailed information, open the man page by typing 'man " \
|
47
|
+
"machinery'.\nIf you are unable to find a solution within the man page visit our wiki " \
|
48
|
+
"page\nat https://github.com/SUSE/machinery/wiki"
|
49
|
+
|
46
50
|
Machinery::Ui.puts "\nMachinery can show hints which guide through a typical workflow."
|
47
51
|
if @config.hints
|
48
|
-
Machinery::Ui.puts "These hints can be switched off by
|
52
|
+
Machinery::Ui.puts "These hints can be switched off by " \
|
53
|
+
"'#{Hint.program_name} config hints=off'."
|
49
54
|
else
|
50
|
-
Machinery::Ui.puts "These hints can be switched on by
|
55
|
+
Machinery::Ui.puts "These hints can be switched on by " \
|
56
|
+
"'#{Hint.program_name} config hints=on'."
|
51
57
|
end
|
52
58
|
|
53
59
|
Hint.print(:get_started)
|
@@ -91,7 +97,7 @@ class Cli
|
|
91
97
|
OptionParser::MissingArgument, OptionParser::AmbiguousOption
|
92
98
|
Machinery::Ui.error e.to_s + "\n\n"
|
93
99
|
command = ARGV & @commands.keys.map(&:to_s)
|
94
|
-
Machinery::Ui.error "Run '#{
|
100
|
+
Machinery::Ui.error "Run '#{Hint.program_name} #{command.first} --help' for more information."
|
95
101
|
exit 1
|
96
102
|
when Machinery::Errors::MachineryError
|
97
103
|
Machinery.logger.error(e.message)
|
@@ -398,6 +404,23 @@ class Cli
|
|
398
404
|
end
|
399
405
|
end
|
400
406
|
|
407
|
+
desc "Move system description"
|
408
|
+
long_desc <<-LONGDESC
|
409
|
+
Move a system description.
|
410
|
+
|
411
|
+
The system description name is changed to the provided name.
|
412
|
+
LONGDESC
|
413
|
+
arg "FROM_NAME"
|
414
|
+
arg "TO_NAME"
|
415
|
+
command "move" do |c|
|
416
|
+
c.action do |_global_options, _options, args|
|
417
|
+
from = shift_arg(args, "FROM_NAME")
|
418
|
+
to = shift_arg(args, "TO_NAME")
|
419
|
+
task = MoveTask.new
|
420
|
+
task.move(system_description_store, from, to)
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
401
424
|
|
402
425
|
desc "Deploy image to OpenStack cloud"
|
403
426
|
long_desc <<-LONGDESC
|
@@ -487,18 +510,7 @@ class Cli
|
|
487
510
|
end
|
488
511
|
end
|
489
512
|
|
490
|
-
|
491
|
-
long_desc <<-LONGDESC
|
492
|
-
Inspect running system and generate system descripton from inspected data.
|
493
|
-
|
494
|
-
Multiple scopes can be passed as comma-separated list. If no specific scopes
|
495
|
-
are given, all scopes are inspected.
|
496
|
-
|
497
|
-
Available scopes: #{AVAILABLE_SCOPE_LIST}
|
498
|
-
LONGDESC
|
499
|
-
arg "HOSTNAME"
|
500
|
-
command "inspect" do |c|
|
501
|
-
supports_filtering(c)
|
513
|
+
def self.define_inspect_command_options(c)
|
502
514
|
c.flag [:name, :n], type: String, required: false, arg_name: "NAME",
|
503
515
|
desc: "Store system description under the specified name"
|
504
516
|
c.flag [:scope, :s], type: String, required: false,
|
@@ -523,49 +535,71 @@ class Cli
|
|
523
535
|
desc: "Print inspection result"
|
524
536
|
c.switch :verbose, required: false, negatable: false,
|
525
537
|
desc: "Display the filters which are used during inspection"
|
538
|
+
end
|
526
539
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
scope_list = process_scope_option(options[:scope], options["exclude-scope"])
|
531
|
-
name = options[:name] || host
|
540
|
+
def self.parse_inspect_command_options(host, options)
|
541
|
+
scope_list = process_scope_option(options[:scope], options["exclude-scope"])
|
542
|
+
name = options[:name] || host
|
532
543
|
|
533
544
|
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
545
|
+
if !scope_list.empty?
|
546
|
+
inspected_scopes = " for #{Machinery::Ui.internal_scope_list_to_string(scope_list)}"
|
547
|
+
end
|
548
|
+
Machinery::Ui.puts "Inspecting #{host}#{inspected_scopes}..."
|
538
549
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
inspect_options[:remote_user] = options["remote-user"]
|
550
|
+
inspect_options = {}
|
551
|
+
if options["show"]
|
552
|
+
inspect_options[:show] = true
|
553
|
+
end
|
554
|
+
if options["verbose"]
|
555
|
+
inspect_options[:verbose] = true
|
556
|
+
end
|
557
|
+
if options["extract-files"] || options["extract-changed-config-files"]
|
558
|
+
inspect_options[:extract_changed_config_files] = true
|
559
|
+
end
|
560
|
+
if options["extract-files"] || options["extract-changed-managed-files"]
|
561
|
+
inspect_options[:extract_changed_managed_files] = true
|
562
|
+
end
|
563
|
+
if options["extract-files"] || options["extract-unmanaged-files"]
|
564
|
+
inspect_options[:extract_unmanaged_files] = true
|
565
|
+
end
|
556
566
|
|
557
|
-
|
567
|
+
filter = FilterOptionParser.parse("inspect", options)
|
558
568
|
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
569
|
+
if options["verbose"] && !filter.empty?
|
570
|
+
Machinery::Ui.puts "\nThe following filters are applied during inspection:"
|
571
|
+
Machinery::Ui.puts filter.to_array.join("\n") + "\n\n"
|
572
|
+
else
|
573
|
+
show_filter_note(scope_list, filter)
|
574
|
+
end
|
575
|
+
|
576
|
+
[name, scope_list, inspect_options, filter]
|
577
|
+
end
|
578
|
+
|
579
|
+
desc "Inspect running system"
|
580
|
+
long_desc <<-LONGDESC
|
581
|
+
Inspect running system and generate system descripton from inspected data.
|
582
|
+
|
583
|
+
Multiple scopes can be passed as comma-separated list. If no specific scopes
|
584
|
+
are given, all scopes are inspected.
|
585
|
+
|
586
|
+
Available scopes: #{AVAILABLE_SCOPE_LIST}
|
587
|
+
LONGDESC
|
588
|
+
arg "HOSTNAME"
|
589
|
+
command "inspect" do |c|
|
590
|
+
supports_filtering(c)
|
591
|
+
define_inspect_command_options(c)
|
592
|
+
|
593
|
+
c.action do |_global_options, options, args|
|
594
|
+
host = shift_arg(args, "HOSTNAME")
|
595
|
+
system = System.for(host, options["remote-user"])
|
596
|
+
inspector_task = InspectTask.new
|
597
|
+
|
598
|
+
name, scope_list, inspect_options, filter = parse_inspect_command_options(host, options)
|
565
599
|
|
566
600
|
inspector_task.inspect_system(
|
567
601
|
system_description_store,
|
568
|
-
|
602
|
+
system,
|
569
603
|
name,
|
570
604
|
CurrentUser.new,
|
571
605
|
scope_list,
|
@@ -581,15 +615,64 @@ class Cli
|
|
581
615
|
end
|
582
616
|
end
|
583
617
|
|
618
|
+
desc "Inspect container image"
|
619
|
+
long_desc <<-LONGDESC
|
620
|
+
Inspect container image and generate system descripton from inspected data.
|
621
|
+
|
622
|
+
Multiple scopes can be passed as comma-separated list. If no specific scopes
|
623
|
+
are given, all scopes are inspected.
|
624
|
+
|
625
|
+
Available scopes: #{AVAILABLE_SCOPE_LIST}
|
626
|
+
LONGDESC
|
627
|
+
arg "IMAGENAME"
|
628
|
+
command "inspect-container" do |c|
|
629
|
+
supports_filtering(c)
|
630
|
+
define_inspect_command_options(c)
|
631
|
+
c.switch ["docker", :d], required: true, negatable: false,
|
632
|
+
desc: "Inspect a docker container"
|
633
|
+
|
634
|
+
c.action do |_global_options, options, args|
|
635
|
+
image = shift_arg(args, "IMAGENAME")
|
636
|
+
system = DockerSystem.new(image)
|
637
|
+
inspector_task = InspectTask.new
|
638
|
+
|
639
|
+
name, scope_list, inspect_options, filter = parse_inspect_command_options(image, options)
|
640
|
+
|
641
|
+
begin
|
642
|
+
system.start
|
643
|
+
inspector_task.inspect_system(
|
644
|
+
system_description_store,
|
645
|
+
system,
|
646
|
+
name,
|
647
|
+
CurrentUser.new,
|
648
|
+
scope_list,
|
649
|
+
filter,
|
650
|
+
inspect_options
|
651
|
+
)
|
652
|
+
ensure
|
653
|
+
system.stop
|
654
|
+
end
|
584
655
|
|
585
656
|
|
657
|
+
Hint.print(:show_data, name: name)
|
658
|
+
|
659
|
+
if !options["extract-files"] || Inspector.all_scopes.count != scope_list.count
|
660
|
+
Hint.print(:do_complete_inspection, name: name, docker_container: image)
|
661
|
+
end
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
586
665
|
desc "List system descriptions"
|
587
666
|
long_desc <<-LONGDESC
|
588
|
-
List system descriptions and their stored scopes.
|
667
|
+
List all system descriptions and their stored scopes, when no NAME parameter is specified.
|
668
|
+
|
669
|
+
List only the specified system descriptions and its stored scopes, when NAME parameter is given.
|
589
670
|
|
590
671
|
The date of modification for each scope can be shown with the verbose
|
591
672
|
option.
|
592
673
|
LONGDESC
|
674
|
+
arg "NAME", [:multiple, :optional]
|
675
|
+
|
593
676
|
command "list" do |c|
|
594
677
|
c.switch :verbose, required: false, negatable: false,
|
595
678
|
desc: "Display additional information about origin of scopes"
|
@@ -598,7 +681,7 @@ class Cli
|
|
598
681
|
|
599
682
|
c.action do |global_options,options,args|
|
600
683
|
task = ListTask.new
|
601
|
-
task.list(system_description_store, options)
|
684
|
+
task.list(system_description_store, args, options)
|
602
685
|
end
|
603
686
|
end
|
604
687
|
|
@@ -787,7 +870,8 @@ class Cli
|
|
787
870
|
task.config(key, value)
|
788
871
|
|
789
872
|
if key == "hints" && (value == "false" || value == "off")
|
790
|
-
Machinery::Ui.puts "Hints can be switched on again by
|
873
|
+
Machinery::Ui.puts "Hints can be switched on again by " \
|
874
|
+
"'#{Hint.program_name} config hints=on'."
|
791
875
|
end
|
792
876
|
end
|
793
877
|
end
|
data/lib/compare_task.rb
CHANGED
@@ -27,7 +27,7 @@ class CompareTask
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def render_html_comparison(description1, description2, scopes, options)
|
30
|
-
LocalSystem.
|
30
|
+
LocalSystem.validate_existence_of_command("xdg-open", "xdg-utils")
|
31
31
|
|
32
32
|
url = "http://#{options[:ip]}:#{options[:port]}/compare/" \
|
33
33
|
"#{CGI.escape(description1.name)}/#{CGI.escape(description2.name)}"
|
data/lib/constants.rb
CHANGED
@@ -21,5 +21,5 @@ module Machinery
|
|
21
21
|
DEFAULT_LOG_FILE = File.join(DEFAULT_CONFIG_DIR, "machinery.log")
|
22
22
|
DEFAULT_CONFIG_FILE = File.join(DEFAULT_CONFIG_DIR, "machinery.config")
|
23
23
|
IMAGE_META_DATA_FILE = "machinery.meta"
|
24
|
-
|
24
|
+
HELPER_REMOTE_PATH = "/root"
|
25
25
|
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# Copyright (c) 2013-2015 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
class DockerSystem < System
|
19
|
+
attr_accessor :image
|
20
|
+
|
21
|
+
def type
|
22
|
+
"docker"
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(image)
|
26
|
+
@image = image
|
27
|
+
|
28
|
+
validate_image_name(image)
|
29
|
+
end
|
30
|
+
|
31
|
+
def start
|
32
|
+
@container = LoggedCheetah.run("docker", "run", "-id", @image, "bash", stdout: :capture).chomp
|
33
|
+
rescue Cheetah::ExecutionFailed => e
|
34
|
+
raise Machinery::Errors::MachineryError, "Container could not be started." \
|
35
|
+
" The error message was:\n" + e.stderr
|
36
|
+
end
|
37
|
+
|
38
|
+
def stop
|
39
|
+
LoggedCheetah.run("docker", "rm", "-f", @container) if @container
|
40
|
+
end
|
41
|
+
|
42
|
+
def run_command(*args)
|
43
|
+
Machinery.logger.info("Running '#{args}'")
|
44
|
+
LoggedCheetah.run("docker", "exec", "--user=root", "-i", @container, *args)
|
45
|
+
end
|
46
|
+
|
47
|
+
def check_retrieve_files_dependencies
|
48
|
+
# Files are retrieved using the `docker cp` command, so there are no additional dependencies
|
49
|
+
end
|
50
|
+
|
51
|
+
def check_create_archive_dependencies
|
52
|
+
# Archives are created using the machinery-helper binary, so there are no additional
|
53
|
+
# dependencies
|
54
|
+
end
|
55
|
+
|
56
|
+
# Reads a file from the System. Returns nil if it does not exist.
|
57
|
+
def read_file(file)
|
58
|
+
run_command("cat", file, stdout: :capture)
|
59
|
+
rescue Cheetah::ExecutionFailed => e
|
60
|
+
if e.status.exitstatus == 1
|
61
|
+
# File not found, return nil
|
62
|
+
return
|
63
|
+
else
|
64
|
+
raise
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Removes a file from the System
|
69
|
+
def remove_file(file)
|
70
|
+
run_command("rm", file)
|
71
|
+
rescue => e
|
72
|
+
raise Machinery::Errors::RemoveFileFailed.new(
|
73
|
+
"Could not remove file '#{file}'.\nError: #{e}"
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Copies a file to the system
|
78
|
+
def inject_file(source, destination)
|
79
|
+
LoggedCheetah.run("docker", "cp", source, "#{@container}:#{destination}")
|
80
|
+
end
|
81
|
+
|
82
|
+
# Retrieves files specified in file_list from the container
|
83
|
+
def retrieve_files(file_list, destination)
|
84
|
+
file_list.each do |file|
|
85
|
+
destination_path = File.join(destination, file)
|
86
|
+
FileUtils.mkdir_p(File.dirname(destination_path), mode: 0700)
|
87
|
+
|
88
|
+
LoggedCheetah.run("docker", "cp", "#{@container}:#{file}", "#{destination_path}")
|
89
|
+
LoggedCheetah.run("chmod", "go-rwx", destination_path)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Retrieves files specified in file_list from the container and creates an archive.
|
94
|
+
def create_archive(file_list, archive, exclude = [])
|
95
|
+
created = !File.exists?(archive)
|
96
|
+
out = File.open(archive, "w")
|
97
|
+
begin
|
98
|
+
run_command(
|
99
|
+
File.join(
|
100
|
+
Machinery::HELPER_REMOTE_PATH, "machinery-helper"
|
101
|
+
), "tar", "--create", "--gzip", "--null", "--files-from=-",
|
102
|
+
*exclude.flat_map { |f| ["--exclude", f] },
|
103
|
+
stdout: out,
|
104
|
+
stdin: Array(file_list).join("\0"),
|
105
|
+
stderr: STDERR
|
106
|
+
)
|
107
|
+
rescue Cheetah::ExecutionFailed => e
|
108
|
+
if e.status.exitstatus == 1
|
109
|
+
# The tarball has been created successfully but some files were changed
|
110
|
+
# on disk while being archived, so we just log the warning and go on
|
111
|
+
Machinery.logger.info e.stderr
|
112
|
+
else
|
113
|
+
raise
|
114
|
+
end
|
115
|
+
end
|
116
|
+
out.close
|
117
|
+
File.chmod(0600, archive) if created
|
118
|
+
end
|
119
|
+
|
120
|
+
def requires_root?
|
121
|
+
false
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def validate_image_name(image)
|
127
|
+
images = LoggedCheetah.run("docker", "images", stdout: :capture).split("\n")
|
128
|
+
|
129
|
+
if !images.find { |i| i.start_with?("#{image} ") || i.index(" #{image} ") }
|
130
|
+
raise Machinery::Errors::InspectionFailed.new(
|
131
|
+
"Unknown docker image: '#{image}'"
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
data/lib/exceptions.rb
CHANGED
@@ -48,7 +48,7 @@ module Machinery
|
|
48
48
|
def to_s
|
49
49
|
"The system description '#{@name}' has an incompatible data " \
|
50
50
|
"format and can not be read.\n" \
|
51
|
-
"Try '#{
|
51
|
+
"Try '#{Hint.program_name} upgrade-format #{name}' to upgrade it to the current version.\n"
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -65,7 +65,7 @@ module Machinery
|
|
65
65
|
end.compact.first || "<HOSTNAME>"
|
66
66
|
formatted_scopes = Machinery::Ui.internal_scope_list_to_string(@scopes)
|
67
67
|
|
68
|
-
cmd = "#{
|
68
|
+
cmd = "#{Hint.program_name} inspect --extract-files --scope=#{formatted_scopes.delete(" ")}"
|
69
69
|
cmd += " --name='#{@description.name}'" if hostname != @description.name
|
70
70
|
cmd += " #{hostname}"
|
71
71
|
|
@@ -139,5 +139,6 @@ module Machinery
|
|
139
139
|
class InjectFileFailed < MachineryError; end
|
140
140
|
class UnexpectedInputData < MachineryError; end
|
141
141
|
class ComposeServiceLink < MachineryError; end
|
142
|
+
class UnsupportedHelperVersion < MachineryError; end
|
142
143
|
end
|
143
144
|
end
|
data/lib/filter.rb
CHANGED
@@ -72,7 +72,7 @@ class Filter
|
|
72
72
|
def self.from_default_definition(command)
|
73
73
|
filter = Filter.new
|
74
74
|
|
75
|
-
default_filters_file = File.join(Machinery::ROOT, "
|
75
|
+
default_filters_file = File.join(Machinery::ROOT, "filters", "default_filters.json")
|
76
76
|
if File.exists?(default_filters_file)
|
77
77
|
default_filters = JSON.parse(File.read(default_filters_file))
|
78
78
|
if default_filters[command]
|
data/lib/hint.rb
CHANGED
@@ -62,8 +62,14 @@ class Hint
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def do_complete_inspection(options)
|
65
|
-
|
66
|
-
|
65
|
+
if options[:host]
|
66
|
+
"To do a full inspection containing all scopes and to extract files run:\n" \
|
67
|
+
"#{program_name} inspect #{options[:host]} --name #{options[:name]} --extract-files"
|
68
|
+
elsif options[:docker_container]
|
69
|
+
"To do a full inspection containing all scopes and to extract files run:\n" \
|
70
|
+
"#{program_name} inspect-container --docker #{options[:docker_container]} " \
|
71
|
+
"--name #{options[:name]} --extract-files"
|
72
|
+
end
|
67
73
|
end
|
68
74
|
|
69
75
|
def upgrade_system_description(_options)
|
data/lib/inspect_task.rb
CHANGED
@@ -14,10 +14,8 @@
|
|
14
14
|
#
|
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
|
-
|
18
17
|
class InspectTask
|
19
|
-
def inspect_system(store,
|
20
|
-
system = System.for(host, options[:remote_user])
|
18
|
+
def inspect_system(store, system, name, current_user, scopes, filter, options = {})
|
21
19
|
check_root(system, current_user)
|
22
20
|
|
23
21
|
description, failed_inspections = build_description(store, name, system,
|
@@ -67,6 +65,8 @@ class InspectTask
|
|
67
65
|
timestring = Time.now.utc.iso8601
|
68
66
|
if system.class == LocalSystem
|
69
67
|
host = "localhost"
|
68
|
+
elsif system.class == DockerSystem
|
69
|
+
host = system.image
|
70
70
|
else
|
71
71
|
host = system.host
|
72
72
|
end
|
data/lib/kiwi_config.rb
CHANGED
@@ -234,8 +234,8 @@ EOF
|
|
234
234
|
end
|
235
235
|
|
236
236
|
def apply_packages(xml)
|
237
|
-
build_filter = YAML.load_file(
|
238
|
-
Machinery::ROOT, "
|
237
|
+
build_filter = YAML.load_file(
|
238
|
+
File.join(Machinery::ROOT, "filters", "filter-packages-for-build.yaml")
|
239
239
|
)
|
240
240
|
filter = build_filter[@system_description.os.canonical_name] || []
|
241
241
|
|
data/lib/list_task.rb
CHANGED
@@ -16,13 +16,17 @@
|
|
16
16
|
# you may find current contact information at www.suse.com
|
17
17
|
|
18
18
|
class ListTask
|
19
|
-
def list(store, options = {})
|
20
|
-
|
19
|
+
def list(store, system_descriptions, options = {})
|
20
|
+
if system_descriptions.empty?
|
21
|
+
descriptions = store.list
|
22
|
+
else
|
23
|
+
descriptions = system_descriptions.sort
|
24
|
+
end
|
21
25
|
has_incompatible_version = false
|
22
26
|
|
23
27
|
descriptions.each do |name|
|
24
28
|
begin
|
25
|
-
|
29
|
+
system_description = SystemDescription.load(name, store, skip_validation: true)
|
26
30
|
rescue Machinery::Errors::SystemDescriptionIncompatible => e
|
27
31
|
if !e.format_version
|
28
32
|
show_error("#{name}: incompatible format version. Can not be upgraded.\n", options)
|
@@ -35,9 +39,12 @@ class ListTask
|
|
35
39
|
"Please upgrade Machinery to the latest version.", options)
|
36
40
|
end
|
37
41
|
next
|
42
|
+
rescue Machinery::Errors::SystemDescriptionNotFound
|
43
|
+
show_error("#{name}: Couldn't find a system description with the name '#{name}'.", options)
|
44
|
+
next
|
38
45
|
rescue Machinery::Errors::SystemDescriptionValidationFailed
|
39
46
|
show_error("#{name}: This description is broken. Use " \
|
40
|
-
"`#{
|
47
|
+
"`#{Hint.program_name} validate #{name}` to see the error message.", options)
|
41
48
|
next
|
42
49
|
rescue Machinery::Errors::SystemDescriptionError
|
43
50
|
show_error("#{name}: This description is broken.", options)
|
@@ -49,10 +56,10 @@ class ListTask
|
|
49
56
|
else
|
50
57
|
scopes = []
|
51
58
|
|
52
|
-
|
59
|
+
system_description.scopes.each do |scope|
|
53
60
|
entry = Machinery::Ui.internal_scope_list_to_string(scope)
|
54
61
|
if SystemDescription::EXTRACTABLE_SCOPES.include?(scope)
|
55
|
-
if
|
62
|
+
if system_description.scope_extracted?(scope)
|
56
63
|
entry += " (extracted)"
|
57
64
|
else
|
58
65
|
entry += " (not extracted)"
|
@@ -60,7 +67,7 @@ class ListTask
|
|
60
67
|
end
|
61
68
|
|
62
69
|
if options[:verbose]
|
63
|
-
meta =
|
70
|
+
meta = system_description[scope].meta
|
64
71
|
if meta
|
65
72
|
time = Time.parse(meta.modified).getlocal
|
66
73
|
date = time.strftime "%Y-%m-%d %H:%M:%S"
|
data/lib/local_system.rb
CHANGED
@@ -67,6 +67,16 @@ You can install it by running `zypper install #{missing_packages.join(" ")}`.
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
def validate_existence_of_command(command, package)
|
71
|
+
Cheetah.run("which", command)
|
72
|
+
rescue Cheetah::ExecutionFailed
|
73
|
+
output = <<-EOF
|
74
|
+
You need the command '#{command}' from package '#{package}'.
|
75
|
+
You can install it by running `zypper install #{package}`.
|
76
|
+
EOF
|
77
|
+
raise(Machinery::Errors::MissingRequirement.new(output))
|
78
|
+
end
|
79
|
+
|
70
80
|
def validate_machinery_compatibility
|
71
81
|
return if !Machinery::Config.new.perform_support_check || os.can_run_machinery?
|
72
82
|
|
@@ -86,7 +96,7 @@ EOF
|
|
86
96
|
if !os.can_build?(system_description.os)
|
87
97
|
message = "Building '#{system_description.os.display_name}' is " \
|
88
98
|
"not supported on this distribution.\n" \
|
89
|
-
"Check the 'BUILD SUPPORT MATRIX' by running `#{
|
99
|
+
"Check the 'BUILD SUPPORT MATRIX' by running `#{Hint.program_name} build --help` for " \
|
90
100
|
"further information which build targets are supported.\n" \
|
91
101
|
"You are only able to build the architecture you are running " \
|
92
102
|
"(#{LocalSystem.os.architecture})."
|
@@ -95,8 +105,12 @@ EOF
|
|
95
105
|
end
|
96
106
|
end
|
97
107
|
|
108
|
+
def matches_architecture?(arch)
|
109
|
+
os.architecture == arch
|
110
|
+
end
|
111
|
+
|
98
112
|
def validate_architecture(arch)
|
99
|
-
if
|
113
|
+
if !matches_architecture?(arch)
|
100
114
|
raise(Machinery::Errors::UnsupportedArchitecture.new(
|
101
115
|
"This operation is not supported on architecture '#{os.architecture}'."
|
102
116
|
))
|
@@ -104,6 +118,10 @@ EOF
|
|
104
118
|
end
|
105
119
|
end
|
106
120
|
|
121
|
+
def type
|
122
|
+
"local"
|
123
|
+
end
|
124
|
+
|
107
125
|
def requires_root?
|
108
126
|
true
|
109
127
|
end
|