machinery-tool 1.0.2

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 (157) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +674 -0
  3. data/NEWS +143 -0
  4. data/bin/machinery +29 -0
  5. data/helpers/changed_managed_files.sh +32 -0
  6. data/helpers/filter-packages-for-build.yaml +6 -0
  7. data/html/assets/arrow_down.png +0 -0
  8. data/html/assets/arrow_up.png +0 -0
  9. data/html/assets/bootstrap-popover.js +113 -0
  10. data/html/assets/bootstrap-tooltip.js +457 -0
  11. data/html/assets/bootstrap.min.css +5 -0
  12. data/html/assets/collapse.js +174 -0
  13. data/html/assets/hogan-3.0.2.min.mustache.js +5 -0
  14. data/html/assets/jquery-2.1.1.min.js +4 -0
  15. data/html/assets/logo-changed-managed-files-small.png +0 -0
  16. data/html/assets/logo-changed-managed-files.png +0 -0
  17. data/html/assets/logo-config-files-small.png +0 -0
  18. data/html/assets/logo-config-files.png +0 -0
  19. data/html/assets/logo-groups-small.png +0 -0
  20. data/html/assets/logo-groups.png +0 -0
  21. data/html/assets/logo-os-small.png +0 -0
  22. data/html/assets/logo-os.png +0 -0
  23. data/html/assets/logo-packages-small.png +0 -0
  24. data/html/assets/logo-packages.png +0 -0
  25. data/html/assets/logo-patterns-small.png +0 -0
  26. data/html/assets/logo-patterns.png +0 -0
  27. data/html/assets/logo-repositories-small.png +0 -0
  28. data/html/assets/logo-repositories.png +0 -0
  29. data/html/assets/logo-services-small.png +0 -0
  30. data/html/assets/logo-services.png +0 -0
  31. data/html/assets/logo-unmanaged-files-small.png +0 -0
  32. data/html/assets/logo-unmanaged-files.png +0 -0
  33. data/html/assets/logo-users-small.png +0 -0
  34. data/html/assets/logo-users.png +0 -0
  35. data/html/assets/machinery-base.css +5767 -0
  36. data/html/assets/machinery.css +131 -0
  37. data/html/assets/machinery.js +148 -0
  38. data/html/assets/transition.js +59 -0
  39. data/html/assets/wheels_horizontal.png +0 -0
  40. data/html/index.html.haml +468 -0
  41. data/kiwi_helpers/kiwi_export_readme.md +22 -0
  42. data/kiwi_helpers/merge_users_and_groups.pl.erb +231 -0
  43. data/kiwi_helpers/unmanaged_files_build_excludes +5 -0
  44. data/lib/analyze_config_file_diffs_task.rb +130 -0
  45. data/lib/array.rb +98 -0
  46. data/lib/build_task.rb +124 -0
  47. data/lib/changed_rpm_files_helper.rb +96 -0
  48. data/lib/cli.rb +600 -0
  49. data/lib/compare_task.rb +68 -0
  50. data/lib/config.rb +33 -0
  51. data/lib/config_base.rb +117 -0
  52. data/lib/config_task.rb +56 -0
  53. data/lib/constants.rb +24 -0
  54. data/lib/copy_task.rb +22 -0
  55. data/lib/current_user.rb +23 -0
  56. data/lib/deploy_task.rb +89 -0
  57. data/lib/exceptions.rb +113 -0
  58. data/lib/generate_html_task.rb +22 -0
  59. data/lib/helper.rb +22 -0
  60. data/lib/hint.rb +39 -0
  61. data/lib/html.rb +103 -0
  62. data/lib/inspect_task.rb +93 -0
  63. data/lib/inspector.rb +65 -0
  64. data/lib/kiwi_config.rb +356 -0
  65. data/lib/kiwi_export_task.rb +36 -0
  66. data/lib/list_task.rb +64 -0
  67. data/lib/local_system.rb +127 -0
  68. data/lib/logged_cheetah.rb +25 -0
  69. data/lib/machinery.rb +85 -0
  70. data/lib/machinery_logger.rb +47 -0
  71. data/lib/migration.rb +128 -0
  72. data/lib/mountpoints.rb +72 -0
  73. data/lib/object.rb +138 -0
  74. data/lib/os.rb +78 -0
  75. data/lib/remote_system.rb +114 -0
  76. data/lib/remove_task.rb +43 -0
  77. data/lib/renderer.rb +243 -0
  78. data/lib/renderer_helper.rb +26 -0
  79. data/lib/rpm.rb +52 -0
  80. data/lib/scope_mixin.rb +38 -0
  81. data/lib/show_task.rb +65 -0
  82. data/lib/system.rb +81 -0
  83. data/lib/system_description.rb +228 -0
  84. data/lib/system_description_store.rb +167 -0
  85. data/lib/system_description_validator.rb +216 -0
  86. data/lib/tarball.rb +82 -0
  87. data/lib/ui.rb +74 -0
  88. data/lib/upgrade_format_task.rb +55 -0
  89. data/lib/validate_task.rb +23 -0
  90. data/lib/version.rb +22 -0
  91. data/lib/zypper.rb +70 -0
  92. data/man/generated/machinery.1.gz +0 -0
  93. data/man/generated/machinery.1.html +1056 -0
  94. data/plugins/docs/changed_managed_files.md +2 -0
  95. data/plugins/docs/config_files.md +5 -0
  96. data/plugins/docs/groups.md +2 -0
  97. data/plugins/docs/os.md +2 -0
  98. data/plugins/docs/packages.md +2 -0
  99. data/plugins/docs/patterns.md +5 -0
  100. data/plugins/docs/repositories.md +24 -0
  101. data/plugins/docs/services.md +6 -0
  102. data/plugins/docs/unmanaged_files.md +13 -0
  103. data/plugins/docs/users.md +3 -0
  104. data/plugins/inspect/changed_managed_files_inspector.rb +109 -0
  105. data/plugins/inspect/config_files_inspector.rb +117 -0
  106. data/plugins/inspect/groups_inspector.rb +46 -0
  107. data/plugins/inspect/os_inspector.rb +116 -0
  108. data/plugins/inspect/packages_inspector.rb +46 -0
  109. data/plugins/inspect/patterns_inspector.rb +67 -0
  110. data/plugins/inspect/repositories_inspector.rb +107 -0
  111. data/plugins/inspect/services_inspector.rb +88 -0
  112. data/plugins/inspect/unmanaged_files_inspector.rb +393 -0
  113. data/plugins/inspect/users_inspector.rb +87 -0
  114. data/plugins/model/changed_managed_files_model.rb +29 -0
  115. data/plugins/model/config_files_model.rb +29 -0
  116. data/plugins/model/groups_model.rb +26 -0
  117. data/plugins/model/os_model.rb +20 -0
  118. data/plugins/model/packages_model.rb +26 -0
  119. data/plugins/model/patterns_model.rb +26 -0
  120. data/plugins/model/repositories_model.rb +26 -0
  121. data/plugins/model/services_model.rb +48 -0
  122. data/plugins/model/unmanaged_files_model.rb +29 -0
  123. data/plugins/model/users_model.rb +26 -0
  124. data/plugins/schema/v1/system-description-changed-managed-files.schema.json +83 -0
  125. data/plugins/schema/v1/system-description-config-files.schema.json +83 -0
  126. data/plugins/schema/v1/system-description-groups.schema.json +30 -0
  127. data/plugins/schema/v1/system-description-os.schema.json +21 -0
  128. data/plugins/schema/v1/system-description-packages.schema.json +34 -0
  129. data/plugins/schema/v1/system-description-patterns.schema.json +24 -0
  130. data/plugins/schema/v1/system-description-repositories.schema.json +41 -0
  131. data/plugins/schema/v1/system-description-services.schema.json +30 -0
  132. data/plugins/schema/v1/system-description-unmanaged-files.schema.json +105 -0
  133. data/plugins/schema/v1/system-description-users.schema.json +61 -0
  134. data/plugins/schema/v2/system-description-changed-managed-files.schema.json +92 -0
  135. data/plugins/schema/v2/system-description-config-files.schema.json +92 -0
  136. data/plugins/schema/v2/system-description-groups.schema.json +30 -0
  137. data/plugins/schema/v2/system-description-os.schema.json +21 -0
  138. data/plugins/schema/v2/system-description-packages.schema.json +34 -0
  139. data/plugins/schema/v2/system-description-patterns.schema.json +24 -0
  140. data/plugins/schema/v2/system-description-repositories.schema.json +41 -0
  141. data/plugins/schema/v2/system-description-services.schema.json +30 -0
  142. data/plugins/schema/v2/system-description-unmanaged-files.schema.json +138 -0
  143. data/plugins/schema/v2/system-description-users.schema.json +61 -0
  144. data/plugins/show/changed_managed_files_renderer.rb +46 -0
  145. data/plugins/show/config_files_renderer.rb +62 -0
  146. data/plugins/show/groups_renderer.rb +36 -0
  147. data/plugins/show/os_renderer.rb +31 -0
  148. data/plugins/show/packages_renderer.rb +32 -0
  149. data/plugins/show/patterns_renderer.rb +32 -0
  150. data/plugins/show/repositories_renderer.rb +38 -0
  151. data/plugins/show/services_renderer.rb +32 -0
  152. data/plugins/show/unmanaged_files_renderer.rb +42 -0
  153. data/plugins/show/users_renderer.rb +35 -0
  154. data/schema/migrations/migrate1to2.rb +56 -0
  155. data/schema/v1/system-description-global.schema.json +31 -0
  156. data/schema/v2/system-description-global.schema.json +31 -0
  157. metadata +370 -0
