vagrant-softlayer 0.3.1 → 0.3.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -24
  3. data/QUICKSTART.md +377 -0
  4. data/README.md +25 -20
  5. data/contrib/README.md +8 -1
  6. data/contrib/vagrant-softlayer-boxes +416 -408
  7. data/contrib/vagrant-softlayer-vlans +329 -0
  8. data/contrib/vagrantcloud/CENTOS_5_32.box +0 -0
  9. data/contrib/vagrantcloud/CENTOS_5_64.box +0 -0
  10. data/contrib/vagrantcloud/CENTOS_6_32.box +0 -0
  11. data/contrib/vagrantcloud/CENTOS_6_64.box +0 -0
  12. data/contrib/vagrantcloud/CENTOS_LATEST.box +0 -0
  13. data/contrib/vagrantcloud/CENTOS_LATEST_32.box +0 -0
  14. data/contrib/vagrantcloud/CENTOS_LATEST_64.box +0 -0
  15. data/contrib/vagrantcloud/CLOUDLINUX_5_32.box +0 -0
  16. data/contrib/vagrantcloud/CLOUDLINUX_5_64.box +0 -0
  17. data/contrib/vagrantcloud/CLOUDLINUX_6_32.box +0 -0
  18. data/contrib/vagrantcloud/CLOUDLINUX_6_64.box +0 -0
  19. data/contrib/vagrantcloud/CLOUDLINUX_LATEST.box +0 -0
  20. data/contrib/vagrantcloud/CLOUDLINUX_LATEST_32.box +0 -0
  21. data/contrib/vagrantcloud/CLOUDLINUX_LATEST_64.box +0 -0
  22. data/contrib/vagrantcloud/DEBIAN_5_32.box +0 -0
  23. data/contrib/vagrantcloud/DEBIAN_5_64.box +0 -0
  24. data/contrib/vagrantcloud/DEBIAN_6_32.box +0 -0
  25. data/contrib/vagrantcloud/DEBIAN_6_64.box +0 -0
  26. data/contrib/vagrantcloud/DEBIAN_7_32.box +0 -0
  27. data/contrib/vagrantcloud/DEBIAN_7_64.box +0 -0
  28. data/contrib/vagrantcloud/DEBIAN_LATEST.box +0 -0
  29. data/contrib/vagrantcloud/DEBIAN_LATEST_32.box +0 -0
  30. data/contrib/vagrantcloud/DEBIAN_LATEST_64.box +0 -0
  31. data/contrib/vagrantcloud/REDHAT_5_32.box +0 -0
  32. data/contrib/vagrantcloud/REDHAT_5_64.box +0 -0
  33. data/contrib/vagrantcloud/REDHAT_6_32.box +0 -0
  34. data/contrib/vagrantcloud/REDHAT_6_64.box +0 -0
  35. data/contrib/vagrantcloud/REDHAT_LATEST.box +0 -0
  36. data/contrib/vagrantcloud/REDHAT_LATEST_32.box +0 -0
  37. data/contrib/vagrantcloud/REDHAT_LATEST_64.box +0 -0
  38. data/contrib/vagrantcloud/SL_GENERIC.box +0 -0
  39. data/contrib/vagrantcloud/UBUNTU_10_32.box +0 -0
  40. data/contrib/vagrantcloud/UBUNTU_10_64.box +0 -0
  41. data/contrib/vagrantcloud/UBUNTU_12_32.box +0 -0
  42. data/contrib/vagrantcloud/UBUNTU_12_64.box +0 -0
  43. data/contrib/vagrantcloud/UBUNTU_14_32.box +0 -0
  44. data/contrib/vagrantcloud/UBUNTU_14_64.box +0 -0
  45. data/contrib/vagrantcloud/UBUNTU_8_32.box +0 -0
  46. data/contrib/vagrantcloud/UBUNTU_8_64.box +0 -0
  47. data/contrib/vagrantcloud/UBUNTU_LATEST.box +0 -0
  48. data/contrib/vagrantcloud/UBUNTU_LATEST_32.box +0 -0
  49. data/contrib/vagrantcloud/UBUNTU_LATEST_64.box +0 -0
  50. data/contrib/vagrantcloud/VYATTACE_6.5_64.box +0 -0
  51. data/contrib/vagrantcloud/VYATTACE_6.6_64.box +0 -0
  52. data/contrib/vagrantcloud/VYATTACE_LATEST.box +0 -0
  53. data/contrib/vagrantcloud/VYATTACE_LATEST_64.box +0 -0
  54. data/contrib/vagrantcloud/WIN_2003-DC-SP2-1_32.box +0 -0
  55. data/contrib/vagrantcloud/WIN_2003-DC-SP2-1_64.box +0 -0
  56. data/contrib/vagrantcloud/WIN_2003-ENT-SP2-5_32.box +0 -0
  57. data/contrib/vagrantcloud/WIN_2003-ENT-SP2-5_64.box +0 -0
  58. data/contrib/vagrantcloud/WIN_2003-STD-SP2-5_32.box +0 -0
  59. data/contrib/vagrantcloud/WIN_2003-STD-SP2-5_64.box +0 -0
  60. data/contrib/vagrantcloud/WIN_2008-DC-R2_64.box +0 -0
  61. data/contrib/vagrantcloud/WIN_2008-DC-SP2_32.box +0 -0
  62. data/contrib/vagrantcloud/WIN_2008-DC-SP2_64.box +0 -0
  63. data/contrib/vagrantcloud/WIN_2008-ENT-R2_64.box +0 -0
  64. data/contrib/vagrantcloud/WIN_2008-ENT-SP2_32.box +0 -0
  65. data/contrib/vagrantcloud/WIN_2008-ENT-SP2_64.box +0 -0
  66. data/contrib/vagrantcloud/WIN_2008-STD-R2-SP1_64.box +0 -0
  67. data/contrib/vagrantcloud/WIN_2008-STD-R2_64.box +0 -0
  68. data/contrib/vagrantcloud/WIN_2008-STD-SP2_32.box +0 -0
  69. data/contrib/vagrantcloud/WIN_2008-STD-SP2_64.box +0 -0
  70. data/contrib/vagrantcloud/WIN_2012-DC_64.box +0 -0
  71. data/contrib/vagrantcloud/WIN_2012-STD_64.box +0 -0
  72. data/contrib/vagrantcloud/WIN_LATEST.box +0 -0
  73. data/contrib/vagrantcloud/WIN_LATEST_32.box +0 -0
  74. data/contrib/vagrantcloud/WIN_LATEST_64.box +0 -0
  75. data/lib/vagrant-softlayer/action.rb +20 -16
  76. data/lib/vagrant-softlayer/action/create_instance.rb +24 -8
  77. data/lib/vagrant-softlayer/action/setup_softlayer.rb +2 -1
  78. data/lib/vagrant-softlayer/action/sync_folders.rb +99 -99
  79. data/lib/vagrant-softlayer/action/wait_for_rebuild.rb +36 -36
  80. data/lib/vagrant-softlayer/config.rb +10 -2
  81. data/lib/vagrant-softlayer/errors.rb +33 -29
  82. data/lib/vagrant-softlayer/plugin.rb +77 -77
  83. data/lib/vagrant-softlayer/util/load_balancer.rb +103 -103
  84. data/lib/vagrant-softlayer/util/network.rb +75 -73
  85. data/lib/vagrant-softlayer/util/warden.rb +38 -38
  86. data/lib/vagrant-softlayer/version.rb +5 -5
  87. data/locales/en.yml +6 -0
  88. data/spec/vagrant-softlayer/config_spec.rb +4 -2
  89. data/vagrant-softlayer.gemspec +55 -55
  90. metadata +71 -2
