I was able to pin down the image upload problem today:
The Store.add file input read loop using chunkreadable throws an error on the
very last read. Apparently the mod_wsgi.Input behaves differently than its
eventlet counterpart in that it throws an error if the requested data length is
greater than what is avalible. When I replaced the chunkreadable for loop with
a while loop that modified the size of the last data read request, it works.
Does anyone know if this is a code bug or rather a WSGI configuration setting
that I missed?
Regards,
Mark
---
I made the following chages to file
/usr/lib/python2.7/dist-packages/glance/store/filesystem.py:
def add(self, image_id, image_file, image_size):
Stores an image file with supplied identifier to the backend
storage system and returns a tuple containing information
about the stored image.
:param image_id: The opaque image identifier
:param image_file: The image data to write, as a file-like object
:param image_size: The size of the image data to write, in bytes
:retval tuple of URL in backing store, bytes written, and checksum
:raises `glance.common.exception.Duplicate` if the image already
existed
:note By default, the backend writes the image data to a file
`/DATADIR/ID`, where DATADIR is the value of
the filesystem_store_datadir configuration option and ID
is the supplied image ID.
filepath = os.path.join(self.datadir, str(image_id))
if os.path.exists(filepath):
raise exception.Duplicate(_(Image file %s already exists!)
% filepath)
checksum = hashlib.md5()
bytes_written = 0
bytes_to_read = ChunkedFile.CHUNKSIZE
try:
with open(filepath, 'wb') as f:
while bytes_written image_size:
if (image_size - bytes_written) ChunkedFile.CHUNKSIZE:
bytes_to_read = image_size - bytes_written
buf = image_file.read(bytes_to_read)
bytes_written += len(buf)
checksum.update(buf)
f.write(buf)
for buf in utils.chunkreadable(image_file,
ChunkedFile.CHUNKSIZE):
bytes_written += len(buf)
checksum.update(buf)
f.write(buf)
except IOError as e:
if e.errno != errno.EACCES:
self._delete_partial(filepath, image_id)
exceptions = {errno.EFBIG: exception.StorageFull(),
errno.ENOSPC: exception.StorageFull(),
errno.EACCES: exception.StorageWriteDenied()}
raise exceptions.get(e.errno, e)
From: Miller, Mark M (EB SW Cloud - RD - Corvallis)
Sent: Tuesday, December 17, 2013 12:32 AM
To: OpenStack Development Mailing List (not for usage questions)
Subject: [openstack-dev] Glance mod_wsgi.input Question
Hello,
I am trying to get the Grizzly Glance service working with Apache2 through the
WSGI interface. I am having problems with the _upload method of file
glance/api/v1/images.py It appears that the req.body_file pointer is invalid
as I get the following error: (9, 'Bad file descriptor').
I have tried adding inline test code attempting to read the image_data object
but have been unsuccessful. The req.content_length = None. Has anyone come
across this issue? Below are a few variable values as well as the req.environ:
scheme = file
image size = 8
image data = mod_wsgi.Input object at 0x7f5fb08931f0
-
key=HTTP_X_TENANT_NAME, value=u'AdminProject'
key=routes.route, value=routes.route.Route object at 0x7f5fb181fc90
key=webob.is_body_readable, value=True
key=mod_wsgi.listener_port, value='9292'
key=HTTP_X_PROJECT_NAME, value=u'AdminProject'
key=SERVER_SOFTWARE, value='Apache'
key=content-length, value=8
key=SCRIPT_NAME, value='/v1/v1'
key=HTTP_TRANSFER_ENCODING, value='chunked'
key=mod_wsgi.handler_script, value=''
key=SERVER_SIGNATURE, value='addressApache Server at 10.1.184.1 Port
9292/address\n'
key=REQUEST_METHOD, value='POST'
key=PATH_INFO, value='/images'
key=SERVER_PROTOCOL, value='HTTP/1.1'
key=QUERY_STRING, value=''
key=Content_Length, value=8
key=HTTP_X_USER_ID, value=u'0dd0361fe85a43deb456dd47ed55c2e2'
key=HTTP_X_IMAGE_META_MIN_RAM, value='0'
key=HTTP_X_AUTH_TOKEN, value='de169f1045f8d306a750d28e8e33172e'
key=HTTP_USER_AGENT, value='python-glanceclient'
key=HTTP_X_DOMAIN_NAME, value=None
key=SERVER_NAME, value='10.1.184.1'
key=REMOTE_ADDR, value='10.1.184.1'
key=HTTP_X_ROLE, value=u'admin'
key=mod_wsgi.request_handler, value='wsgi-script'
key=HTTP_X_IDENTITY_STATUS, value='Confirmed'
key=wsgi.url_scheme, value='https'
key=SERVER_ADMIN, value='[no address given]'
key=CONTENT_LENGTH,