@@ -68,17 +68,29 @@ def call(env)
68
68
# If we received a shorthand URL ("mitchellh/precise64"),
69
69
# then expand it properly.
70
70
expanded = false
71
- url . each_index do | i |
72
- next if url [ i ] !~ /^[^ \/ ]+ \/ [^ \/ ]+$/
71
+ # Mark if only a single url entry was provided
72
+ single_entry = url . size == 1
73
73
74
- if !File . file? ( url [ i ] )
74
+ url = url . map do |url_entry |
75
+ if url_entry =~ /^[^\/ ]+\/ [^\/ ]+$/ && !File . file? ( url_entry )
75
76
server = Vagrant . server_url env [ :box_server_url ]
76
77
raise Errors ::BoxServerNotSet if !server
77
78
78
79
expanded = true
79
- url [ i ] = "#{ server } /#{ url [ i ] } "
80
+ # If only a single entry, expand to both the API endpoint and
81
+ # the direct shorthand endpoint.
82
+ if single_entry
83
+ url_entry = [
84
+ "#{ server } /api/v2/vagrant/#{ url_entry } " ,
85
+ "#{ server } /#{ url_entry } "
86
+ ]
87
+ else
88
+ url_entry = "#{ server } /#{ url_entry } "
89
+ end
80
90
end
81
- end
91
+
92
+ url_entry
93
+ end . flatten
82
94
83
95
# Call the hook to transform URLs into authenticated URLs.
84
96
# In the case we don't have a plugin that does this, then it
@@ -99,6 +111,21 @@ def call(env)
99
111
end
100
112
end
101
113
114
+ # If only a single entry was provided, and it was expanded,
115
+ # inspect the metadata check results and extract the one that
116
+ # was successful, with preference to the API endpoint
117
+ if single_entry && expanded
118
+ idx = is_metadata_results . index { |v | v === true }
119
+ # If none of the urls were successful, set the index
120
+ # as the last entry
121
+ idx = is_metadata_results . size - 1 if idx . nil?
122
+
123
+ # Now reset collections with single value
124
+ is_metadata_results = [ is_metadata_results [ idx ] ]
125
+ authed_urls = [ authed_urls [ idx ] ]
126
+ url = [ url [ idx ] ]
127
+ end
128
+
102
129
if expanded && url . length == 1
103
130
is_error = is_metadata_results . find do |b |
104
131
b . is_a? ( Errors ::DownloaderError )
@@ -165,6 +192,7 @@ def add_direct(urls, env)
165
192
env ,
166
193
checksum : env [ :box_checksum ] ,
167
194
checksum_type : env [ :box_checksum_type ] ,
195
+ architecture : env [ :architecture ]
168
196
)
169
197
end
170
198
@@ -179,6 +207,9 @@ def add_direct(urls, env)
179
207
# a Atlas server URL.
180
208
def add_from_metadata ( url , env , expanded )
181
209
original_url = env [ :box_url ]
210
+ architecture = env [ :box_architecture ]
211
+ display_architecture = architecture == :auto ?
212
+ Util ::Platform . architecture : architecture
182
213
provider = env [ :box_provider ]
183
214
provider = Array ( provider ) if provider
184
215
version = env [ :box_version ]
@@ -228,12 +259,17 @@ def add_from_metadata(url, env, expanded)
228
259
end
229
260
230
261
metadata_version = metadata . version (
231
- version || ">= 0" , provider : provider )
262
+ version || ">= 0" ,
263
+ provider : provider ,
264
+ architecture : architecture ,
265
+ )
232
266
if !metadata_version
233
- if provider && !metadata . version ( ">= 0" , provider : provider )
267
+ if provider && !metadata . version ( ">= 0" , provider : provider , architecture : architecture )
234
268
raise Errors ::BoxAddNoMatchingProvider ,
235
269
name : metadata . name ,
236
- requested : provider ,
270
+ requested : [ provider ,
271
+ display_architecture ? "(#{ display_architecture } )" : nil
272
+ ] . compact . join ( " " ) ,
237
273
url : display_url
238
274
else
239
275
raise Errors ::BoxAddNoMatchingVersion ,
@@ -249,16 +285,16 @@ def add_from_metadata(url, env, expanded)
249
285
# If a provider was specified, make sure we get that specific
250
286
# version.
251
287
provider . each do |p |
252
- metadata_provider = metadata_version . provider ( p )
288
+ metadata_provider = metadata_version . provider ( p , architecture )
253
289
break if metadata_provider
254
290
end
255
- elsif metadata_version . providers . length == 1
291
+ elsif metadata_version . providers ( architecture ) . length == 1
256
292
# If we have only one provider in the metadata, just use that
257
293
# provider.
258
294
metadata_provider = metadata_version . provider (
259
- metadata_version . providers . first )
295
+ metadata_version . providers . first , architecture )
260
296
else
261
- providers = metadata_version . providers . sort
297
+ providers = metadata_version . providers ( architecture ) . sort
262
298
263
299
choice = 0
264
300
options = providers . map do |p |
@@ -279,7 +315,7 @@ def add_from_metadata(url, env, expanded)
279
315
end
280
316
281
317
metadata_provider = metadata_version . provider (
282
- providers [ choice -1 ] )
318
+ providers [ choice -1 ] , architecture )
283
319
end
284
320
285
321
provider_url = metadata_provider . url
@@ -293,6 +329,17 @@ def add_from_metadata(url, env, expanded)
293
329
provider_url = authed_urls [ 0 ]
294
330
end
295
331
332
+ # The architecture name used when adding the box should be
333
+ # the value extracted from the metadata provider
334
+ arch_name = metadata_provider . architecture
335
+
336
+ # In the special case where the architecture name is "unknown" and
337
+ # it is listed as the default architecture, unset the architecture
338
+ # name so it is installed without architecture information
339
+ if arch_name == "unknown" && metadata_provider . default_architecture
340
+ arch_name = nil
341
+ end
342
+
296
343
box_add (
297
344
[ [ provider_url , metadata_provider . url ] ] ,
298
345
metadata . name ,
@@ -302,6 +349,7 @@ def add_from_metadata(url, env, expanded)
302
349
env ,
303
350
checksum : metadata_provider . checksum ,
304
351
checksum_type : metadata_provider . checksum_type ,
352
+ architecture : arch_name ,
305
353
)
306
354
end
307
355
@@ -317,16 +365,21 @@ def add_from_metadata(url, env, expanded)
317
365
# @param [Hash] env
318
366
# @return [Box]
319
367
def box_add ( urls , name , version , provider , md_url , env , **opts )
368
+ display_architecture = opts [ :architecture ] == :auto ?
369
+ Util ::Platform . architecture : opts [ :architecture ]
320
370
env [ :ui ] . output ( I18n . t (
321
371
"vagrant.box_add_with_version" ,
322
372
name : name ,
323
373
version : version ,
324
- providers : Array ( provider ) . join ( ", " ) ) )
374
+ providers : [
375
+ provider ,
376
+ display_architecture ? "(#{ display_architecture } )" : nil
377
+ ] . compact . join ( " " ) ) )
325
378
326
379
# Verify the box we're adding doesn't already exist
327
380
if provider && !env [ :box_force ]
328
381
box = env [ :box_collection ] . find (
329
- name , provider , version )
382
+ name , provider , version , opts [ :architecture ] )
330
383
if box
331
384
raise Errors ::BoxAlreadyExists ,
332
385
name : name ,
@@ -377,7 +430,9 @@ def box_add(urls, name, version, provider, md_url, env, **opts)
377
430
box_url , name , version ,
378
431
force : env [ :box_force ] ,
379
432
metadata_url : md_url ,
380
- providers : provider )
433
+ providers : provider ,
434
+ architecture : opts [ :architecture ]
435
+ )
381
436
ensure
382
437
# Make sure we delete the temporary file after we add it,
383
438
# unless we were interrupted, in which case we keep it around
@@ -396,7 +451,10 @@ def box_add(urls, name, version, provider, md_url, env, **opts)
396
451
"vagrant.box_added" ,
397
452
name : box . name ,
398
453
version : box . version ,
399
- provider : box . provider ) )
454
+ provider : [
455
+ provider ,
456
+ display_architecture ? "(#{ display_architecture } )" : nil
457
+ ] . compact . join ( " " ) ) )
400
458
401
459
# Store the added box in the env for future middleware
402
460
env [ :box_added ] = box
0 commit comments