Merge "Directly copy a file URL from glance."
This commit is contained in:
commit
a4d608fa33
@ -22,6 +22,7 @@ from __future__ import absolute_import
|
||||
import copy
|
||||
import itertools
|
||||
import random
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
import urlparse
|
||||
@ -58,7 +59,12 @@ glance_opts = [
|
||||
cfg.IntOpt('glance_num_retries',
|
||||
default=0,
|
||||
help='Number retries when downloading an image from glance'),
|
||||
]
|
||||
cfg.ListOpt('allowed_direct_url_schemes',
|
||||
default=[],
|
||||
help='A list of url scheme that can be downloaded directly '
|
||||
'via the direct_url. Currently supported schemes: '
|
||||
'[file].'),
|
||||
]
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
@ -254,6 +260,18 @@ class GlanceImageService(object):
|
||||
|
||||
def download(self, context, image_id, data):
|
||||
"""Calls out to Glance for metadata and data and writes data."""
|
||||
if 'file' in CONF.allowed_direct_url_schemes:
|
||||
location = self.get_location(context, image_id)
|
||||
o = urlparse.urlparse(location)
|
||||
if o.scheme == "file":
|
||||
with open(o.path, "r") as f:
|
||||
# FIXME(jbresnah) a system call to cp could have
|
||||
# significant performance advantages, however we
|
||||
# do not have the path to files at this point in
|
||||
# the abstraction.
|
||||
shutil.copyfileobj(f, data)
|
||||
return
|
||||
|
||||
try:
|
||||
image_chunks = self._client.call(context, 1, 'data', image_id)
|
||||
except Exception:
|
||||
|
@ -17,7 +17,10 @@
|
||||
|
||||
|
||||
import datetime
|
||||
import filecmp
|
||||
import os
|
||||
import random
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
import glanceclient.exc
|
||||
@ -468,6 +471,40 @@ class TestGlanceImageService(test.TestCase):
|
||||
self.flags(glance_num_retries=1)
|
||||
service.download(self.context, image_id, writer)
|
||||
|
||||
def test_download_file_url(self):
|
||||
class MyGlanceStubClient(glance_stubs.StubGlanceClient):
|
||||
"""A client that returns a file url."""
|
||||
|
||||
(outfd, s_tmpfname) = tempfile.mkstemp(prefix='directURLsrc')
|
||||
outf = os.fdopen(outfd, 'w')
|
||||
inf = open('/dev/urandom', 'r')
|
||||
for i in range(10):
|
||||
_data = inf.read(1024)
|
||||
outf.write(_data)
|
||||
outf.close()
|
||||
|
||||
def get(self, image_id):
|
||||
return type('GlanceTestDirectUrlMeta', (object,),
|
||||
{'direct_url': 'file://%s' + self.s_tmpfname})
|
||||
|
||||
client = MyGlanceStubClient()
|
||||
(outfd, tmpfname) = tempfile.mkstemp(prefix='directURLdst')
|
||||
writer = os.fdopen(outfd, 'w')
|
||||
|
||||
service = self._create_image_service(client)
|
||||
image_id = 1 # doesn't matter
|
||||
|
||||
self.flags(allowed_direct_url_schemes=['file'])
|
||||
service.download(self.context, image_id, writer)
|
||||
writer.close()
|
||||
|
||||
# compare the two files
|
||||
rc = filecmp.cmp(tmpfname, client.s_tmpfname)
|
||||
self.assertTrue(rc, "The file %s and %s should be the same" %
|
||||
(tmpfname, client.s_tmpfname))
|
||||
os.remove(client.s_tmpfname)
|
||||
os.remove(tmpfname)
|
||||
|
||||
def test_client_forbidden_converts_to_imagenotauthed(self):
|
||||
class MyGlanceStubClient(glance_stubs.StubGlanceClient):
|
||||
"""A client that raises a Forbidden exception."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user