PackerFiles 0.0.1

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 (195) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/PackerFiles.gemspec +36 -0
  6. data/README.md +32 -0
  7. data/Rakefile +21 -0
  8. data/bin/pkf +5 -0
  9. data/lib/PackerFiles/CLI/OS.rb +44 -0
  10. data/lib/PackerFiles/CLI/Root.rb +41 -0
  11. data/lib/PackerFiles/Core/Base.rb +23 -0
  12. data/lib/PackerFiles/Core/CDImage.rb +185 -0
  13. data/lib/PackerFiles/Core/Disk.rb +135 -0
  14. data/lib/PackerFiles/Core/Exceptions.rb +65 -0
  15. data/lib/PackerFiles/Core/Hypervisor.rb +96 -0
  16. data/lib/PackerFiles/Core/Keyboard.rb +38 -0
  17. data/lib/PackerFiles/Core/Locale.rb +62 -0
  18. data/lib/PackerFiles/Core/LogicalVolume.rb +41 -0
  19. data/lib/PackerFiles/Core/Network.rb +67 -0
  20. data/lib/PackerFiles/Core/Packages.rb +30 -0
  21. data/lib/PackerFiles/Core/Partition.rb +41 -0
  22. data/lib/PackerFiles/Core/TimeZone.rb +45 -0
  23. data/lib/PackerFiles/Core/User.rb +46 -0
  24. data/lib/PackerFiles/Core/VolumeGroup.rb +50 -0
  25. data/lib/PackerFiles/Core/example/CDImage.txt +75 -0
  26. data/lib/PackerFiles/Core/example/Disk.txt +29 -0
  27. data/lib/PackerFiles/Core/example/Hypervisor.txt +111 -0
  28. data/lib/PackerFiles/Core/example/Keyboard.txt +28 -0
  29. data/lib/PackerFiles/Core/example/Locale.txt +31 -0
  30. data/lib/PackerFiles/Core/example/Network.txt +68 -0
  31. data/lib/PackerFiles/Core/example/Packages.txt +22 -0
  32. data/lib/PackerFiles/Core/example/TimeZone.txt +36 -0
  33. data/lib/PackerFiles/Core/example/User.txt +48 -0
  34. data/lib/PackerFiles/OS/Builder.rb +116 -0
  35. data/lib/PackerFiles/OS/CentOS/CD.rb +81 -0
  36. data/lib/PackerFiles/OS/CentOS/Kickstart.rb +64 -0
  37. data/lib/PackerFiles/OS/CentOS/Server.rb +170 -0
  38. data/lib/PackerFiles/OS/CentOS/Templates/Base_erb.rb +4 -0
  39. data/lib/PackerFiles/OS/CentOS/Templates/Disk_erb.rb +35 -0
  40. data/lib/PackerFiles/OS/CentOS/Templates/Keyboard_erb.rb +4 -0
  41. data/lib/PackerFiles/OS/CentOS/Templates/Locale_erb.rb +4 -0
  42. data/lib/PackerFiles/OS/CentOS/Templates/Network_erb.rb +17 -0
  43. data/lib/PackerFiles/OS/CentOS/Templates/Packages_erb.rb +34 -0
  44. data/lib/PackerFiles/OS/CentOS/Templates/Tail_erb.rb +15 -0
  45. data/lib/PackerFiles/OS/CentOS/Templates/TimeZone_erb.rb +10 -0
  46. data/lib/PackerFiles/OS/CentOS/Templates/User_erb.rb +20 -0
  47. data/lib/PackerFiles/OS/CentOS/Templates/boot_command_erb.rb +16 -0
  48. data/lib/PackerFiles/OS/CentOS/Templates/command_as_root_erb.rb +1 -0
  49. data/lib/PackerFiles/OS/CentOS/Templates/disable_root_erb.rb +1 -0
  50. data/lib/PackerFiles/OS/CentOS/Templates/enable_root_erb.rb +1 -0
  51. data/lib/PackerFiles/OS/CentOS/Templates/shutdown_command_erb.rb +1 -0
  52. data/lib/PackerFiles/OS/Debian/Apt.rb +42 -0
  53. data/lib/PackerFiles/OS/Debian/CD.rb +65 -0
  54. data/lib/PackerFiles/OS/Debian/Mirrors.rb +73 -0
  55. data/lib/PackerFiles/OS/Debian/Preseed.rb +64 -0
  56. data/lib/PackerFiles/OS/Debian/Server.rb +169 -0
  57. data/lib/PackerFiles/OS/Debian/Templates/Apt_erb.rb +18 -0
  58. data/lib/PackerFiles/OS/Debian/Templates/Disk_erb.rb +69 -0
  59. data/lib/PackerFiles/OS/Debian/Templates/Keyboard_erb.rb +5 -0
  60. data/lib/PackerFiles/OS/Debian/Templates/Locale_erb.rb +7 -0
  61. data/lib/PackerFiles/OS/Debian/Templates/Mirrors_erb.rb +9 -0
  62. data/lib/PackerFiles/OS/Debian/Templates/Network_erb.rb +19 -0
  63. data/lib/PackerFiles/OS/Debian/Templates/Packages_erb.rb +6 -0
  64. data/lib/PackerFiles/OS/Debian/Templates/TimeZone_erb.rb +6 -0
  65. data/lib/PackerFiles/OS/Debian/Templates/User_erb.rb +14 -0
  66. data/lib/PackerFiles/OS/Debian/Templates/boot_command_erb.rb +24 -0
  67. data/lib/PackerFiles/OS/Debian/Templates/command_as_root_erb.rb +1 -0
  68. data/lib/PackerFiles/OS/Debian/Templates/disable_root_erb.rb +5 -0
  69. data/lib/PackerFiles/OS/Debian/Templates/enable_root_erb.rb +1 -0
  70. data/lib/PackerFiles/OS/Debian/Templates/shutdown_command_erb.rb +1 -0
  71. data/lib/PackerFiles/OS/Debian/example/Apt.txt +55 -0
  72. data/lib/PackerFiles/OS/DocGenerator.rb +51 -0
  73. data/lib/PackerFiles/OS/Finder.rb +96 -0
  74. data/lib/PackerFiles/OS/RHEL/CD.rb +32 -0
  75. data/lib/PackerFiles/OS/RHEL/Fedora.rb +59 -0
  76. data/lib/PackerFiles/OS/RHEL/FedoraCD.rb +68 -0
  77. data/lib/PackerFiles/OS/RHEL/Server.rb +32 -0
  78. data/lib/PackerFiles/OS/RHEL/Templates/Fedora_Tail_erb.rb +14 -0
  79. data/lib/PackerFiles/OS/RHEL/Templates/boot_command_fedora_erb.rb +16 -0
  80. data/lib/PackerFiles/OS/SUSE/Templates/Base_erb.xml +32 -0
  81. data/lib/PackerFiles/OS/SUSE/Templates/Disk_erb.xml +110 -0
  82. data/lib/PackerFiles/OS/SUSE/Templates/Keyboard_erb.xml +7 -0
  83. data/lib/PackerFiles/OS/SUSE/Templates/Locale_erb.xml +18 -0
  84. data/lib/PackerFiles/OS/SUSE/Templates/Network_erb.xml +143 -0
  85. data/lib/PackerFiles/OS/SUSE/Templates/Packages_erb.xml +29 -0
  86. data/lib/PackerFiles/OS/SUSE/Templates/Tail_erb.xml +4 -0
  87. data/lib/PackerFiles/OS/SUSE/Templates/TimeZone_erb.xml +15 -0
  88. data/lib/PackerFiles/OS/SUSE/Templates/User_erb.xml +57 -0
  89. data/lib/PackerFiles/OS/SUSE/Templates/boot_command_erb.rb +23 -0
  90. data/lib/PackerFiles/OS/SUSE/Templates/command_as_root_erb.rb +1 -0
  91. data/lib/PackerFiles/OS/SUSE/Templates/disable_root_erb.rb +1 -0
  92. data/lib/PackerFiles/OS/SUSE/Templates/enable_root_erb.rb +1 -0
  93. data/lib/PackerFiles/OS/SUSE/Templates/shutdown_command_erb.rb +1 -0
  94. data/lib/PackerFiles/OS/Ubuntu/CD.rb +81 -0
  95. data/lib/PackerFiles/OS/Ubuntu/Desktop.rb +50 -0
  96. data/lib/PackerFiles/OS/Ubuntu/DesktopCD.rb +16 -0
  97. data/lib/PackerFiles/OS/Ubuntu/Mirrors.rb +103 -0
  98. data/lib/PackerFiles/OS/Ubuntu/Server.rb +78 -0
  99. data/lib/PackerFiles/OS/Ubuntu/Templates/Apt_erb.rb +18 -0
  100. data/lib/PackerFiles/OS/Ubuntu/Templates/boot_command_desktop_erb.rb +36 -0
  101. data/lib/PackerFiles/OS/Ubuntu/Templates/boot_command_erb.rb +30 -0
  102. data/lib/PackerFiles/OS/Ubuntu/Templates/ubiquity_erb.rb +8 -0
  103. data/lib/PackerFiles/OS/example/Doc.txt +8 -0
  104. data/lib/PackerFiles/Provision/Base.rb +20 -0
  105. data/lib/PackerFiles/Provision/ChefSolo.rb +90 -0
  106. data/lib/PackerFiles/Provision/ChefSoloHelper.rb +72 -0
  107. data/lib/PackerFiles/Provision/Copy.rb +22 -0
  108. data/lib/PackerFiles/Provision/ExternalScript.rb +43 -0
  109. data/lib/PackerFiles/Provision/InlineScript.rb +37 -0
  110. data/lib/PackerFiles/Provision/Provisioners.rb +87 -0
  111. data/lib/PackerFiles/Provision/example/Provisioners.txt +21 -0
  112. data/lib/PackerFiles/Utils/AutoZone.rb +96 -0
  113. data/lib/PackerFiles/Utils/FastestURL.rb +73 -0
  114. data/lib/PackerFiles/Utils/Generator.rb +34 -0
  115. data/lib/PackerFiles/Utils/HashSerializer.rb +110 -0
  116. data/lib/PackerFiles/Utils/Size.rb +44 -0
  117. data/lib/PackerFiles/Utils/TypeAccessor.rb +71 -0
  118. data/lib/PackerFiles/Virtual/Hypervisors.rb +72 -0
  119. data/lib/PackerFiles/Virtual/KVM.rb +119 -0
  120. data/lib/PackerFiles/Virtual/KVMConverter.rb +79 -0
  121. data/lib/PackerFiles/Virtual/VMWare.rb +108 -0
  122. data/lib/PackerFiles/Virtual/VMWareConverter.rb +78 -0
  123. data/lib/PackerFiles/Virtual/VirtualBox.rb +98 -0
  124. data/lib/PackerFiles/Virtual/VirtualBoxConverter.rb +75 -0
  125. data/lib/PackerFiles/Virtual/example/Hypervisors.txt +23 -0
  126. data/lib/PackerFiles/version.rb +3 -0
  127. data/lib/PackerFiles.rb +44 -0
  128. data/spec/core/builder_spec.rb +84 -0
  129. data/spec/core/cdimage_spec.rb +159 -0
  130. data/spec/core/disk_spec.rb +191 -0
  131. data/spec/core/keyboard_spec.rb +36 -0
  132. data/spec/core/locale_spec.rb +73 -0
  133. data/spec/core/network_spec.rb +96 -0
  134. data/spec/core/packages_spec.rb +18 -0
  135. data/spec/core/timezone_spec.rb +43 -0
  136. data/spec/core/user_spec.rb +44 -0
  137. data/spec/core/volume_group_spec.rb +53 -0
  138. data/spec/os/centos/cd_spec.rb +12 -0
  139. data/spec/os/centos/data/Server-Script-Provisioner.rb +57 -0
  140. data/spec/os/centos/data/Server.rb +55 -0
  141. data/spec/os/centos/data/chef-solo-provisioner.rb +58 -0
  142. data/spec/os/centos/finder_spec.rb +22 -0
  143. data/spec/os/centos/templates/boot_command_spec.rb +57 -0
  144. data/spec/os/centos/templates/disk_spec.rb +79 -0
  145. data/spec/os/centos/templates/keyboard_spec.rb +18 -0
  146. data/spec/os/centos/templates/locale_spec.rb +26 -0
  147. data/spec/os/centos/templates/network_spec.rb +38 -0
  148. data/spec/os/centos/templates/packages_spec.rb +18 -0
  149. data/spec/os/centos/templates/timezone_spec.rb +37 -0
  150. data/spec/os/centos/templates/user_spec.rb +24 -0
  151. data/spec/os/debian/apt_spec.rb +50 -0
  152. data/spec/os/debian/cd_spec.rb +30 -0
  153. data/spec/os/debian/data/7zip.tar.gz +0 -0
  154. data/spec/os/debian/data/All-sections.rb +60 -0
  155. data/spec/os/debian/data/Chef-Solo-Provisioner.rb +60 -0
  156. data/spec/os/debian/data/Copy-Provisioner.rb +61 -0
  157. data/spec/os/debian/data/External-Script-Provisioner.rb +69 -0
  158. data/spec/os/debian/data/Missing-CDImage.rb +53 -0
  159. data/spec/os/debian/data/Missing-VMWare-KVM-sections.rb +51 -0
  160. data/spec/os/debian/data/Missing-sections.rb +53 -0
  161. data/spec/os/debian/data/Script-Provisioner.rb +62 -0
  162. data/spec/os/debian/data/chef-solo-cookbooks/git_setup/Berksfile.lock +32 -0
  163. data/spec/os/debian/data/chef-solo-cookbooks/git_setup/README.md +81 -0
  164. data/spec/os/debian/data/chef-solo-cookbooks/git_setup/attributes/default.rb +3 -0
  165. data/spec/os/debian/data/chef-solo-cookbooks/git_setup/metadata.rb +11 -0
  166. data/spec/os/debian/data/chef-solo-cookbooks/git_setup/recipes/default.rb +30 -0
  167. data/spec/os/debian/data/chef-solo.json +5 -0
  168. data/spec/os/debian/data/test-script.sh +4 -0
  169. data/spec/os/debian/finder_spec.rb +59 -0
  170. data/spec/os/debian/mirrors_spec.rb +18 -0
  171. data/spec/os/debian/preseed_spec.rb +56 -0
  172. data/spec/os/debian/server_spec.rb +59 -0
  173. data/spec/os/debian/templates/apt_spec.rb +20 -0
  174. data/spec/os/debian/templates/boot_command_spec.rb +56 -0
  175. data/spec/os/debian/templates/disk_spec.rb +81 -0
  176. data/spec/os/debian/templates/keyboard_spec.rb +18 -0
  177. data/spec/os/debian/templates/locale_spec.rb +36 -0
  178. data/spec/os/debian/templates/mirrors_spec.rb +16 -0
  179. data/spec/os/debian/templates/network_spec.rb +38 -0
  180. data/spec/os/debian/templates/packages_spec.rb +17 -0
  181. data/spec/os/debian/templates/timezone_spec.rb +36 -0
  182. data/spec/os/debian/templates/user_spec.rb +25 -0
  183. data/spec/os/finder_spec.rb +21 -0
  184. data/spec/os/rhel/data/Fedora.rb +45 -0
  185. data/spec/os/rhel/data/Server-Custom.rb +54 -0
  186. data/spec/os/rhel/data/Server.rb +45 -0
  187. data/spec/os/rhel/finder_spec.rb +21 -0
  188. data/spec/os/ubuntu/cd_spec.rb +28 -0
  189. data/spec/os/ubuntu/data/Desktop.rb +61 -0
  190. data/spec/os/ubuntu/data/Server.rb +61 -0
  191. data/spec/os/ubuntu/finder_spec.rb +17 -0
  192. data/spec/os/ubuntu/mirrors_spec.rb +18 -0
  193. data/spec/utils/autozone_spec.rb +33 -0
  194. data/spec/virtual/virtual_box_spec.rb +16 -0
  195. metadata +405 -0