@@ -0,0 +1,68 @@
1
+ # Copyright (c) 2013-2014 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 CompareTask
19
+ def compare(description1, description2, scopes, options = {})
20
+ output = render_comparison(description1, description2, scopes, options)
21
+
22
+ Machinery::Ui.print_output(output, :no_pager => options[:no_pager])
23
+ end
24
+
25
+ def render_comparison(description1, description2, scopes, options = {})
26
+ output = ""
27
+ identical = true
28
+ common_scopes = false
29
+ scopes.each do |scope|
30
+ if description1[scope] && description2[scope]
31
+ comparison = description1[scope].compare_with(description2[scope])
32
+
33
+ partial_description1 = SystemDescription.new(
34
+ description1.name,
35
+ scope => comparison[0]
36
+ )
37
+
38
+ partial_description2 = SystemDescription.new(
39
+ description2.name,
40
+ scope => comparison[1]
41
+ )
42
+
43
+ partial_description_common = SystemDescription.new("common", scope => comparison[2])
44
+
45
+ output += Renderer.for(scope).render_comparison(
46
+ partial_description1,
47
+ partial_description2,
48
+ partial_description_common,
49
+ options
50
+ )
51
+
52
+ if partial_description1[scope] || partial_description2[scope]
53
+ identical = false
54
+ end
55
+ common_scopes = true
56
+ else
57
+ output += Renderer.for(scope).render_comparison_missing_scope(
58
+ description1, description2
59
+ )
60
+ identical = false if description1[scope] || description2[scope]
61
+ end
62
+ end
63
+
64
+ output = "Compared descriptions are identical.\n" + output if identical && common_scopes
65
+
66
+ output
67
+ end
68
+ end
data/lib/config.rb ADDED
@@ -0,0 +1,33 @@
1
+ # Copyright (c) 2013-2014 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
+
19
+ # This file contains the defaults for machinery's configuration.
20
+ # They can be overwritten by the config file.
21
+
22
+ module Machinery
23
+ class Config < ConfigBase
24
+ def define_entries
25
+ default_config_file(Machinery::DEFAULT_CONFIG_FILE)
26
+
27
+ entry("hints",
28
+ default: true,
29
+ description: "Show hints about usage of Machinery in the context of the commands ran by the user"
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,117 @@
1
+ # Copyright (c) 2013-2014 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
+
19
+ # The defaults for machinery's configuration are defined in
20
+ # the file 'machinery_config.rb'.
21
+
22
+ class ConfigBase
23
+ def initialize
24
+ @entries = {}
25
+ @file = ""
26
+ define_entries
27
+ apply_custom_config(@file) if File.exist?(@file)
28
+ end
29
+
30
+ def default_config_file(file)
31
+ @file = file
32
+ end
33
+
34
+ def entry(key, parameters = {})
35
+ @entries[key] = { value: parameters[:default], description: parameters[:description] }
36
+ create_method(key.to_sym) { get(key) }
37
+ create_method("#{key}=".to_sym) { |value| set(key, value) }
38
+ end
39
+
40
+ def define_entries
41
+ raise NotImplementedError.new("No config entries defined for #{self.class}")
42
+ end
43
+
44
+ def each(&block)
45
+ @entries.each(&block)
46
+ end
47
+
48
+ def get(key)
49
+ ensure_config_exists(key)
50
+ @entries[key][:value]
51
+ end
52
+
53
+ def set(key, value, options = {auto_save: true} )
54
+ ensure_config_exists(key)
55
+
56
+ # Check if data type is correct. true and false are not of the same type which makes the check complex
57
+ if value.class != @entries[key][:value].class &&
58
+ ! ( ( value == true || value == false ) && ( @entries[key][:value].class == TrueClass || @entries[key][:value].class == FalseClass ) )
59
+ raise Machinery::Errors::MachineryError.new("The value \"#{value}\" for configuration key \"#{key}\" is of an invalid data type.")
60
+ end
61
+
62
+ @entries[key][:value] = value
63
+
64
+ save if options[:auto_save]
65
+ end
66
+
67
+
68
+ private
69
+
70
+ def save
71
+ config_table_stripped = {}
72
+ @entries.each do |key,value|
73
+ config_table_stripped[key] = value[:value]
74
+ end
75
+
76
+ FileUtils.mkdir_p(Machinery::DEFAULT_CONFIG_DIR)
77
+
78
+ begin
79
+ File.write(@file, config_table_stripped.to_yaml)
80
+ Machinery.logger.info("Wrote configuration file \"#{@file}\".")
81
+ rescue => e
82
+ raise Machinery::Errors::MachineryError.new("Could not write configuration file \"#{@file}\": #{e}.")
83
+ end
84
+ end
85
+
86
+ def apply_custom_config(file)
87
+ content = read_config_file(file) || []
88
+
89
+ content.each do |key, value|
90
+ begin
91
+ set(key, value, :auto_save => false )
92
+ rescue => e
93
+ Machinery::Ui.warn "Warning: The machinery config file \"#{file}\" contains an invalid entry \"#{key}\":\n#{e}"
94
+ end
95
+ end
96
+ end
97
+
98
+ def read_config_file(file)
99
+ begin
100
+ content = YAML.load_file(file)
101
+ Machinery.logger.info("Read configuration file \"#{file}\".")
102
+ rescue => e
103
+ Machinery::Ui.warn "Warning: Cannot parse machinery config file \"#{@file}\":\n#{e}"
104
+ end
105
+ content
106
+ end
107
+
108
+ def ensure_config_exists(key)
109
+ if @entries[key].nil?
110
+ raise Machinery::Errors::UnknownConfig.new("Unknown configuration key: #{key}")
111
+ end
112
+ end
113
+
114
+ def create_method(name, &block)
115
+ self.class.send(:define_method, name, &block)
116
+ end
117
+ end
@@ -0,0 +1,56 @@
1
+ # Copyright (c) 2013-2014 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 ConfigTask
19
+ def initialize(config = Machinery::Config.new)
20
+ @config = config
21
+ end
22
+
23
+ def config(key = nil, value_string = nil)
24
+ if !key
25
+ # show all config entries
26
+ @config.each do |key, value|
27
+ Machinery::Ui.puts "#{key} = #{value[:value]} (#{value[:description]})"
28
+ end
29
+ elsif !value_string
30
+ # show one specific config entry
31
+ Machinery::Ui.puts "#{key} = #{@config.get(key)}"
32
+ else
33
+ # set one specific config entry
34
+ @config.set(key, parse_value_string(key, value_string))
35
+ Machinery::Ui.puts "#{key} = #{@config.get(key)}"
36
+ end
37
+ end
38
+
39
+ def parse_value_string(key, value_string)
40
+ current_value = @config.get(key)
41
+
42
+ if current_value == true || current_value == false
43
+ if value_string == "true" || value_string == "on"
44
+ return true
45
+ elsif value_string == "false" || value_string == "off"
46
+ return false
47
+ else
48
+ raise Machinery::Errors::MachineryError.new("The value '#{value_string}' is not valid for key '#{key}'.")
49
+ end
50
+ elsif current_value.kind_of?(Integer)
51
+ return value_string.to_i
52
+ else
53
+ return value_string
54
+ end
55
+ end
56
+ end
data/lib/constants.rb ADDED
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2013-2014 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
+ module Machinery
19
+ ROOT = File.expand_path("..", File.dirname(__FILE__))
20
+ DEFAULT_CONFIG_DIR = File.join(ENV['HOME'], ".machinery")
21
+ DEFAULT_LOG_FILE = File.join(DEFAULT_CONFIG_DIR, "machinery.log")
22
+ DEFAULT_CONFIG_FILE = File.join(DEFAULT_CONFIG_DIR, "machinery.config")
23
+ IMAGE_META_DATA_FILE = "machinery.meta"
24
+ end
data/lib/copy_task.rb ADDED
@@ -0,0 +1,22 @@
1
+ # Copyright (c) 2013-2014 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 CopyTask
19
+ def copy(store, from, to)
20
+ store.copy(from, to)
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright (c) 2013-2014 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
+ # Represents the user under which Machinery is running.
19
+ class CurrentUser
20
+ def is_root?
21
+ Process.euid == 0
22
+ end
23
+ end
@@ -0,0 +1,89 @@
1
+ # Copyright (c) 2013-2014 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 DeployTask
19
+ def deploy(description, cloud_config, options = {})
20
+ LocalSystem.validate_existence_of_package("python-glanceclient")
21
+ if !File.exists?(cloud_config)
22
+ raise(Machinery::Errors::DeployFailed,
23
+ "The cloud config file '#{cloud_config}' could not be found."
24
+ )
25
+ end
26
+
27
+ if options[:image_dir]
28
+ if !Dir.exists?(options[:image_dir])
29
+ raise(Machinery::Errors::DeployFailed,
30
+ "The image directory does not exist."
31
+ )
32
+ end
33
+ image_dir = options[:image_dir]
34
+ else
35
+ image_dir = Dir.mktmpdir("#{description.name}-image", "/tmp")
36
+ is_temporary = true
37
+ task = BuildTask.new
38
+ task.build(description, image_dir)
39
+ end
40
+
41
+ meta_data = load_meta_data(image_dir)
42
+ image_file = File.join(image_dir, meta_data[:image_file])
43
+
44
+ if meta_data[:description] != description.name
45
+ raise(Machinery::Errors::MissingRequirement,
46
+ "The image file '#{image_file}' was not build from the provided system description."
47
+ )
48
+ end
49
+
50
+ if !File.exists?(image_file)
51
+ raise(Machinery::Errors::DeployFailed,
52
+ "The image file '#{image_file}' does not exist."
53
+ )
54
+ end
55
+
56
+ command = "/usr/bin/glance"
57
+ command << " --insecure" if options[:insecure]
58
+ command << " image-create"
59
+ command << " --name=#{options[:image_name] || description.name}"
60
+ command << " --disk-format=qcow2 --container-format=bare"
61
+ command << " --file=#{Shellwords.escape(image_file)}"
62
+
63
+ system "sh -c '. #{Shellwords.escape(cloud_config)} && #{command}'"
64
+
65
+ if is_temporary && image_dir.start_with?("/tmp/")
66
+ FileUtils.rm_rf(image_dir)
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def load_meta_data(meta_dir)
73
+ meta_file = File.join(meta_dir, Machinery::IMAGE_META_DATA_FILE)
74
+ if !File.exists?(meta_file)
75
+ raise(Machinery::Errors::DeployFailed,
76
+ "The meta data file '#{meta_file}' could not be found."
77
+ )
78
+ end
79
+
80
+ meta_data = YAML.load_file(meta_file)
81
+
82
+ if !meta_data[:image_file] || !meta_data[:description]
83
+ raise(Machinery::Errors::DeployFailed,
84
+ "The meta data file '#{meta_file}' is broken."
85
+ )
86
+ end
87
+ meta_data
88
+ end
89
+ end
data/lib/exceptions.rb ADDED
@@ -0,0 +1,113 @@
1
+ # Copyright (c) 2013-2014 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
+ module Machinery
19
+ module Errors
20
+ class IncompatibleHost < StandardError; end
21
+
22
+ # Superclass for all "expected" errors in Machinery.
23
+ # "Expected" errors are errors which are caused by the environment or input
24
+ # data and are not caused by bugs in the machinery codebase.
25
+ #
26
+ # Those errors will be handled specially by the machinery tool, e.g. by not
27
+ # showing a backtrace.
28
+ class MachineryError < StandardError; end
29
+
30
+ class UnknownScope < MachineryError; end
31
+ class UnknownOs < MachineryError; end
32
+ class InvalidPager < MachineryError; end
33
+ class InvalidCommandLine < MachineryError; end
34
+
35
+ class MissingRequirement < MachineryError; end
36
+
37
+ class SystemDescriptionError < MachineryError; end
38
+ class SystemDescriptionNotFound < SystemDescriptionError; end
39
+
40
+ class SystemDescriptionIncompatible < SystemDescriptionError
41
+ attr_reader :name
42
+
43
+ def initialize(name)
44
+ @name = name
45
+ end
46
+
47
+ def to_s
48
+ "The system description '#{@name}' has an incompatible data " \
49
+ "format and can not be read.\n" \
50
+ "Try '#{$0} upgrade-format #{name}' to upgrade it to the current version.\n"
51
+ end
52
+ end
53
+
54
+ class MissingExtractedFiles < SystemDescriptionError
55
+ def initialize(description, scopes)
56
+ @description = description
57
+ @scopes = scopes
58
+ end
59
+
60
+ def to_s
61
+ meta = @description[@scopes.first].meta
62
+ hostname = @scopes.map do |s|
63
+ @description[s].meta.hostname if @description[s].meta
64
+ end.compact.first || "<HOSTNAME>"
65
+ formatted_scopes = Machinery::Ui.internal_scope_list_to_string(@scopes)
66
+
67
+ cmd = "#{$0} inspect --extract-files --scope=#{formatted_scopes}"
68
+ cmd += " --name='#{@description.name}'" if hostname != @description.name
69
+ cmd += " #{hostname}"
70
+
71
+ if @scopes.count > 1
72
+ output = "The following scopes '#{formatted_scopes}' are part of the system description"
73
+ else
74
+ output = "The scope '#{formatted_scopes}' is part of the system description"
75
+ end
76
+ output += " but the corresponding files weren't extracted during inspection.\n" \
77
+ "The files are required to continue with this command." \
78
+ " Run `#{cmd}` to extract them."
79
+ end
80
+ end
81
+
82
+ class SystemDescriptionValidationFailed < SystemDescriptionError
83
+ attr_reader :errors
84
+ attr_accessor :header
85
+
86
+ def initialize(errors)
87
+ @errors = errors
88
+ end
89
+
90
+ def to_s
91
+ message = ""
92
+ if @header
93
+ message += header + "\n\n"
94
+ end
95
+ message += @errors.join("\n")
96
+ message += "\n"
97
+ message
98
+ end
99
+ end
100
+
101
+ class MigrationError < MachineryError; end
102
+
103
+ class BuildFailed < MachineryError; end
104
+ class DeployFailed < MachineryError; end
105
+ class InspectionFailed < MachineryError; end
106
+ class KiwiExportFailed < MachineryError; end
107
+
108
+ class SshConnectionFailed < MachineryError; end
109
+ class RsyncFailed < MachineryError; end
110
+ class OpenInBrowserFailed < MachineryError; end
111
+ class UnknownConfig < MachineryError; end
112
+ end
113
+ end