machinery-tool 1.13.0 → 1.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|