@@ -0,0 +1,87 @@
1
+ # Requires
2
+ require_relative 'Copy'
3
+ require_relative 'InlineScript'
4
+ require_relative 'ExternalScript'
5
+ require_relative 'ChefSolo'
6
+
7
+ # Top level class for managing Provisioners in a OS Spec file
8
+ module PackerFiles
9
+ class Provisioners
10
+
11
+ # Documentation for this class
12
+ def self.doc_file
13
+ PackerFiles.DirPath('Provision/example/Provisioners.txt').first
14
+ end
15
+
16
+ # List of registered provisioners
17
+ attr_accessor :list
18
+
19
+ # Constructor just yields self for further initialization
20
+ def initialize(&block)
21
+ @list = []
22
+ yield self if block_given?
23
+ end
24
+
25
+ # Enable File Copy Provisioner to be called multiple times
26
+ # with order preservation.
27
+ def Copy(&block)
28
+ @list.push(Provision::Copy.new(&block))
29
+ end
30
+
31
+ # Enable Inline Script Provisioner to be called multiple times
32
+ # with order preservation.
33
+ def InlineScript(&block)
34
+ @list.push(Provision::InlineScript.new(&block))
35
+ end
36
+
37
+ # Enable External Script Provisioner to be called multiple times
38
+ # with order preservation.
39
+ def ExternalScript(&block)
40
+ @list.push(Provision::ExternalScript.new(&block))
41
+ end
42
+
43
+ # Enable Chef Solo Provisioner to be called multiple times
44
+ # with order preservation.
45
+ def ChefSolo(&block)
46
+ @list.push(Provision::ChefSolo.new(&block))
47
+ end
48
+
49
+ # Convert self into Packer JSON format.
50
+ def convert(gen, os)
51
+ @list.unshift(EnableRootLoginScript(os))
52
+ @list.push(DisableRootLoginScript(os))
53
+ @list.compact.each do |prov|
54
+ prov.os = os
55
+ hash = prov.to_hash(os)
56
+ gen.provisioners.push(hash) if !hash.nil?
57
+ end
58
+ end
59
+
60
+ # Create a inline script command to enable root logins
61
+ private
62
+ def EnableRootLoginScript(os)
63
+ cmd = os.run_command_as_root
64
+ enable = os.enable_root_for_user
65
+ if !cmd.nil? && !enable.nil?
66
+ return Provision::InlineScript.new do |script|
67
+ script.execute_command = cmd
68
+ script.inline = enable
69
+ end
70
+ end
71
+ end
72
+
73
+ # Create a inline script command to disable root logins
74
+ private
75
+ def DisableRootLoginScript(os)
76
+ cmd = os.run_command_as_root
77
+ disable = os.disable_root_for_user
78
+ if !cmd.nil? && !disable.nil?
79
+ return Provision::InlineScript.new do |script|
80
+ script.execute_command = cmd
81
+ script.inline = disable
82
+ end
83
+ end
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,21 @@
1
+
2
+ # Define Provisioners for this OS
3
+ <% if @obj.nil? -%>
4
+ #os.<%= @name -%> do |prov|
5
+ <% else -%>
6
+ os.<%= @name -%> do |prov|
7
+ <% end -%>
8
+
9
+ # The Copy provisioner is used for Copying files.
10
+ # Multiple files or folders can be copied by using the same
11
+ # construct many times.
12
+ # prov.Copy do |cp|
13
+ # cp.source = 'source'
14
+ # cp.destination = 'destination'
15
+ # end
16
+
17
+ <% if @obj.nil? -%>
18
+ #end
19
+ <% else -%>
20
+ end
21
+ <% end -%>
@@ -0,0 +1,96 @@
1
+ # Requires
2
+ require 'rubygems'
3
+ require 'open-uri'
4
+ require 'json'
5
+
6
+ module PackerFiles
7
+
8
+ module Utils
9
+
10
+ # AutoZone handles the automatic detection of a time zone via
11
+ # web based GEO Lookups.
12
+ class AutoZone
13
+
14
+ # URL for maxmind timezone specifier
15
+ @@url = 'https://raw.githubusercontent.com/maxmind/geoip-api-c/master/timezone/timezone.txt'
16
+
17
+ # List of URLs for Geo-IP lookup
18
+ @@geo = [
19
+ 'http://www.telize.com/geoip',
20
+ 'http://freegeoip.net/json'
21
+ ]
22
+
23
+ # JSON object cache to prevent multiple internet lookups.
24
+ @@cache = nil
25
+
26
+ # Return back the Cached JSON
27
+ def self.Cache
28
+ @@cache
29
+ end
30
+
31
+ # Return the JSON from the web services, to do what ever.
32
+ def JSON
33
+
34
+ # Return the cache if it is populated already
35
+ return @@cache if !@@cache.nil?
36
+
37
+ # Cache Miss! Let us get it from Internet.
38
+ @@geo.each do |url|
39
+ begin
40
+ contents = open(url) {|f| f.read }
41
+ @@cache = JSON.parse(contents)
42
+ break
43
+ rescue
44
+ next
45
+ end
46
+ end
47
+ return @@cache
48
+ end
49
+
50
+ # Sugar coated country code
51
+ def country_code
52
+ return self.JSON['country_code']
53
+ end
54
+
55
+ # Sugar coated country_area code
56
+ def country_area_code
57
+ json = self.JSON
58
+ return json['country_code'], json['area_code']
59
+ end
60
+
61
+ # Sugar coated perfect time zone look-up
62
+ def time_zone
63
+
64
+ # Get the RAW JSON
65
+ json = self.JSON
66
+
67
+ # If it already contains a timezone, good enough and move on.
68
+ return json['timezone'] if json.has_key?('timezone')
69
+
70
+ # If not need more lookups with max-mind DB. Cache it for further
71
+ # use.
72
+ country = json['country_code']
73
+ area = json['area_code']
74
+ open(@@url) {|f|
75
+ f.each_line do |line|
76
+ arr = line.split("\t")
77
+ # Return the Time Zone if there is an exact match of country and area
78
+ if (arr[0] == country && arr[1] == area)
79
+ @@cache['timezone'] = arr[2]
80
+ break
81
+ # Return the Time Zone if there is an exact match of country and if
82
+ # area cannot be determined reliably.
83
+ elsif (arr[0] == country && (arr[1].empty? || area.empty?))
84
+ @@cache['timezone'] = arr[2]
85
+ break
86
+ end
87
+ end
88
+ }
89
+ return @@cache['timezone']
90
+ end
91
+
92
+ end # AutoZone
93
+
94
+ end # Utils
95
+
96
+ end # PackerFiles
@@ -0,0 +1,73 @@
1
+ # Requires
2
+ require 'open-uri'
3
+ require 'benchmark'
4
+ require 'uri'
5
+
6
+ module PackerFiles
7
+
8
+ module Utils
9
+
10
+ # Given a list of URL, returns the fastest URL (to access) among them.
11
+ # This is done by launching several threads in parallel and estimating
12
+ # the time taken to access the contents of these URLs.
13
+ class FastestURL
14
+
15
+ # Error URL
16
+ @@error = 25000
17
+
18
+ # Creates a new object of type FastestURL. slow_limit is used for
19
+ # signalling the response time (in seconds) of a web URL to be
20
+ # categorized as slow. Trials specifies the # of attempts the web
21
+ # URLs must be opened and closed.
22
+ def initialize(slow_limit = 0.5 , trials = 1)
23
+ @limit = slow_limit
24
+ @trials = trials
25
+ end
26
+
27
+ # Returns URLs sorted in terms of best access times from a list of
28
+ # input URLs.
29
+ def best_urls(url_list)
30
+ threads = url_list.map { |h| Thread.new {speed_trials(h) }}
31
+ speeds = threads.map { |t| t.join; t.value }
32
+ hash = Hash.new
33
+ url_list.each_with_index do |url, index|
34
+ hash[url] = speeds.at(index) if speeds.at(index) != @@error
35
+ end
36
+ hash.sort_by {|url, speed| speed}
37
+ end
38
+
39
+ # Compute the latency of a web url, multiple times via independent
40
+ # trials. This is called in thread context only.
41
+ private
42
+ def speed_trials(url)
43
+ total = 0.0
44
+ @trials.times do
45
+ speed = estimate_speed(url)
46
+ if speed >= @limit
47
+ return @@error
48
+ else
49
+ total += speed
50
+ end
51
+ end
52
+ return (total / @trials)
53
+ end
54
+
55
+ # This function is called in thread context only. It computes
56
+ # the time it takes for the various mirrors to return the index
57
+ # as a proxy for measuring it's speed.
58
+ private
59
+ def estimate_speed(url)
60
+ Benchmark.realtime do
61
+ begin
62
+ open(url) {|f| f.read}
63
+ rescue Exception => e
64
+ return @@error
65
+ end
66
+ end
67
+ end
68
+
69
+ end # FastestURL
70
+
71
+ end # Utils
72
+
73
+ end # PackerFiles
@@ -0,0 +1,34 @@
1
+ # Requires
2
+ require 'Utils/HashSerializer'
3
+ require 'json'
4
+
5
+ module PackerFiles
6
+ module Utils
7
+
8
+ # Generates the top level JSON file for Packer to operate upon.
9
+ class Generator < HashSerializer
10
+
11
+ # List of Hash Serializers
12
+ hash_variable :variables, Hash
13
+ hash_variable :builders, Array
14
+ hash_variable :provisioners, Array
15
+
16
+ # Constructor
17
+ def initialize
18
+ self.builders = Array.new
19
+ self.variables = Hash.new
20
+ self.provisioners = Array.new
21
+ end
22
+
23
+ # Create the JSON file in the given directory
24
+ def create_json(filename)
25
+ hash = self.to_hash
26
+ content = JSON.pretty_generate(hash) + "\n"
27
+ File.write(filename, content)
28
+ end
29
+
30
+ end # Generator
31
+
32
+ end # Utils
33
+
34
+ end # PackerFiles
@@ -0,0 +1,110 @@
1
+ # Requires
2
+
3
+ module PackerFiles
4
+
5
+ module Utils
6
+
7
+ # The Hash serializer is a meta-class that allows tracking of objects
8
+ # that needs to be converted into Hash objects, w/o having to hand-write
9
+ # lot of code.
10
+ class HashSerializer
11
+
12
+ # The Meta-class Idiom. All functions within this block are meta-class
13
+ # functions that cannot be invoked on the object, but can be invoked
14
+ # on the class.
15
+ class << self
16
+
17
+ # Specify that a list of methods are tracked for serialization.
18
+ # Name is the attribute name, Type is the object type that it
19
+ # belongs to. Method is the name of the conversion function that
20
+ # returns the value of the object serialized for JSON.
21
+ def hash_variable(name, type = String, method = nil, nil_emit=false)
22
+ @attrs ||= []
23
+ @attrs += [Hash["name", name, "type", type,
24
+ "method", method, "nil_emit", nil_emit]
25
+ ]
26
+ self.class_eval do
27
+
28
+ # Read accessor
29
+ define_method(name) do
30
+ instance_variable_get("@#{name}")
31
+ end
32
+
33
+ # Write accessor
34
+ define_method("#{name}=") do |value|
35
+ if value.is_a? type
36
+ instance_variable_set("@#{name}", value)
37
+ else
38
+ raise ArgumentError.new("Invalid Type")
39
+ end
40
+ end
41
+
42
+ # Converter function. We need to first get the
43
+ # variable and then call a function on it by binding
44
+ # first. (See Module::instance_method example in Ruby man page)
45
+ define_method("to_hash_value_#{name}") do
46
+ var = instance_variable_get("@#{name}")
47
+ if (method.nil? || var.nil?)
48
+ var
49
+ else
50
+ self.method(method).call
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+
57
+ # Return the attributes that are tracked so that it can be
58
+ # used for serialization.
59
+ def hash_attributes
60
+ @attrs
61
+ end
62
+
63
+ end
64
+
65
+ # Merge a hash serializer object with the current object.
66
+ def merge_hs(other)
67
+
68
+ # Do nothing if the other is not a Hash Serializer
69
+ return unless other.kind_of?(HashSerializer)
70
+
71
+ # Get the attributes set in other and if the same attribute
72
+ # is not set in self, then replace it. Otherwise ignore
73
+ other.class.hash_attributes.each do |attr|
74
+ name = attr['name']
75
+ other_value = other.method(name).call
76
+ self_value = self.method(name).call
77
+ if !other_value.nil? && self_value.nil?
78
+ self.method("#{name}=").call(other_value)
79
+ end
80
+ end
81
+ end
82
+
83
+ # Hash Converter which iterates through all the tracked objects
84
+ # and outputs the hash. This function is *NOT* a meta-class function
85
+ # but instead operates on the object level.
86
+ def to_hash(*args)
87
+
88
+ # Return value
89
+ hash = Hash.new
90
+
91
+ # Get all classes in the class hierarchy until HashSerializer
92
+ index = self.class.ancestors.index(HashSerializer)
93
+ cl_list = self.class.ancestors.slice(0, index)
94
+ cl_list.each do |klass|
95
+ next if !klass.respond_to?(:hash_attributes)
96
+ klass.hash_attributes.each do |attr|
97
+ name = attr['name']
98
+ nil_emit = attr['nil_emit']
99
+ value = method("to_hash_value_#{name}").call
100
+ hash[name] = value if (!value.nil? || (value.nil? && nil_emit))
101
+ end
102
+ end
103
+ return hash
104
+ end
105
+
106
+ end # HashSerializer
107
+
108
+ end # Utils
109
+
110
+ end # PackerFiles
@@ -0,0 +1,44 @@
1
+
2
+ module PackerFiles
3
+
4
+ module Utils
5
+
6
+ # Contains utility functions to manage size conversions
7
+ module Size
8
+
9
+ # Array of regular expressions to match size and their
10
+ # corresponding lambda functions to return size in number. It is
11
+ # easy to understand the constants if we remember that Packer always
12
+ # accepts size in MiB [Power of 2].
13
+ @@regex = {
14
+ /([0-9]+)GiB/ => lambda {|n| 1024 * n},
15
+ /([0-9]+)GB/ => lambda {|n| (953.67 * n).round},
16
+ /([0-9]+)MB/ => lambda {|n| (0.95367 * n).round},
17
+ /([0-9]+)MiB/ => lambda {|n| n},
18
+ /([0-9]+)TiB/ => lambda {|n| 1048576 * n},
19
+ /([0-9]+)TB/ => lambda {|n| (909486.46 * n).round},
20
+ /([0-9]+)GHz/ => lambda {|n| 1024 * n},
21
+ /([0-9]+)MHz/ => lambda {|n| n}
22
+ }
23
+
24
+ # Convert a text 'size' into a units of MiB. This is done
25
+ # calling the appropriate lambda function, whenever the
26
+ # regex is matched.
27
+ def MiB(size)
28
+ @@regex.each_pair do |r, l|
29
+ if m = r.match(size)
30
+ return l.call(m[1].to_i)
31
+ end
32
+ end
33
+ end
34
+
35
+ # Convert MiB Size into Bytes
36
+ def Bytes(size)
37
+ size * 1024 * 1024
38
+ end
39
+
40
+ end # Size
41
+
42
+ end # Utils
43
+
44
+ end # PackerFiles
@@ -0,0 +1,71 @@
1
+ # Requires
2
+ require_relative "../Core/Exceptions"
3
+
4
+ module PackerFiles
5
+
6
+ module Utils
7
+
8
+ # Exception class used to indicate that a required type accessor is
9
+ # missing.
10
+ class MissingAccessor < Core::Error
11
+ def initialize(accessor_name, class_name)
12
+ self.message = "Missing #{accessor_name} Section for #{class_name}"
13
+ end
14
+ end
15
+
16
+ # The Type accessor class is used as a meta-class for any class.
17
+ class TypeAccessor
18
+
19
+ # The Meta-class Idiom. All functions within this block are meta-class
20
+ # functions that cannot be invoked on the object, but can be invoked
21
+ # on the class.
22
+ class << self
23
+
24
+ # Custom accessor to create accessors from type name. It is also
25
+ # Possible to set the name of the accessor. By default it is the
26
+ # name of the type.
27
+ def type_accessor(type, name = type.name.gsub(/.*::/, ''),
28
+ optional = false)
29
+
30
+ # Save the type and name in a array hash, which will be used later.
31
+ @types ||= Hash.new
32
+ @types[name] = [type, optional]
33
+
34
+ # Doing a class_eval creates a new method of "name"
35
+ class_eval do
36
+
37
+ # Read/Write accessor which accepts blocks for initialization.
38
+ define_method("#{name}") do |arg = nil, &block|
39
+ if (self.class.proc_from(&block).nil?)
40
+ instance_variable_get("@#{name}")
41
+ else
42
+ obj = type.new(&block)
43
+ instance_variable_set("@#{name}", obj)
44
+ end
45
+ end # define_method
46
+ end # class_eval
47
+
48
+ end
49
+
50
+ # Return the Hash that is used to track registered type accessors
51
+ def type_accessors
52
+ @types
53
+ end
54
+
55
+ # Given a block, convert it into a proc. if no block is given
56
+ # then it is a nil object that is returned
57
+ def proc_from(&block)
58
+ if block_given?
59
+ Proc.new
60
+ else
61
+ nil
62
+ end
63
+ end
64
+
65
+ end # class << self
66
+
67
+ end # TypeAccessor
68
+
69
+ end # Utils
70
+
71
+ end # PackerFiles
@@ -0,0 +1,72 @@
1
+ # Requires
2
+ require 'Utils/TypeAccessor'
3
+ require 'Core/Hypervisor'
4
+
5
+ module PackerFiles
6
+
7
+ module Virtual
8
+
9
+ # Internal List of Hypervisors that are supported. All of them Just override
10
+ # the Custom Object call.
11
+ class I_VirtualBox < Core::Hypervisor
12
+ def Custom(&block)
13
+ @custom = VirtualBox.new(&block)
14
+ end
15
+ end
16
+
17
+ class I_VMWare < Core::Hypervisor
18
+ def Custom(&block)
19
+ @custom = VMWare.new(&block)
20
+ end
21
+ end
22
+
23
+ class I_KVM < Core::Hypervisor
24
+ def Custom(&block)
25
+ @custom = KVM.new(&block)
26
+ end
27
+ end
28
+
29
+ # Top level class for managing hypervisors in a OS Spec file
30
+ class Hypervisors < Utils::TypeAccessor
31
+
32
+ # Documentation for this class
33
+ def self.doc_file
34
+ PackerFiles.DirPath('Virtual/example/Hypervisors.txt').first
35
+ end
36
+
37
+ # Specify accessors for various supported Hypervisors
38
+ type_accessor I_VirtualBox, :VirtualBox
39
+ type_accessor I_VMWare, :VMWare
40
+ type_accessor I_KVM, :KVM
41
+
42
+ # Constructor just yields self for further initialization
43
+ def initialize(&block)
44
+ yield self if block_given?
45
+ end
46
+
47
+ # Given a generator and a OS class derived from builder, convert
48
+ # it into hashes suitable for packer json file generation
49
+ def convert(gen, builder)
50
+
51
+ # Convert parameters into hash for registered Hypervisors
52
+ if !self.VirtualBox.nil?
53
+ hash = builder.vbox_converter_hook(gen)
54
+ gen.builders.push(hash) if !hash.nil?
55
+ end
56
+ if !self.VMWare.nil?
57
+ hash = builder.vmware_converter_hook(gen)
58
+ gen.builders.push(hash) if !hash.nil?
59
+ end
60
+ if !self.KVM.nil?
61
+ hash = builder.kvm_converter_hook(gen)
62
+ gen.builders.push(hash) if !hash.nil?
63
+ end
64
+
65
+ end
66
+
67
+ end # Hypervisors
68
+
69
+ end # Virtual
70
+
71
+ end # PackerFiles
72
+