Merge "Directly copy a file URL from glance."

This commit is contained in:
Jenkins 2013-01-21 23:05:19 +00:00 committed by Gerrit Code Review
commit a4d608fa33
2 changed files with 56 additions and 1 deletions

View File

@ -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:

View File

@ -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."""