machinery-tool 1.11.2 → 1.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5d39b671ef2bf800e50ffe8cb48003f1ad6cf50
4
- data.tar.gz: a5f739eb08389646bd1d6e8d26ee29d6f21b1595
3
+ metadata.gz: 59b0cae046e00683fea873260999de11ce3ad562
4
+ data.tar.gz: 295b43b9d42e832be6f78363cee7f8c91c25a47d
5
5
  SHA512:
6
- metadata.gz: 1992072db448872c81e4179fa7f2a7518179ecf15f12c433b9cd0f6c6a1811bdb4e7f68b4776ea69ac649fcdf8b5c813af213aa7e786f40d0cb02638f2462d1e
7
- data.tar.gz: 651d2cfa1150a857ca265db080d113d61f845c8ed2cfdaeb626b81b058b5b52193239b751c2385cdf2978f86e7ff42510265f5efdb1dbc6f9f57f8031797a5c0
6
+ metadata.gz: be116d55112cf6d945db98ce6ce4723644df3753904d5811b9c7abe05f0dfc4b4199bb574025d9b3833b4fc642df6132103937b0a4aeb48fe551627a024d0253
7
+ data.tar.gz: 76221ef972ded4ce554d3b4e7e085477b7071057ef26847a6d40cf20ef94142aced57b5109cad75274135b8a0fe7573c3d815eab092d91066fcfe95131d217a8
data/NEWS CHANGED
@@ -1,6 +1,13 @@
1
1
  # Machinery Release Notes
2
2
 
3
3
 
4
+ ## Version 1.12.0 - Fri Sep 04 16:51:10 CEST 2015 - cschum@suse.de
5
+
6
+ * The x86_64 machinery-helper is now shipped with machinery. It speeds up
7
+ inspection of unmanaged-files when the files are not extracted
8
+ * Fix for unmanaged-file inspector to not mark directories as unmanaged if they
9
+ only consist managed sub directories
10
+
4
11
  ## Version 1.11.2 - Thu Jul 30 14:42:44 CEST 2015 - thardeck@suse.de
5
12
 
6
13
  * Fix issue with showing HTML view when not all file scopes are inspected
@@ -0,0 +1,44 @@
1
+ # README for Docker Containers created by Machinery
2
+
3
+ This directory contains a (Docker Compose) Container configuration that was exported by
4
+ Machinery.
5
+
6
+ The user is expected to be familiar with using Docker.
7
+ Details on Docker can be found at https://www.docker.com/.
8
+
9
+ ## Requirements
10
+
11
+ Docker and docker-compose are required. Packages are available in the Virtualization repository.
12
+
13
+ Install on openSUSE 13.2:
14
+
15
+ sudo zypper ar -f http://download.opensuse.org/repositories/Virtualization:/containers/openSUSE_13.2/ virt
16
+ sudo zypper refresh
17
+ sudo zypper in docker docker-compose
18
+ sudo usermod -aG docker $(whoami)
19
+ sudo systemctl start docker
20
+
21
+ Log out and in again to refresh the user's group.
22
+
23
+ ## Managing Docker containers
24
+
25
+ Run container:
26
+
27
+ docker-compose up
28
+
29
+ Run container as daemon in background:
30
+
31
+ docker-compose up -d
32
+
33
+ Shows list of all running containers:
34
+
35
+ docker-compose ps
36
+
37
+ Stop the container:
38
+
39
+ docker-compose kill
40
+
41
+ Remove the container image:
42
+
43
+ docker-compose rm -vf
44
+
@@ -7,6 +7,7 @@
7
7
  "/unmanaged_files/files/name=/var/tmp",
8
8
  "/unmanaged_files/files/name=/lost+found",
9
9
  "/unmanaged_files/files/name=/var/run",
10
+ "/unmanaged_files/files/name=/var/lock",
10
11
  "/unmanaged_files/files/name=/var/lib/rpm",
11
12
  "/unmanaged_files/files/name=/.snapshots",
12
13
  "/unmanaged_files/files/name=/proc",
data/html/index.html.haml CHANGED
@@ -433,25 +433,25 @@
433
433
  %span.scope-navigation
434
434
  Scopes:
435
435
  %a{:href => "#os", :title => "Operating System"}
436
- %img{:src => "assets/logo-os-small.png"}/
436
+ %img{:src => "assets/logo-os-small.png", :title=>"Operating System", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('os')}"}/
437
437
  %a{:href => "#packages", :title => "Packages"}
438
- %img{:src => "assets/logo-packages-small.png"}/
438
+ %img{:src => "assets/logo-packages-small.png", :title => "Packages", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('packages')}"}/
439
439
  %a{:href => "#patterns", :title => "Patterns"}
