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 copy
|
||||||
import itertools
|
import itertools
|
||||||
import random
|
import random
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import urlparse
|
import urlparse
|
||||||
@ -58,7 +59,12 @@ glance_opts = [
|
|||||||
cfg.IntOpt('glance_num_retries',
|
cfg.IntOpt('glance_num_retries',
|
||||||
default=0,
|
default=0,
|
||||||
help='Number retries when downloading an image from glance'),
|
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__)
|
LOG = logging.getLogger(__name__)
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@ -254,6 +260,18 @@ class GlanceImageService(object):
|
|||||||
|
|
||||||
def download(self, context, image_id, data):
|
def download(self, context, image_id, data):
|
||||||
"""Calls out to Glance for metadata and data and writes 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:
|
try:
|
||||||
image_chunks = self._client.call(context, 1, 'data', image_id)
|
image_chunks = self._client.call(context, 1, 'data', image_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -17,7 +17,10 @@
|
|||||||
|
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import filecmp
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import glanceclient.exc
|
import glanceclient.exc
|
||||||
@ -468,6 +471,40 @@ class TestGlanceImageService(test.TestCase):
|
|||||||
self.flags(glance_num_retries=1)
|
self.flags(glance_num_retries=1)
|
||||||
service.download(self.context, image_id, writer)
|
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):
|
def test_client_forbidden_converts_to_imagenotauthed(self):
|
||||||
class MyGlanceStubClient(glance_stubs.StubGlanceClient):
|
class MyGlanceStubClient(glance_stubs.StubGlanceClient):
|
||||||
"""A client that raises a Forbidden exception."""
|
"""A client that raises a Forbidden exception."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user