Remerge common code with glance.

Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
Angus Salkeld 2012-03-16 12:08:53 +11:00
parent 3fad43a5e2
commit a5fbf17743
7 changed files with 59 additions and 26 deletions

View File

@ -22,9 +22,6 @@ return
import logging import logging
import re import re
import routes
from heat.api import v1
from heat.api import versions from heat.api import versions
from heat.common import wsgi from heat.common import wsgi

View File

@ -22,8 +22,6 @@ import json
import webob.dec import webob.dec
from heat.common import wsgi
class Controller(object): class Controller(object):

View File

@ -127,10 +127,23 @@ class SendFileIterator:
return self.len return self.len
while self.sending: while self.sending:
sent = sendfile.sendfile(self.connection.sock.fileno(), try:
self.body.fileno(), sent = sendfile.sendfile(self.connection.sock.fileno(),
self.offset, self.body.fileno(),
CHUNKSIZE) self.offset,
CHUNKSIZE)
except OSError as e:
# suprisingly, sendfile may fail transiently instead of
# blocking, in which case we select on the socket in order
# to wait on its return to a writeable state before resuming
# the send loop
if e.errno in (errno.EAGAIN, errno.EBUSY):
wlist = [self.connection.sock.fileno()]
rfds, wfds, efds = select.select([], wlist, [])
if wfds:
continue
raise
self.sending = (sent != 0) self.sending = (sent != 0)
self.offset += sent self.offset += sent
yield OfLength(sent) yield OfLength(sent)
@ -224,19 +237,19 @@ class BaseClient(object):
key. key.
If use_ssl is True, and this param is None (the If use_ssl is True, and this param is None (the
default), then an environ variable default), then an environ variable
heat_CLIENT_KEY_FILE is looked for. If no such HEAT_CLIENT_KEY_FILE is looked for. If no such
environ variable is found, ClientConnectionError environ variable is found, ClientConnectionError
will be raised. will be raised.
:param cert_file: Optional PEM-formatted certificate chain file. :param cert_file: Optional PEM-formatted certificate chain file.
If use_ssl is True, and this param is None (the If use_ssl is True, and this param is None (the
default), then an environ variable default), then an environ variable
heat_CLIENT_CERT_FILE is looked for. If no such HEAT_CLIENT_CERT_FILE is looked for. If no such
environ variable is found, ClientConnectionError environ variable is found, ClientConnectionError
will be raised. will be raised.
:param ca_file: Optional CA cert file to use in SSL connections :param ca_file: Optional CA cert file to use in SSL connections
If use_ssl is True, and this param is None (the If use_ssl is True, and this param is None (the
default), then an environ variable default), then an environ variable
heat_CLIENT_CA_FILE is looked for. HEAT_CLIENT_CA_FILE is looked for.
:param insecure: Optional. If set then the server's certificate :param insecure: Optional. If set then the server's certificate
will not be verified. will not be verified.
""" """
@ -263,11 +276,11 @@ class BaseClient(object):
connect_kwargs = {} connect_kwargs = {}
if self.use_ssl: if self.use_ssl:
if self.key_file is None: if self.key_file is None:
self.key_file = os.environ.get('heat_CLIENT_KEY_FILE') self.key_file = os.environ.get('HEAT_CLIENT_KEY_FILE')
if self.cert_file is None: if self.cert_file is None:
self.cert_file = os.environ.get('heat_CLIENT_CERT_FILE') self.cert_file = os.environ.get('HEAT_CLIENT_CERT_FILE')
if self.ca_file is None: if self.ca_file is None:
self.ca_file = os.environ.get('heat_CLIENT_CA_FILE') self.ca_file = os.environ.get('HEAT_CLIENT_CA_FILE')
# Check that key_file/cert_file are either both set or both unset # Check that key_file/cert_file are either both set or both unset
if self.cert_file is not None and self.key_file is None: if self.cert_file is not None and self.key_file is None:
@ -275,7 +288,7 @@ class BaseClient(object):
"and you have supplied a cert, " "and you have supplied a cert, "
"however you have failed to supply either a " "however you have failed to supply either a "
"key_file parameter or set the " "key_file parameter or set the "
"heat_CLIENT_KEY_FILE environ variable") "HEAT_CLIENT_KEY_FILE environ variable")
raise exception.ClientConnectionError(msg) raise exception.ClientConnectionError(msg)
if self.key_file is not None and self.cert_file is None: if self.key_file is not None and self.cert_file is None:
@ -283,7 +296,7 @@ class BaseClient(object):
"and you have supplied a key, " "and you have supplied a key, "
"however you have failed to supply either a " "however you have failed to supply either a "
"cert_file parameter or set the " "cert_file parameter or set the "
"heat_CLIENT_CERT_FILE environ variable") "HEAT_CLIENT_CERT_FILE environ variable")
raise exception.ClientConnectionError(msg) raise exception.ClientConnectionError(msg)
if (self.key_file is not None and if (self.key_file is not None and
@ -506,6 +519,10 @@ class BaseClient(object):
raise TypeError('Unsupported image type: %s' % body.__class__) raise TypeError('Unsupported image type: %s' % body.__class__)
res = c.getresponse() res = c.getresponse()
def _retry(res):
return res.getheader('Retry-After')
status_code = self.get_status_code(res) status_code = self.get_status_code(res)
if status_code in self.OK_RESPONSE_CODES: if status_code in self.OK_RESPONSE_CODES:
return res return res
@ -523,8 +540,13 @@ class BaseClient(object):
raise exception.Invalid(res.read()) raise exception.Invalid(res.read())
elif status_code == httplib.MULTIPLE_CHOICES: elif status_code == httplib.MULTIPLE_CHOICES:
raise exception.MultipleChoices(body=res.read()) raise exception.MultipleChoices(body=res.read())
elif status_code == httplib.REQUEST_ENTITY_TOO_LARGE:
raise exception.LimitExceeded(retry=_retry(res),
body=res.read())
elif status_code == httplib.INTERNAL_SERVER_ERROR: elif status_code == httplib.INTERNAL_SERVER_ERROR:
raise Exception("Internal Server error: %s" % res.read()) raise Exception("Internal Server error: %s" % res.read())
elif status_code == httplib.SERVICE_UNAVAILABLE:
raise exception.ServiceUnavailable(retry=_retry(res))
elif status_code == httplib.REQUEST_URI_TOO_LONG: elif status_code == httplib.REQUEST_URI_TOO_LONG:
raise exception.RequestUriTooLong(body=res.read()) raise exception.RequestUriTooLong(body=res.read())
else: else:

View File

@ -168,8 +168,6 @@ def load_paste_app(conf, app_name=None):
# Setup logging early # Setup logging early
setup_logging(conf) setup_logging(conf)
logger = logging.getLogger(app_name)
app = wsgi.paste_deploy_app(conf_file, app_name, conf) app = wsgi.paste_deploy_app(conf_file, app_name, conf)
# Log the options used when starting if we're in debug mode... # Log the options used when starting if we're in debug mode...

View File

@ -19,8 +19,6 @@ Routines for URL-safe encrypting/decrypting
""" """
import base64 import base64
import string
import os
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto import Random from Crypto import Random

View File

@ -141,6 +141,27 @@ class MultipleChoices(HeatException):
"means that you have not included a version indicator in a " "means that you have not included a version indicator in a "
"request URI.\n\nThe body of response returned:\n%(body)s") "request URI.\n\nThe body of response returned:\n%(body)s")
class LimitExceeded(HeatException):
message = _("The request returned a 413 Request Entity Too Large. This "
"generally means that rate limiting or a quota threshold was "
"breached.\n\nThe response body:\n%(body)s")
def __init__(self, *args, **kwargs):
self.retry_after = (int(kwargs['retry']) if kwargs.get('retry')
else None)
super(LimitExceeded, self).__init__(*args, **kwargs)
class ServiceUnavailable(HeatException):
message = _("The request returned a 503 ServiceUnavilable. This "
"generally occurs on service overload or other transient "
"outage.")
def __init__(self, *args, **kwargs):
self.retry_after = (int(kwargs['retry']) if kwargs.get('retry')
else None)
super(ServiceUnavailable, self).__init__(*args, **kwargs)
class RequestUriTooLong(HeatException): class RequestUriTooLong(HeatException):
message = _("The URI was too long.") message = _("The URI was too long.")

View File

@ -22,13 +22,10 @@ System-level utilities and helper functions.
import datetime import datetime
import errno import errno
import inspect
import logging import logging
import os import os
import platform import platform
import random
import subprocess import subprocess
import socket
import sys import sys
import uuid import uuid
@ -327,9 +324,11 @@ def get_terminal_size():
if not height_width: if not height_width:
try: try:
p = subprocess.Popen(['stty', 'size'], p = subprocess.Popen(['stty', 'size'],
shell=false, shell=False,
stdout=subprocess.PIPE) stdout=subprocess.PIPE)
return tuple(int(x) for x in p.communicate()[0].split()) result = p.communicate()
if p.returncode == 0:
return tuple(int(x) for x in result[0].split())
except: except:
pass pass