440
- %img{:src => "assets/logo-patterns-small.png"}/
440
+ %img{:src => "assets/logo-patterns-small.png", :title => "Patterns", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('patterns')}"}/
441
441
  %a{:href => "#repositories", :title => "Repositories"}
442
- %img{:src => "assets/logo-repositories-small.png"}/
442
+ %img{:src => "assets/logo-repositories-small.png", :title => "Repositories", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('repositories')}"}/
443
443
  %a{:href => "#users", :title => "Users"}
444
- %img{:src => "assets/logo-users-small.png"}/
444
+ %img{:src => "assets/logo-users-small.png", :title => "Users", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('users')}"}/
445
445
  %a{:href => "#groups", :title => "Groups"}
446
- %img{:src => "assets/logo-groups-small.png"}/
446
+ %img{:src => "assets/logo-groups-small.png", :title => "Groups", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('groups')}"}/
447
447
  %a{:href => "#services", :title => "Services"}
448
- %img{:src => "assets/logo-services-small.png"}/
448
+ %img{:src => "assets/logo-services-small.png", :title => "Services", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('services')}"}/
449
449
  %a{:href => "#config_files", :title => "Config Files"}
450
- %img{:src => "assets/logo-config-files-small.png"}/
450
+ %img{:src => "assets/logo-config-files-small.png", :title => "Config Files", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('config_files')}"}/
451
451
  %a{:href => "#changed_managed_files", :title => "Changed Managed Files"}
452
- %img{:src => "assets/logo-changed-managed-files-small.png"}/
452
+ %img{:src => "assets/logo-changed-managed-files-small.png", :title => "Changed Managed Files", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('changed_managed_files')}"}/
453
453
  %a{:href => "#unmanaged_files", :title => "Unmanaged Files"}
454
- %img{:src => "assets/logo-unmanaged-files-small.png"}/
454
+ %img{:src => "assets/logo-unmanaged-files-small.png", :title => "Unmanaged Files", :class=>"over", :"data-toggle"=>"popover", :"data-content"=>"#{scope_help('unmanaged_files')}"}/
455
455
 
456
456
 
457
457
  #content_container{"ng-controller" => "showController"}
data/lib/build_task.rb CHANGED
@@ -34,7 +34,7 @@ class BuildTask
34
34
  output_path, img_extension)
35
35
 
36
36
  begin
