PackerFiles 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+