data/README.md CHANGED
@@ -79,26 +79,27 @@ See [Join load balancers](https://github.com/audiolize/vagrant-softlayer/wiki/Jo
79
79
 
80
80
  ### Instance Configuration
81
81
 
82
- Parameter | Description | Default | Required
83
- ------------------ | ---------------------------------------------------------- | ----------------------- | --------
84
- `datacenter` | Datacenter shortname | First available | no
85
- `dedicated` | Allocate a dedicated CCI (non-shared host) | false | no
86
- `disk_capacity` | The capacity of each disk | | no **
87
- `domain` | The domain of the instance | | yes
88
- `hostname` | The hostname of the instance | | yes *
89
- `hourly_billing` | Hourly billing type (false for monthly) | true | no
90
- `image_guid` | The global identifier for the compute or flex image to use | | no **
91
- `local_disk` | Use a local disk (false for SAN) | true | no
92
- `max_memory` | The amount of RAM of the instance in Mb | 1024 | no
93
- `network_speed` | Network port speed in Mbps | 10 | no
94
- `operating_system` | The instance operating system identifier | UBUNTU_LATEST | no **
95
- `post_install` | URI of Post-install script to download | | no
96
- `private_only` | Only create access to the private network | false | no
97
- `ssh_key` | ID or label of the SSH key(s) to provision | | yes
98
- `start_cpus` | The number of processors of the instance | 1 | no
99
- `user_data` | User defined metadata string | | no
100
- `vlan_private` | The ID of the private VLAN | Automatically generated | no
101
- `vlan_public` | The ID of the public VLAN | Automatically generated | no
82
+ Parameter | Description | Default | Required
83
+ ------------------ | -----------------------------------------------------------| ----------------| --------
84
+ `datacenter` | Datacenter shortname | First available | no
85
+ `dedicated` | Allocate a dedicated CCI (non-shared host) | false | no
86
+ `disk_capacity` | The capacity of each disk | | no **
87
+ `domain` | The domain of the instance | | yes
88
+ `force_private_ip` | Use private IP for communication even if public IP is set | false | no
89
+ `hostname` | The hostname of the instance | | yes *
90
+ `hourly_billing` | Hourly billing type (false for monthly) | true | no
91
+ `image_guid` | The global identifier for the compute or flex image to use | | no **
92
+ `local_disk` | Use a local disk (false for SAN) | true | no
93
+ `max_memory` | The amount of RAM of the instance in Mb | 1024 | no
94
+ `network_speed` | Network port speed in Mbps | 10 | no
95
+ `operating_system` | The instance operating system identifier | UBUNTU_LATEST | no **
96
+ `post_install` | URI of Post-install script to download | | no
97
+ `private_only` | Only create access to the private network | false | no
98
+ `ssh_key` | ID or label of the SSH key(s) to provision | | yes
99
+ `start_cpus` | The number of processors of the instance | 1 | no
100
+ `user_data` | User defined metadata string | | no
101
+ `vlan_private` | The ID, name or qualified name of the private VLAN | Auto-generated | no
102
+ `vlan_public` | The ID, name or qualified name of the public VLAN | Auto-generated | no
102
103
 
103
104
  \* The `hostname` could be specified either using `config.vm.hostname` or the provider parameter.
104
105
 
@@ -208,6 +209,10 @@ Also, a bunch of aliases for the `ssh_key` parameter are provided for better sem
208
209
  * `ssh_key_name`
209
210
  * `ssh_key_names`
210
211
 
212
+ ## Quick Start Guide
213
+
214
+ For those new to Vagrant, see the [Quick Start Guide](https://github.com/audiolize/vagrant-softlayer/blob/master/QUICKSTART.md).
215
+
211
216
  ## Development
212
217
 
213
218
  To work on the `vagrant-softlayer` plugin, clone this repository out, and use
data/contrib/README.md CHANGED
@@ -6,6 +6,13 @@ for each item will be kept below.
6
6
 
7
7
  ## List of Contrib Items
8
8
 
9
+ * `vagrantcloud` - Vagrant boxes used by Vagrant Cloud examples in the Quick Start
10
+ guide or for manual install locally without having to use `vagrant-softlayer-boxes`.
9
11
  * `vagrant-softlayer-boxes` - Vagrant box creation tool which allows you to create
10
12
  starter boxes from those offered in the SoftLayer API or from public/private compute
11
- or flex images associated with your SoftLayer account.
13
+ or flex images associated with your SoftLayer account.
14
+ * `vagrant-softlayer-vlans` - SoftLayer vlan tool which allows you to list the data
15
+ for all SoftLayer vlans associated with your account that are usable for assigning to
16
+ CCI's during `vagrant-softlayer` provisioning. It provides the id, name, and qualified
17
+ name of vlans that can be used with the `vlan_private` and `vlan_public`
18
+ `vagrant-softlayer` settings.
@@ -1,408 +1,416 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'getoptlong'
4
- require 'tmpdir'
5
-
6
- require 'rubygems'
7
- require 'softlayer_api'
8
-
9
- $sl = {
10
- :data => {
11
- :create_opts => nil,
12
- :private_images => nil,
13
- :public_images => nil
14
- },
15
- :service => {
16
- :account => nil,
17
- :virtual_guest => nil,
18
- :virtual_guest_block_device_template_group => nil
19
- },
20
- :sl_credentials => {
21
- :api_key => nil,
22
- :endpoint_url => SoftLayer::API_PUBLIC_ENDPOINT,
23
- :username => nil
24
- }
25
- }
26
-
27
- $boxes = {
28
- :data => {},
29
- :datacenter => nil,
30
- :dir => {
31
- :boxes => "boxes",
32
- :vagrantfiles => "vagrantfiles",
33
- :boxes_root => nil,
34
- :output_root => File.expand_path("."),
35
- :vagrantfiles_root => nil
36
- },
37
- :domain => nil,
38
- :file_templates => {
39
- :created_by => "# vagrant-softlayer-boxes automatic template export",
40
- :end => "end",
41
- :image_detail => "# Compute or flex image details:",
42
- :indent => Hash.new() { |hash, key| hash[key] = " " * key },
43
- :metadata_json => "{\"provider\": \"softlayer\"}",
44
- :os_templates_avail => "# Available versions of this OS template (based on VM property selections):",
45
- :sl_config_start => "config.vm.provider :softlayer do |sl|",
46
- :vagrant_config_start => "Vagrant.configure(\"2\") do |config|"
47
- },
48
- :filter => nil,
49
- :images => {
50
- :private => true,
51
- :public => true
52
- },
53
- :metadata_path => nil,
54
- :monthly_billing => nil,
55
- :templates => true,
56
- :vlan_private => nil,
57
- :vlan_public => nil
58
- }
59
-
60
- def procCliOptions()
61
- opts = GetoptLong.new(
62
- [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
63
- [ '--output_dir', '-o', GetoptLong::REQUIRED_ARGUMENT ],
64
- [ '--only_images', '-i', GetoptLong::NO_ARGUMENT ],
65
- [ '--only_private_images', '-p', GetoptLong::NO_ARGUMENT ],
66
- [ '--only_public_images', '-g', GetoptLong::NO_ARGUMENT ],
67
- [ '--only_templates', '-t', GetoptLong::NO_ARGUMENT ],
68
- [ '--default_domain', GetoptLong::REQUIRED_ARGUMENT ],
69
- [ '--default_datacenter', GetoptLong::REQUIRED_ARGUMENT ],
70
- [ '--default_monthly_billing', GetoptLong::NO_ARGUMENT ],
71
- [ '--default_vlan_private', GetoptLong::REQUIRED_ARGUMENT ],
72
- [ '--default_vlan_public', GetoptLong::REQUIRED_ARGUMENT ],
73
- [ '--sl_api_key', '-k', GetoptLong::REQUIRED_ARGUMENT ],
74
- [ '--sl_endpoint_url', '-e', GetoptLong::REQUIRED_ARGUMENT ],
75
- [ '--sl_username','-u', GetoptLong::REQUIRED_ARGUMENT ]
76
- )
77
-
78
- opts.each do | opt, optval |
79
- case opt
80
- when '--help'
81
- puts <<-EOF
82
- vagrant-softlayer-boxes [OPTION] [FILTER]
83
-
84
- --help, -h:
85
- Print this help.
86
-
87
- --sl_username USERNAME, -u USERNAME:
88
- Sets the SoftLayer account user name. If not specified, it is assumed SL_API_USERNAME environment variable is set.
89
-
90
- --sl_api_key SL_API_KEY, -k SL_API_KEY:
91
- Sets the SoftLayer API key. If not specified, it is assumed SL_API_KEY environment variable is set.
92
-
93
- --sl_endpoint_url SL_API_BASE_URL, -e SL_API_BASE_URL:
94
- Sets the SoftLayer endpoint URL. If not specified, it assumed SL_API_BASE_URL environment variable is set to API_PUBLIC_ENDPOINT or API_PRIVATE_ENDPOINT.
95
- Defaults to API_PUBLIC_ENDPOINT.
96
-
97
- --output_dir OUTPUTDIR, -o OUTPUTDIR:
98
- Sets the root directory to create box output under.
99
-
100
- --only_templates, -t:
101
- Only create boxes for the CCI templates and not compute or flex images.
102
-
103
- --only_images, -i:
104
- Only create boxes for the compute or flex images and not the CCI templates.
105
-
106
- --only_public_images, -g:
107
- Only create boxes for the public compute or flex images and not the CCI templates.
108
-
109
- --only_private_images, -p:
110
- Only create boxes for the private compute or flex images and not the CCI templates.
111
-
112
- --default_domain:
113
- Set default vm domain.
114
-
115
- --default_datacenter:
116
- Set default vm datacenter.
117
-
118
- --default_monthly_billing:
119
- Set default billing type to monthly.
120
-
121
- --default_vlan_private:
122
- Set default vm private vlan.
123
-
124
- --default_vlan_public:
125
- Set default vm public vlan.
126
-
127
- FILTER
128
- String used to filter template and compute/flex images by name to export boxes for specific matches. Supports filtering by regular expression.
129
-
130
- EOF
131
-
132
- exit 0
133
-
134
- when '--sl_username'
135
- $sl[:sl_credentials][:username] = optval.to_s
136
-
137
- when '--sl_api_key'
138
- $sl[:sl_credentials][:api_key] = optval.to_s
139
-
140
- when '--sl_endpoint_url'
141
- if ! [ "API_PUBLIC_ENDPOINT", "API_PRIVATE_ENDPOINT" ].include?(optval.to_s.upcase)
142
- $stderr.puts "ERROR: Invalid endpoint_url value: " + optval.to_s.upcase
143
- exit 2
144
- end
145
-
146
- $sl[:sl_credentials][:endpoint_url] = (optval.to_s.upcase == 'API_PUBLIC_ENDPOINT' ? SoftLayer::API_PUBLIC_ENDPOINT : SoftLayer::API_PRIVATE_ENDPOINT )
147
-
148
- when '--output_dir'
149
- if File.exists?(optval.to_s) && File.ftype(optval.to_s) != 'directory'
150
- $stderr.puts "ERROR: Path is not a directory: " + optval.to_s
151
- exit 2
152
- end
153
-
154
- $boxes[:dir][:output_root] = File.expand_path(optval.to_s)
155
- $boxes[:dir][:vagrantfiles_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles])
156
- $boxes[:dir][:boxes_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:boxes])
157
-
158
- if File.exists?($boxes[:dir][:vagrantfiles_root]) && File.ftype($boxes[:dir][:vagrantfiles_root]) != 'directory'
159
- $stderr.puts "ERROR: Output directory subdir is not a directory: " + $boxes[:dir][:vagrantfiles_root]
160
- exit 2
161
- end
162
-
163
- if File.exists?($boxes[:dir][:boxes_root]) && File.ftype($boxes[:dir][:boxes_root]) != 'directory'
164
- $stderr.puts "ERROR: Output directory subdir is not a directory: " + $boxes[:dir][:boxes_root]
165
- exit 2
166
- end
167
-
168
- when '--only_templates'
169
- $boxes[:images][:public] = false
170
- $boxes[:images][:private] = false
171
-
172
- when '--only_images'
173
- $boxes[:templates] = false
174
-
175
- when '--only_public_images'
176
- $boxes[:templates] = false
177
- $boxes[:images][:private] = false
178
-
179
- when '--only_private_images'
180
- $boxes[:templates] = false
181
- $boxes[:images][:public] = false
182
-
183
- when '--default_domain'
184
- $boxes[:domain] = optval.to_s
185
-
186
- when '--default_datacenter'
187
- $boxes[:datacenter] = optval.to_s
188
-
189
- when '--default_monthly_billing'
190
- $boxes[:monthly_billing] = true
191
-
192
- when '--default_vlan_private'
193
- $boxes[:vlan_private] = optval.to_s
194
-
195
- when'--default_vlan_public'
196
- $boxes[:vlan_public] = optval.to_s
197
-
198
- end
199
- end
200
-
201
- $boxes[:dir][:vagrantfiles_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles])
202
- $boxes[:dir][:boxes_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:boxes])
203
- $boxes[:metadata_path] = File.join($boxes[:dir][:output_root], "metadata.json")
204
-
205
- begin
206
- [ $boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles_root], $boxes[:dir][:boxes_root] ].each do |path|
207
- Dir.mkdir(path, 0755) if ! File.exists?(path)
208
- end
209
- rescue Exception => e
210
- $stderr.puts "ERROR: Failed to create output directories: " + e.message
211
- exit 1
212
- end
213
-
214
- $sl[:sl_credentials][:username] = ENV["SL_API_USERNAME"] if $sl[:sl_credentials][:username].nil? && ENV.include?("SL_API_USERNAME")
215
- $sl[:sl_credentials][:api_key] = ENV["SL_API_KEY"] if $sl[:sl_credentials][:api_key].nil? && ENV.include?("SL_API_KEY")
216
- $sl[:sl_credentials][:endpoint_url] = (ENV["SL_API_BASE_URL"] == "API_PUBLIC_ENDPOINT" ? SoftLayer::API_PUBLIC_ENDPOINT : SoftLayer::API_PRIVATE_ENDPOINT ) if $sl[:sl_credentials][:endpoint_url].nil? && ENV.include?("SL_API_BASE_URL")
217
-
218
- if $sl[:sl_credentials][:username].nil?
219
- $stderr.puts "ERROR: No SoftLayer username specified"
220
- exit 2
221
- end
222
-
223
- if $sl[:sl_credentials][:username].nil?
224
- $stderr.puts "ERROR: No SoftLayer user name specified"
225
- exit 2
226
- end
227
-
228
- if $sl[:sl_credentials][:api_key].nil?
229
- $stderr.puts "ERROR: No SoftLayer API key specified"
230
- exit 2
231
- end
232
- end
233
-
234
- def procCliArgs()
235
- if ARGV.length > 2
236
- $stderr.puts "ERROR: Invalid argument supplied, please check help"
237
- exit 2
238
- elsif ARGV.length == 1
239
- begin
240
- $boxes[:filter] = Regexp.new(ARGV[0], Regexp::IGNORECASE)
241
- rescue Exception => e
242
- $stderr.puts "ERROR: Filter value is not a valid regular expression: " + e.message
243
- exit 2
244
- end
245
- end
246
- end
247
-
248
- def getBoxData()
249
- begin
250
- $sl[:service][:virtual_guest] = SoftLayer::Service.new("SoftLayer_Virtual_Guest", $sl[:sl_credentials]) if $boxes[:templates]
251
- $sl[:service][:account] = SoftLayer::Service.new("SoftLayer_Account", $sl[:sl_credentials]) if $boxes[:images][:private]
252
- $sl[:service][:virtual_guest_block_device_template_group] = SoftLayer::Service.new("SoftLayer_Virtual_Guest_Block_Device_Template_Group", $sl[:sl_credentials]) if $boxes[:images][:public]
253
- rescue Exception => e
254
- $stderr.puts "ERROR: Failed to create SoftLayer service object: " + e.message
255
- exit 1
256
- end
257
-
258
- begin
259
- $sl[:data][:create_opts] = $sl[:service][:virtual_guest].getCreateObjectOptions if $boxes[:templates]
260
- $sl[:data][:private_images] = $sl[:service][:account].getBlockDeviceTemplateGroups.delete_if { |block_device| ! block_device.has_key?("globalIdentifier") } if $boxes[:images][:private]
261
- $sl[:data][:public_images] = $sl[:service][:virtual_guest_block_device_template_group].getPublicImages.delete_if { |block_device| ! block_device.has_key?("globalIdentifier") } if $boxes[:images][:public]
262
- rescue Exception => e
263
- $stderr.puts "ERROR: Failed to retrieve SoftLayer service data: " + e.message
264
- exit 1
265
- end
266
-
267
- if $boxes[:templates]
268
- $sl[:data][:create_opts]["operatingSystems"].each do |os|
269
- boxgroup = os["template"]["operatingSystemReferenceCode"].strip.gsub(/[()]/,'').gsub(/[^a-zA-Z0-9_.-]/, '_').upcase
270
-
271
- #We dont want to allow separate instances for templates of same group name since the only difference is additional descriptions
272
- if ! $boxes[:data].has_key?(boxgroup)
273
- $boxes[:data][boxgroup] = Array.new()
274
-
275
- $boxes[:data][boxgroup].push(
276
- {
277
- :type => :template,
278
- :name => os["template"]["operatingSystemReferenceCode"],
279
- :description => [ os["itemPrice"]["item"]["description"] ]
280
- }
281
- )
282
- else
283
- $boxes[:data][boxgroup][0][:description].push(os["itemPrice"]["item"]["description"])
284
- end
285
- end
286
- end
287
-
288
- $boxes[:images].each_key do |image_view|
289
- if $boxes[:images][image_view]
290
- $sl[:data][(image_view == :public ? :public_images : :private_images)].each do |image|
291
- boxgroup = image["name"].strip.gsub(/[()]/,'').gsub(/[^a-zA-Z0-9_.-]/, '_').upcase
292
-
293
- $boxes[:data][boxgroup] = Array.new() if ! $boxes[:data].has_key?(boxgroup)
294
- $boxes[:data][boxgroup].push(
295
- {
296
- :type => :block_image,
297
- :name => image["name"],
298
- :global_id => image["globalIdentifier"],
299
- :note => image["note"].to_s,
300
- :summary => image["summary"].to_s,
301
- :visibility => image_view
302
- }
303
- )
304
- end
305
- end
306
- end
307
- end
308
-
309
- def filterBoxes()
310
- if ! $boxes[:filter].nil?
311
- $boxes[:data].each_key do |boxgroup|
312
- begin
313
- $boxes[:data][boxgroup].delete_if { |box| ! box[:name].match($boxes[:filter]) }
314
- rescue Exception => e
315
- $stderr.puts "ERROR: Failed to filter Softlayer boxes: " + e.message
316
- exit 1
317
- end
318
- end
319
- end
320
- end
321
-
322
- def saveBoxFiles()
323
- begin
324
- File.open($boxes[:metadata_path], "w", 0644) { |fout| fout.puts $boxes[:file_templates][:metadata_json] }
325
- rescue Exception => e
326
- $stderr.puts "ERROR: Failed to save box metadata JSON data: " + e.message
327
- exit 1
328
- end
329
-
330
- $boxes[:data].each_key do |boxgroup|
331
- $boxes[:data][boxgroup].each do |box|
332
- boxFileName = ($boxes[:data][boxgroup].length > 1 ? boxgroup + "_" + ($boxes[:data][boxgroup].index(box) + 1).to_s : boxgroup)
333
-
334
- begin
335
- File.open(File.join($boxes[:dir][:vagrantfiles_root], boxFileName + ".vagrantfile"), "w", 0644) do |fout|
336
- fout.puts $boxes[:file_templates][:created_by]
337
- fout.puts
338
-
339
- fout.puts $boxes[:file_templates][:os_templates_avail] if box[:type] == :template
340
- fout.puts box[:description].map { |descr| "# " + descr }.join("\n") if box[:type] == :template
341
-
342
- fout.puts $boxes[:file_templates][:image_detail] if box[:type] == :block_image
343
- fout.puts "# Global Identifier: " + box[:global_id].to_s if box[:type] == :block_image
344
- fout.puts "# Name: " + box[:name] if box[:type] == :block_image
345
- fout.puts "# Summary: " + box[:summary].to_s if box[:type] == :block_image
346
- fout.puts "# Note: " + box[:note].to_s if box[:type] == :block_image
347
- fout.puts "# Visibility: " + (box[:visibility] == :public ? "public" : "private" ) if box[:type] == :block_image
348
-
349
- fout.puts
350
- fout.puts $boxes[:file_templates][:vagrant_config_start]
351
- fout.puts $boxes[:file_templates][:indent][4] + $boxes[:file_templates][:sl_config_start]
352
-
353
- fout.puts $boxes[:file_templates][:indent][8] + "sl.datacenter = \"" + $boxes[:datacenter] + "\"" if $boxes[:datacenter]
354
- fout.puts $boxes[:file_templates][:indent][8] + "sl.domain = \"" + $boxes[:domain] + "\"" if $boxes[:domain]
355
- fout.puts $boxes[:file_templates][:indent][8] + "sl.hourly_billing = false" if $boxes[:monthly_billing]
356
- fout.puts $boxes[:file_templates][:indent][8] + "sl.operating_system = \"" + box[:name] + "\"" if box[:type] == :template
357
- fout.puts $boxes[:file_templates][:indent][8] + "sl.image_guid = \"" + box[:global_id].to_s + "\"" if box[:type] == :block_image
358
- fout.puts $boxes[:file_templates][:indent][8] + "sl.vlan_private = \"" + $boxes[:vlan_private] + "\"" if $boxes[:vlan_private]
359
- fout.puts $boxes[:file_templates][:indent][8] + "sl.vlan_public = \"" + $boxes[:vlan_public] + "\"" if $boxes[:vlan_public]
360
-
361
- fout.puts $boxes[:file_templates][:indent][4] + $boxes[:file_templates][:end]
362
- fout.puts $boxes[:file_templates][:end]
363
- end
364
- rescue Exception => e
365
- $stderr.puts "ERROR: Failed to save box Vagrantfile: " + e.message
366
- exit 1
367
- end
368
- end
369
- end
370
- end
371
-
372
- def createBoxes()
373
- $boxes[:data].each_key do |boxgroup|
374
- $boxes[:data][boxgroup].each do |box|
375
- boxFileName = ($boxes[:data][boxgroup].length > 1 ? boxgroup + "_" + ($boxes[:data][boxgroup].index(box) + 1).to_s : boxgroup)
376
-
377
- begin
378
- Dir.mktmpdir do |tmpDir|
379
- FileUtils.cd(tmpDir) do
380
- FileUtils.cp($boxes[:metadata_path], File.join(tmpDir,"metadata.json"), :preserve => true)
381
- FileUtils.cp(File.join($boxes[:dir][:vagrantfiles_root], boxFileName + ".vagrantfile"), File.join(tmpDir, "Vagrantfile"), :preserve => true)
382
-
383
- result = %x(tar -czvf "#{File.join($boxes[:dir][:boxes_root], boxFileName + ".box.tar.gz")}" Vagrantfile metadata.json)
384
-
385
- raise result if $?.exitstatus != 0
386
-
387
- FileUtils.mv(File.join($boxes[:dir][:boxes_root], boxFileName + ".box.tar.gz"), File.join($boxes[:dir][:boxes_root], boxFileName + ".box"), :force => true)
388
- FileUtils.chmod(0644, File.join($boxes[:dir][:boxes_root], boxFileName + ".box"))
389
- end
390
- end
391
- rescue Exception => e
392
- $stderr.puts "ERROR: Failed to save Vagrant box: " + e.message
393
- exit 1
394
- end
395
- end
396
- end
397
- end
398
-
399
- def main()
400
- procCliOptions()
401
- procCliArgs()
402
- getBoxData()
403
- filterBoxes()
404
- saveBoxFiles()
405
- createBoxes()
406
- end
407
-
408
- main
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'getoptlong'
4
+ require 'tmpdir'
5
+
6
+ require 'rubygems'
7
+ require 'softlayer_api'
8
+
9
+ $sl = {
10
+ :data => {
11
+ :create_opts => nil,
12
+ :private_images => nil,
13
+ :public_images => nil
14
+ },
15
+ :service => {
16
+ :account => nil,
17
+ :virtual_guest => nil,
18
+ :virtual_guest_block_device_template_group => nil
19
+ },
20
+ :sl_credentials => {
21
+ :api_key => nil,
22
+ :endpoint_url => SoftLayer::API_PUBLIC_ENDPOINT,
23
+ :username => nil
24
+ }
25
+ }
26
+
27
+ $boxes = {
28
+ :data => {},
29
+ :datacenter => nil,
30
+ :dir => {
31
+ :boxes => "boxes",
32
+ :vagrantfiles => "vagrantfiles",
33
+ :boxes_root => nil,
34
+ :output_root => File.expand_path("."),
35
+ :vagrantfiles_root => nil
36
+ },
37
+ :domain => nil,
38
+ :file_templates => {
39
+ :created_by => "# vagrant-softlayer-boxes automatic template export",
40
+ :end => "end",
41
+ :image_detail => "# Compute or flex image details:",
42
+ :indent => Hash.new() { |hash, key| hash[key] = " " * key },
43
+ :metadata_json => "{\"provider\": \"softlayer\"}",
44
+ :os_templates_avail => "# Available versions of this OS template (based on VM property selections):",
45
+ :sl_config_start => "config.vm.provider :softlayer do |sl|",
46
+ :vagrant_config_start => "Vagrant.configure(\"2\") do |config|"
47
+ },
48
+ :filter => nil,
49
+ :images => {
50
+ :private => true,
51
+ :public => true
52
+ },
53
+ :metadata_path => nil,
54
+ :monthly_billing => nil,
55
+ :templates => true,
56
+ :vlan_private => nil,
57
+ :vlan_public => nil
58
+ }
59
+
60
+ def procCliOptions()
61
+ opts = GetoptLong.new(
62
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
63
+ [ '--output_dir', '-o', GetoptLong::REQUIRED_ARGUMENT ],
64
+ [ '--only_images', '-i', GetoptLong::NO_ARGUMENT ],
65
+ [ '--only_private_images', '-p', GetoptLong::NO_ARGUMENT ],
66
+ [ '--only_public_images', '-g', GetoptLong::NO_ARGUMENT ],
67
+ [ '--only_templates', '-t', GetoptLong::NO_ARGUMENT ],
68
+ [ '--default_domain', GetoptLong::REQUIRED_ARGUMENT ],
69
+ [ '--default_datacenter', GetoptLong::REQUIRED_ARGUMENT ],
70
+ [ '--default_monthly_billing', GetoptLong::NO_ARGUMENT ],
71
+ [ '--default_vlan_private', GetoptLong::REQUIRED_ARGUMENT ],
72
+ [ '--default_vlan_public', GetoptLong::REQUIRED_ARGUMENT ],
73
+ [ '--sl_api_key', '-k', GetoptLong::REQUIRED_ARGUMENT ],
74
+ [ '--sl_endpoint_url', '-e', GetoptLong::REQUIRED_ARGUMENT ],
75
+ [ '--sl_username','-u', GetoptLong::REQUIRED_ARGUMENT ]
76
+ )
77
+
78
+ opts.each do | opt, optval |
79
+ case opt
80
+ when '--help'
81
+ puts <<-EOF
82
+ vagrant-softlayer-boxes [OPTION] [FILTER]
83
+
84
+ --help, -h:
85
+ Print this help.
86
+
87
+ --sl_username USERNAME, -u USERNAME:
88
+ Sets the SoftLayer account user name. If not specified, it is assumed SL_API_USERNAME environment variable is set.
89
+
90
+ --sl_api_key SL_API_KEY, -k SL_API_KEY:
91
+ Sets the SoftLayer API key. If not specified, it is assumed SL_API_KEY environment variable is set.
92
+
93
+ --sl_endpoint_url SL_API_BASE_URL, -e SL_API_BASE_URL:
94
+ Sets the SoftLayer endpoint URL. If not specified, it assumed SL_API_BASE_URL environment variable is set to API_PUBLIC_ENDPOINT or API_PRIVATE_ENDPOINT.
95
+ Defaults to API_PUBLIC_ENDPOINT.
96
+
97
+ --output_dir OUTPUTDIR, -o OUTPUTDIR:
98
+ Sets the root directory to create box output under.
99
+
100
+ --only_templates, -t:
101
+ Only create boxes for the CCI templates and not compute or flex images.
102
+
103
+ --only_images, -i:
104
+ Only create boxes for the compute or flex images and not the CCI templates.
105
+
106
+ --only_public_images, -g:
107
+ Only create boxes for the public compute or flex images and not the CCI templates.
108
+
109
+ --only_private_images, -p:
110
+ Only create boxes for the private compute or flex images and not the CCI templates.
111
+
112
+ --default_domain:
113
+ Set default vm domain.
114
+
115
+ --default_datacenter:
116
+ Set default vm datacenter.
117
+
118
+ --default_monthly_billing:
119
+ Set default billing type to monthly.
120
+
121
+ --default_vlan_private:
122
+ Set default vm private vlan.
123
+
124
+ --default_vlan_public:
125
+ Set default vm public vlan.
126
+
127
+ FILTER
128
+ String used to filter template and compute/flex images by name to export boxes for specific matches. Supports filtering by regular expression.
129
+
130
+ EOF
131
+
132
+ exit 0
133
+
134
+ when '--sl_username'
135
+ $sl[:sl_credentials][:username] = optval.to_s
136
+
137
+ when '--sl_api_key'
138
+ $sl[:sl_credentials][:api_key] = optval.to_s
139
+
140
+ when '--sl_endpoint_url'
141
+ if ! [ "API_PUBLIC_ENDPOINT", "API_PRIVATE_ENDPOINT" ].include?(optval.to_s.upcase)
142
+ $stderr.puts "ERROR: Invalid endpoint_url value: " + optval.to_s.upcase
143
+ exit 2
144
+ end
145
+
146
+ $sl[:sl_credentials][:endpoint_url] = (optval.to_s.upcase == 'API_PUBLIC_ENDPOINT' ? SoftLayer::API_PUBLIC_ENDPOINT : SoftLayer::API_PRIVATE_ENDPOINT )
147
+
148
+ when '--output_dir'
149
+ if File.exists?(optval.to_s) && File.ftype(optval.to_s) != 'directory'
150
+ $stderr.puts "ERROR: Path is not a directory: " + optval.to_s
151
+ exit 2
152
+ end
153
+
154
+ $boxes[:dir][:output_root] = File.expand_path(optval.to_s)
155
+ $boxes[:dir][:vagrantfiles_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles])
156
+ $boxes[:dir][:boxes_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:boxes])
157
+
158
+ if File.exists?($boxes[:dir][:vagrantfiles_root]) && File.ftype($boxes[:dir][:vagrantfiles_root]) != 'directory'
159
+ $stderr.puts "ERROR: Output directory subdir is not a directory: " + $boxes[:dir][:vagrantfiles_root]
160
+ exit 2
161
+ end
162
+
163
+ if File.exists?($boxes[:dir][:boxes_root]) && File.ftype($boxes[:dir][:boxes_root]) != 'directory'
164
+ $stderr.puts "ERROR: Output directory subdir is not a directory: " + $boxes[:dir][:boxes_root]
165
+ exit 2
166
+ end
167
+
168
+ when '--only_templates'
169
+ $boxes[:images][:public] = false
170
+ $boxes[:images][:private] = false
171
+
172
+ when '--only_images'
173
+ $boxes[:templates] = false
174
+
175
+ when '--only_public_images'
176
+ $boxes[:templates] = false
177
+ $boxes[:images][:private] = false
178
+
179
+ when '--only_private_images'
180
+ $boxes[:templates] = false
181
+ $boxes[:images][:public] = false
182
+
183
+ when '--default_domain'
184
+ $boxes[:domain] = optval.to_s
185
+
186
+ when '--default_datacenter'
187
+ $boxes[:datacenter] = optval.to_s
188
+
189
+ when '--default_monthly_billing'
190
+ $boxes[:monthly_billing] = true
191
+
192
+ when '--default_vlan_private'
193
+ $boxes[:vlan_private] = optval.to_s
194
+
195
+ when'--default_vlan_public'
196
+ $boxes[:vlan_public] = optval.to_s
197
+
198
+ end
199
+ end
200
+
201
+ $boxes[:dir][:vagrantfiles_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles])
202
+ $boxes[:dir][:boxes_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:boxes])
203
+ $boxes[:metadata_path] = File.join($boxes[:dir][:output_root], "metadata.json")
204
+
205
+ begin
206
+ [ $boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles_root], $boxes[:dir][:boxes_root] ].each do |path|
207
+ Dir.mkdir(path, 0755) if ! File.exists?(path)
208
+ end
209
+ rescue Exception => e
210
+ $stderr.puts "ERROR: Failed to create output directories: " + e.message
211
+ exit 1
212
+ end
213
+
214
+ $sl[:sl_credentials][:username] = ENV["SL_API_USERNAME"] if $sl[:sl_credentials][:username].nil? && ENV.include?("SL_API_USERNAME")
215
+ $sl[:sl_credentials][:api_key] = ENV["SL_API_KEY"] if $sl[:sl_credentials][:api_key].nil? && ENV.include?("SL_API_KEY")
216
+
217
+ if $sl[:sl_credentials][:endpoint_url].nil? && ENV.include?("SL_API_BASE_URL")
218
+ if ! [ 'API_PRIVATE_ENDPOINT', 'API_PUBLIC_ENDPOINT' ].include?(ENV["SL_API_BASE_URL"])
219
+ $stderr.puts "ERROR: Invalid SoftLayer endpoint URL specified in environment variable SL_API_BASE_URL, expected one of #{[ 'API_PRIVATE_ENDPOINT', 'API_PUBLIC_ENDPOINT' ].inspect}: #{ENV["SL_API_BASE_URL"].inspect}"
220
+ exit 2
221
+ end
222
+
223
+ $sl[:sl_credentials][:endpoint_url] = (ENV["SL_API_BASE_URL"] == "API_PUBLIC_ENDPOINT" ? SoftLayer::API_PUBLIC_ENDPOINT : SoftLayer::API_PRIVATE_ENDPOINT )
224
+ end
225
+
226
+ if $sl[:sl_credentials][:username].nil?
227
+ $stderr.puts "ERROR: No SoftLayer username specified"
228
+ exit 2
229
+ end
230
+
231
+ if $sl[:sl_credentials][:username].nil?
232
+ $stderr.puts "ERROR: No SoftLayer user name specified"
233
+ exit 2
234
+ end
235
+
236
+ if $sl[:sl_credentials][:api_key].nil?
237
+ $stderr.puts "ERROR: No SoftLayer API key specified"
238
+ exit 2
239
+ end
240
+ end
241
+
242
+ def procCliArgs()
243
+ if ARGV.length > 2
244
+ $stderr.puts "ERROR: Invalid argument supplied, please check help"
245
+ exit 2
246
+ elsif ARGV.length == 1
247
+ begin
248
+ $boxes[:filter] = Regexp.new(ARGV[0], Regexp::IGNORECASE)
249
+ rescue Exception => e
250
+ $stderr.puts "ERROR: Filter value is not a valid regular expression: " + e.message
251
+ exit 2
252
+ end
253
+ end
254
+ end
255
+
256
+ def getBoxData()
257
+ begin
258
+ $sl[:service][:virtual_guest] = SoftLayer::Service.new("SoftLayer_Virtual_Guest", $sl[:sl_credentials]) if $boxes[:templates]
259
+ $sl[:service][:account] = SoftLayer::Service.new("SoftLayer_Account", $sl[:sl_credentials]) if $boxes[:images][:private]
260
+ $sl[:service][:virtual_guest_block_device_template_group] = SoftLayer::Service.new("SoftLayer_Virtual_Guest_Block_Device_Template_Group", $sl[:sl_credentials]) if $boxes[:images][:public]
261
+ rescue Exception => e
262
+ $stderr.puts "ERROR: Failed to create SoftLayer service object: " + e.message
263
+ exit 1
264
+ end
265
+
266
+ begin
267
+ $sl[:data][:create_opts] = $sl[:service][:virtual_guest].getCreateObjectOptions if $boxes[:templates]
268
+ $sl[:data][:private_images] = $sl[:service][:account].getBlockDeviceTemplateGroups.delete_if { |block_device| ! block_device.has_key?("globalIdentifier") } if $boxes[:images][:private]
269
+ $sl[:data][:public_images] = $sl[:service][:virtual_guest_block_device_template_group].getPublicImages.delete_if { |block_device| ! block_device.has_key?("globalIdentifier") } if $boxes[:images][:public]
270
+ rescue Exception => e
271
+ $stderr.puts "ERROR: Failed to retrieve SoftLayer service data: " + e.message
272
+ exit 1
273
+ end
274
+
275
+ if $boxes[:templates]
276
+ $sl[:data][:create_opts]["operatingSystems"].each do |os|
277
+ boxgroup = os["template"]["operatingSystemReferenceCode"].strip.gsub(/[()]/,'').gsub(/[^a-zA-Z0-9_.-]/, '_').upcase
278
+
279
+ #We dont want to allow separate instances for templates of same group name since the only difference is additional descriptions
280
+ if ! $boxes[:data].has_key?(boxgroup)
281
+ $boxes[:data][boxgroup] = Array.new()
282
+
283
+ $boxes[:data][boxgroup].push(
284
+ {
285
+ :type => :template,
286
+ :name => os["template"]["operatingSystemReferenceCode"],
287
+ :description => [ os["itemPrice"]["item"]["description"] ]
288
+ }
289
+ )
290
+ else
291
+ $boxes[:data][boxgroup][0][:description].push(os["itemPrice"]["item"]["description"])
292
+ end
293
+ end
294
+ end
295
+
296
+ $boxes[:images].each_key do |image_view|
297
+ if $boxes[:images][image_view]
298
+ $sl[:data][(image_view == :public ? :public_images : :private_images)].each do |image|
299
+ boxgroup = image["name"].strip.gsub(/[()]/,'').gsub(/[^a-zA-Z0-9_.-]/, '_').upcase
300
+
301
+ $boxes[:data][boxgroup] = Array.new() if ! $boxes[:data].has_key?(boxgroup)
302
+ $boxes[:data][boxgroup].push(
303
+ {
304
+ :type => :block_image,
305
+ :name => image["name"],
306
+ :global_id => image["globalIdentifier"],
307
+ :note => image["note"].to_s,
308
+ :summary => image["summary"].to_s,
309
+ :visibility => image_view
310
+ }
311
+ )
312
+ end
313
+ end
314
+ end
315
+ end
316
+
317
+ def filterBoxes()
318
+ if ! $boxes[:filter].nil?
319
+ $boxes[:data].each_key do |boxgroup|
320
+ begin
321
+ $boxes[:data][boxgroup].delete_if { |box| ! box[:name].match($boxes[:filter]) }
322
+ rescue Exception => e
323
+ $stderr.puts "ERROR: Failed to filter Softlayer boxes: " + e.message
324
+ exit 1
325
+ end
326
+ end
327
+ end
328
+ end
329
+
330
+ def saveBoxFiles()
331
+ begin
332
+ File.open($boxes[:metadata_path], "w", 0644) { |fout| fout.puts $boxes[:file_templates][:metadata_json] }
333
+ rescue Exception => e
334
+ $stderr.puts "ERROR: Failed to save box metadata JSON data: " + e.message
335
+ exit 1
336
+ end
337
+
338
+ $boxes[:data].each_key do |boxgroup|
339
+ $boxes[:data][boxgroup].each do |box|
340
+ boxFileName = ($boxes[:data][boxgroup].length > 1 ? boxgroup + "_" + ($boxes[:data][boxgroup].index(box) + 1).to_s : boxgroup)
341
+
342
+ begin
343
+ File.open(File.join($boxes[:dir][:vagrantfiles_root], boxFileName + ".vagrantfile"), "w", 0644) do |fout|
344
+ fout.puts $boxes[:file_templates][:created_by]
345
+ fout.puts
346
+
347
+ fout.puts $boxes[:file_templates][:os_templates_avail] if box[:type] == :template
348
+ fout.puts box[:description].map { |descr| "# " + descr }.join("\n") if box[:type] == :template
349
+
350
+ fout.puts $boxes[:file_templates][:image_detail] if box[:type] == :block_image
351
+ fout.puts "# Global Identifier: " + box[:global_id].to_s if box[:type] == :block_image
352
+ fout.puts "# Name: " + box[:name] if box[:type] == :block_image
353
+ fout.puts "# Summary: " + box[:summary].to_s if box[:type] == :block_image
354
+ fout.puts "# Note: " + box[:note].to_s if box[:type] == :block_image
355
+ fout.puts "# Visibility: " + (box[:visibility] == :public ? "public" : "private" ) if box[:type] == :block_image
356
+
357
+ fout.puts
358
+ fout.puts $boxes[:file_templates][:vagrant_config_start]
359
+ fout.puts $boxes[:file_templates][:indent][4] + $boxes[:file_templates][:sl_config_start]
360
+
361
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.datacenter = \"" + $boxes[:datacenter] + "\"" if $boxes[:datacenter]
362
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.domain = \"" + $boxes[:domain] + "\"" if $boxes[:domain]
363
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.hourly_billing = false" if $boxes[:monthly_billing]
364
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.operating_system = \"" + box[:name] + "\"" if box[:type] == :template
365
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.image_guid = \"" + box[:global_id].to_s + "\"" if box[:type] == :block_image
366
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.vlan_private = \"" + $boxes[:vlan_private] + "\"" if $boxes[:vlan_private]
367
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.vlan_public = \"" + $boxes[:vlan_public] + "\"" if $boxes[:vlan_public]
368
+
369
+ fout.puts $boxes[:file_templates][:indent][4] + $boxes[:file_templates][:end]
370
+ fout.puts $boxes[:file_templates][:end]
371
+ end
372
+ rescue Exception => e
373
+ $stderr.puts "ERROR: Failed to save box Vagrantfile: " + e.message
374
+ exit 1
375
+ end
376
+ end
377
+ end
378
+ end
379
+
380
+ def createBoxes()
381
+ $boxes[:data].each_key do |boxgroup|
382
+ $boxes[:data][boxgroup].each do |box|
383
+ boxFileName = ($boxes[:data][boxgroup].length > 1 ? boxgroup + "_" + ($boxes[:data][boxgroup].index(box) + 1).to_s : boxgroup)
384
+
385
+ begin
386
+ Dir.mktmpdir do |tmpDir|
387
+ FileUtils.cd(tmpDir) do
388
+ FileUtils.cp($boxes[:metadata_path], File.join(tmpDir,"metadata.json"), :preserve => true)
389
+ FileUtils.cp(File.join($boxes[:dir][:vagrantfiles_root], boxFileName + ".vagrantfile"), File.join(tmpDir, "Vagrantfile"), :preserve => true)
390
+
391
+ result = %x(tar -czvf "#{File.join($boxes[:dir][:boxes_root], boxFileName + ".box.tar.gz")}" Vagrantfile metadata.json)
392
+
393
+ raise result if $?.exitstatus != 0
394
+
395
+ FileUtils.mv(File.join($boxes[:dir][:boxes_root], boxFileName + ".box.tar.gz"), File.join($boxes[:dir][:boxes_root], boxFileName + ".box"), :force => true)
396
+ FileUtils.chmod(0644, File.join($boxes[:dir][:boxes_root], boxFileName + ".box"))
397
+ end
398
+ end
399
+ rescue Exception => e
400
+ $stderr.puts "ERROR: Failed to save Vagrant box: " + e.message
401
+ exit 1
402
+ end
403
+ end
404
+ end
405
+ end
406
+
407
+ def main()
408
+ procCliOptions()
409
+ procCliArgs()
410
+ getBoxData()
411
+ filterBoxes()
412
+ saveBoxFiles()
413
+ createBoxes()
414
+ end
415
+
416
+ main