37
- LoggedCheetah.run(
37
+ LoggedCheetah.run_with_c(
38
38
  "sudo",
39
39
  tmp_script.path,
40
40
  stdout: $stdout,
data/lib/cli.rb CHANGED
@@ -87,7 +87,8 @@ class Cli
87
87
  Machinery::Ui.error("Option --" + e.message)
88
88
  exit 1
89
89
  when GLI::UnknownCommandArgument, GLI::UnknownGlobalArgument,
90
- GLI::UnknownCommand, GLI::BadCommandLine, OptionParser::MissingArgument
90
+ GLI::UnknownCommand, GLI::BadCommandLine,
91
+ OptionParser::MissingArgument, OptionParser::AmbiguousOption
91
92
  Machinery::Ui.error e.to_s + "\n\n"
92
93
  command = ARGV & @commands.keys.map(&:to_s)
93
94
  Machinery::Ui.error "Run '#{$0} #{command.first} --help' for more information."
@@ -105,8 +106,16 @@ class Cli
105
106
  Machinery::Ui.error("Error: " + e.message)
106
107
  exit 1
107
108
  else
108
- Machinery::Ui.error "Machinery experienced an unexpected error. Please file a " \
109
- "bug report at: https://github.com/SUSE/machinery/issues/new\n"
109
+ if LocalSystem.os.canonical_name.include? ("SUSE Linux Enterprise")
110
+ Machinery::Ui.error "Machinery experienced an unexpected error.\n" \
111
+ "If this impacts your business please file a service request at " \
112
+ "https://www.suse.com/mysupport\n" \
113
+ "so that we can assist you on this issue. An active support contract is required.\n"
114
+ else
115
+ Machinery::Ui.error "Machinery experienced an unexpected error. Please file a " \
116
+ "bug report at: https://github.com/SUSE/machinery/issues/new\n"
117
+ end
118
+
110
119
  if e.is_a?(Cheetah::ExecutionFailed)
111
120
  result = ""
112
121
  result << "#{e.message}\n"
@@ -728,6 +737,10 @@ class Cli
728
737
 
729
738
  The value of a key is shown when no value argument is passed.
730
739
  If neither the key argument nor the value argument are specified a list of all keys and their values are shown.
740
+
741
+ ALTERNATIVE SYNOPSIS:
742
+
743
+ machinery [global options] config [KEY][=VALUE]
731
744
  LONGDESC
732
745
  arg "KEY", :optional
733
746
  arg "VALUE", :optional
data/lib/constants.rb CHANGED
@@ -21,4 +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
+ REMOTE_HELPERS_PATH = "/root"
24
25
  end
@@ -0,0 +1,46 @@
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 ContainerizeTask
19
+ def containerize(description, dir)
20
+ output_path = File.join(dir, description.name)
21
+
22
+ mapper = WorkloadMapper.new
23
+ workloads = mapper.identify_workloads(description)
24
+
25
+ if workloads.empty?
26
+ Machinery::Ui.puts "No workloads detected."
27
+ else
28
+ FileUtils.mkdir_p(output_path)
29
+ mapper.save(workloads, output_path)
30
+ mapper.extract(description, workloads, output_path)
31
+ write_readme_file(output_path)
32
+
33
+ workloads.each do |workload|
34
+ Machinery::Ui.puts "Detected workload '#{workload[0]}'."
35
+ end
36
+ Machinery::Ui.puts "\nWrote to #{output_path}."
37
+ end
38
+ end
39
+
40
+ def write_readme_file(dir)
41
+ FileUtils.cp(
42
+ File.join(Machinery::ROOT, "export_helpers", "containerize_readme.md"),
43
+ File.join(dir, "README.md")
44
+ )
45
+ end
46
+ end
data/lib/exceptions.rb CHANGED
@@ -135,5 +135,9 @@ module Machinery
135
135
  class UnknownConfig < MachineryError; end
136
136
  class UnsupportedArchitecture < MachineryError; end
137
137
  class ServeFailed < MachineryError; end
138
+ class RemoveFileFailed < MachineryError; end
139
+ class InjectFileFailed < MachineryError; end
140
+ class UnexpectedInputData < MachineryError; end
141
+ class ComposeServiceLink < MachineryError; end
138
142
  end
139
143
  end
data/lib/helper.rb CHANGED
@@ -51,6 +51,10 @@ def with_c_locale(&block)
51
51
  with_env "LC_ALL" => "C", &block
52
52
  end
53
53
 
54
+ def with_utf8_locale(&block)
55
+ with_env "LC_ALL" => "en_US.UTF-8", &block
56
+ end
57
+
54
58
  def with_env(env)
55
59
  # ENV isn't a Hash, but a weird Hash-like object. Calling #to_hash on it
56
60
  # will copy its items into a newly created Hash instance. This approach
data/lib/local_system.rb CHANGED
@@ -87,7 +87,9 @@ EOF
87
87
  message = "Building '#{system_description.os.display_name}' is " \
88
88
  "not supported on this distribution.\n" \
89
89
  "Check the 'BUILD SUPPORT MATRIX' by running `#{$0} build --help` for " \
90
- "further information which build targets are supported."
90
+ "further information which build targets are supported.\n" \
91
+ "You are only able to build the architecture you are running " \
92
+ "(#{LocalSystem.os.architecture})."
91
93
 
92
94
  raise(Machinery::Errors::BuildFailed.new(message))
93
95
  end
@@ -112,7 +114,7 @@ EOF
112
114
  else
113
115
  cheetah_class = LoggedCheetah
114
116
  end
115
- with_c_locale do
117
+ with_utf8_locale do
116
118
  cheetah_class.run(*args)
117
119
  end
118
120
  end
@@ -148,4 +150,24 @@ EOF
148
150
  # File not found, return nil
149
151
  return
150
152
  end
153
+
154
+ # Copies a file to the local system
155
+ def inject_file(source, destination)
156
+ FileUtils.copy(source, destination)
157
+ rescue => e
158
+ raise Machinery::Errors::InjectFileFailed.new(
159
+ "Could not inject file '#{source}' to local system.\n" \
160
+ "Error: #{e}"
161
+ )
162
+ end
163
+
164
+ # Removes a file from the System
165
+ def remove_file(file)
166
+ File.delete(file) if File.exist?(file)
167
+ rescue => e
168
+ raise Machinery::Errors::RemoveFileFailed.new(
169
+ "Could not remove file '#{file}' on local system'.\n" \
170
+ "Error: #{e}"
171
+ )
172
+ end
151
173
  end
@@ -16,12 +16,30 @@
16
16
  # you may find current contact information at www.suse.com
17
17
 
18
18
  class LoggedCheetah
19
- def self.run(*args)
20
- command = args.select{|e| e.is_a?(String)}.join(" ")
21
- Machinery.logger.info("Running '#{command}'")
19
+ class << self
20
+ def run(*args)
21
+ run_overloaded(*args, {})
22
+ end
23
+
24
+ def run_with_c(*args)
25
+ run_overloaded(*args, with_c_locale: true)
26
+ end
27
+
28
+ private
29
+
30
+ def run_overloaded(*args, options)
31
+ command = args.select { |e| e.is_a?(String) }.join(" ")
32
+ Machinery.logger.info("Running '#{command}'")
22
33
 
23
- with_c_locale do
24
- Cheetah.run(*args)
34
+ if options[:with_c_locale]
35
+ with_c_locale do
36
+ Cheetah.run(*args)
37
+ end
38
+ else
39
+ with_utf8_locale do
40
+ Cheetah.run(*args)
41
+ end
42
+ end
25
43
  end
26
44
  end
27
45
  end
data/lib/machinery.rb CHANGED
@@ -102,6 +102,10 @@ require_relative "serve_html_task"
102
102
  require_relative "file_diff"
103
103
  require_relative "server"
104
104
  require_relative "html"
105
+ require_relative "machinery_helper"
106
+ require_relative "workload_mapper"
107
+ require_relative "containerize_task"
108
+ require_relative "workload_mapper_dsl"
105
109
 
106
110
  Dir[File.join(Machinery::ROOT, "plugins", "**", "*.rb")].each { |f| require(f) }
107
111
 
@@ -0,0 +1,66 @@
1
+ # Copyright (c) 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
+ # The MachineryHelper class handles the helper binaries Machinery can use to
19
+ # do inspections. It provides methods to check, if a helper is available, to
20
+ # inject it to the target machine, run it there, and clean up after it's done.
21
+ #
22
+ # The inspection checks, if a binary helper is available on the machine where
23
+ # the inspection is started. It looks at the location
24
+ #
25
+ # /usr/share/machinery/helpers/<arch>/machinery-helper
26
+ #
27
+ # where <arch> is the hardware architecture of the target system. Valid values
28
+ # are x86_64, i586, s390x, and ppcle.
29
+
30
+ class MachineryHelper
31
+ attr_accessor :local_helpers_path
32
+
33
+ def initialize(s)
34
+ @system = s
35
+ @arch = @system.arch
36
+
37
+ @local_helpers_path = "/usr/share/machinery/helpers"
38
+ end
39
+
40
+ def local_helper_path
41
+ File.join(@local_helpers_path, @arch, "machinery-helper")
42
+ end
43
+
44
+ # Returns true, if there is a helper binary matching the architecture of the
45
+ # inspected system. Return false, if not.
46
+ def can_help?
47
+ File.exist?(local_helper_path)
48
+ end
49
+
50
+ def inject_helper
51
+ @system.inject_file(local_helper_path, Machinery::REMOTE_HELPERS_PATH)
52
+ end
53
+
54
+ def run_helper(scope)
55
+ json = @system.run_command(
56
+ File.join(
57
+ Machinery::REMOTE_HELPERS_PATH, "machinery-helper"
58
+ ), stdout: :capture, stderr: STDERR
59
+ )
60
+ scope.set_attributes(JSON.parse(json))
61
+ end
62
+
63
+ def remove_helper
64
+ @system.remove_file(File.join(Machinery::REMOTE_HELPERS_PATH, "machinery-helper"))
65
+ end
66
+ end
data/lib/remote_system.rb CHANGED
@@ -73,7 +73,9 @@ class RemoteSystem < System
73
73
  end
74
74
 
75
75
  sudo = ["sudo", "-n"] if options[:privileged] && remote_user != "root"
76
- cmds = ["ssh", "#{remote_user}@#{host}", sudo, "LC_ALL=C", *piped_args, options].compact.flatten
76
+ cmds = [
77
+ "ssh", "#{remote_user}@#{host}", sudo, "LC_ALL=en_US.utf8", *piped_args, options
78
+ ].compact.flatten
77
79
  cheetah_class.run(*cmds)
78
80
  rescue Cheetah::ExecutionFailed => e
79
81
  if e.stderr.include?("password is required")
@@ -140,4 +142,32 @@ class RemoteSystem < System
140
142
  raise
141
143
  end
142
144
  end
145
+
146
+ # Copies a file to the system
147
+ def inject_file(source, destination)
148
+ destination = "#{remote_user}@#{host}:#{destination}"
149
+
150
+ cmd = [
151
+ "scp",
152
+ source,
153
+ destination
154
+ ]
155
+
156
+ begin
157
+ LoggedCheetah.run(*cmd)
158
+ rescue Cheetah::ExecutionFailed => e
159
+ raise Machinery::Errors::InjectFileFailed.new(
160
+ "Could not inject file '#{source}' to host '#{host}'.\nError: #{e}"
161
+ )
162
+ end
163
+ end
164
+
165
+ # Removes a file from the system
166
+ def remove_file(file)
167
+ run_command("rm", file, privileged: true)
168
+ rescue Cheetah::ExecutionFailed => e
169
+ raise Machinery::Errors::RemoveFileFailed.new(
170
+ "Could not remove file '#{file}' on host '#{host}'.\nError: #{e}"
171
+ )
172
+ end
143
173
  end