Merge changes I05dcfd9a,If938b51a,Iebd2693b
* changes: Don't go fishing in the stack for the KeyName Tidy up create timeout code Get rid of _wrap_db_error()
This commit is contained in:
commit
73492540dd
2
bin/heat
2
bin/heat
|
@ -176,7 +176,7 @@ def stack_create(options, arguments):
|
||||||
parameters['Parameters.member.%d.ParameterValue' % count] = v
|
parameters['Parameters.member.%d.ParameterValue' % count] = v
|
||||||
count = count + 1
|
count = count + 1
|
||||||
|
|
||||||
parameters['Timeout'] = options.timeout
|
parameters['TimeoutInMinutes'] = options.timeout
|
||||||
|
|
||||||
if options.template_file:
|
if options.template_file:
|
||||||
parameters['TemplateBody'] = open(options.template_file).read()
|
parameters['TemplateBody'] = open(options.template_file).read()
|
||||||
|
|
|
@ -152,9 +152,6 @@ class StackController(object):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
msg = _("The Template must be a JSON document.")
|
msg = _("The Template must be a JSON document.")
|
||||||
return webob.exc.HTTPBadRequest(explanation=msg)
|
return webob.exc.HTTPBadRequest(explanation=msg)
|
||||||
stack['StackName'] = req.params['StackName']
|
|
||||||
if 'Timeout' in req.params:
|
|
||||||
stack['Timeout'] = req.params['Timeout']
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = rpc.call(con, 'engine',
|
res = rpc.call(con, 'engine',
|
||||||
|
|
|
@ -16,6 +16,6 @@
|
||||||
SUPPORTED_PARAMS = ('StackName', 'TemplateBody', 'TemplateUrl',
|
SUPPORTED_PARAMS = ('StackName', 'TemplateBody', 'TemplateUrl',
|
||||||
'NotificationARNs', 'Parameters', 'Version',
|
'NotificationARNs', 'Parameters', 'Version',
|
||||||
'SignatureVersion', 'Timestamp', 'AWSAccessKeyId',
|
'SignatureVersion', 'Timestamp', 'AWSAccessKeyId',
|
||||||
'Signature', 'KeyStoneCreds', 'Timeout',
|
'Signature', 'KeyStoneCreds', 'TimeoutInMinutes',
|
||||||
'LogicalResourceId', 'PhysicalResourceId', 'NextToken',
|
'LogicalResourceId', 'PhysicalResourceId', 'NextToken',
|
||||||
)
|
)
|
||||||
|
|
|
@ -27,30 +27,6 @@ _ENGINE = None
|
||||||
_MAKER = None
|
_MAKER = None
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DBError(Error):
|
|
||||||
"""Wraps an implementation specific exception."""
|
|
||||||
def __init__(self, inner_exception=None):
|
|
||||||
self.inner_exception = inner_exception
|
|
||||||
super(DBError, self).__init__(str(inner_exception))
|
|
||||||
|
|
||||||
|
|
||||||
def _wrap_db_error(f):
|
|
||||||
def _wrap(*args, **kwargs):
|
|
||||||
try:
|
|
||||||
return f(*args, **kwargs)
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
raise InvalidUnicodeParameter()
|
|
||||||
except Exception, e:
|
|
||||||
logger.exception(_('DB exception wrapped.'))
|
|
||||||
raise DBError(e)
|
|
||||||
_wrap.func_name = f.func_name
|
|
||||||
return _wrap
|
|
||||||
|
|
||||||
|
|
||||||
def get_session(autocommit=True, expire_on_commit=False):
|
def get_session(autocommit=True, expire_on_commit=False):
|
||||||
"""Return a SQLAlchemy session."""
|
"""Return a SQLAlchemy session."""
|
||||||
global _ENGINE, _MAKER
|
global _ENGINE, _MAKER
|
||||||
|
@ -58,10 +34,7 @@ def get_session(autocommit=True, expire_on_commit=False):
|
||||||
if _MAKER is None or _ENGINE is None:
|
if _MAKER is None or _ENGINE is None:
|
||||||
_ENGINE = get_engine()
|
_ENGINE = get_engine()
|
||||||
_MAKER = get_maker(_ENGINE, autocommit, expire_on_commit)
|
_MAKER = get_maker(_ENGINE, autocommit, expire_on_commit)
|
||||||
session = _MAKER()
|
return _MAKER()
|
||||||
session.query = _wrap_db_error(session.query)
|
|
||||||
session.flush = _wrap_db_error(session.flush)
|
|
||||||
return session
|
|
||||||
|
|
||||||
|
|
||||||
class SynchronousSwitchListener(sqlalchemy.interfaces.PoolListener):
|
class SynchronousSwitchListener(sqlalchemy.interfaces.PoolListener):
|
||||||
|
|
|
@ -241,17 +241,20 @@ class Instance(Resource):
|
||||||
res = Resource.validate(self)
|
res = Resource.validate(self)
|
||||||
if res:
|
if res:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
#check validity of key
|
#check validity of key
|
||||||
if self.stack.parms['KeyName']:
|
try:
|
||||||
|
key_name = self.properties['KeyName']
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
else:
|
||||||
keypairs = self.nova().keypairs.list()
|
keypairs = self.nova().keypairs.list()
|
||||||
valid_key = False
|
valid_key = False
|
||||||
for k in keypairs:
|
for k in keypairs:
|
||||||
if k.name == self.stack.parms['KeyName']:
|
if k.name == key_name:
|
||||||
valid_key = True
|
return
|
||||||
if not valid_key:
|
return {'Error':
|
||||||
return {'Error':
|
'Provided KeyName is not registered with nova'}
|
||||||
'Provided KeyName is not registered with nova'}
|
|
||||||
return None
|
|
||||||
|
|
||||||
def handle_delete(self):
|
def handle_delete(self):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -63,6 +63,18 @@ def _extract_user_params(params):
|
||||||
return dict(get_param_pairs())
|
return dict(get_param_pairs())
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_args(params):
|
||||||
|
kwargs = {}
|
||||||
|
try:
|
||||||
|
timeout_mins = int(params.get('TimeoutInMinutes', 0))
|
||||||
|
except ValueError:
|
||||||
|
logger.exception('create timeout conversion')
|
||||||
|
else:
|
||||||
|
if timeout > 0:
|
||||||
|
kwargs['timeout_in_minutes'] = timeout_mins
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
class EngineManager(manager.Manager):
|
class EngineManager(manager.Manager):
|
||||||
"""
|
"""
|
||||||
Manages the running instances from creation to destruction.
|
Manages the running instances from creation to destruction.
|
||||||
|
@ -129,9 +141,8 @@ class EngineManager(manager.Manager):
|
||||||
mem['LastUpdatedTimestamp'] = heat_utils.strtime(s.updated_at)
|
mem['LastUpdatedTimestamp'] = heat_utils.strtime(s.updated_at)
|
||||||
mem['NotificationARNs'] = 'TODO'
|
mem['NotificationARNs'] = 'TODO'
|
||||||
mem['Parameters'] = ps.t['Parameters']
|
mem['Parameters'] = ps.t['Parameters']
|
||||||
mem['TimeoutInMinutes'] = ps.t.get('Timeout', '60')
|
|
||||||
mem['Description'] = ps.t.get('Description',
|
mem['Description'] = ps.t.get('Description',
|
||||||
'No description')
|
'No description')
|
||||||
mem['StackStatus'] = s.status
|
mem['StackStatus'] = s.status
|
||||||
mem['StackStatusReason'] = s.status_reason
|
mem['StackStatusReason'] = s.status_reason
|
||||||
|
|
||||||
|
@ -201,7 +212,8 @@ class EngineManager(manager.Manager):
|
||||||
new_pt = db_api.parsed_template_create(None, pt)
|
new_pt = db_api.parsed_template_create(None, pt)
|
||||||
|
|
||||||
stack.parsed_template_id = new_pt.id
|
stack.parsed_template_id = new_pt.id
|
||||||
greenpool.spawn_n(stack.create)
|
|
||||||
|
greenpool.spawn_n(stack.create, **_extract_args(params))
|
||||||
|
|
||||||
return {'StackId': "/".join([new_s.name, str(new_s.id)])}
|
return {'StackId': "/".join([new_s.name, str(new_s.id)])}
|
||||||
|
|
||||||
|
|
|
@ -191,28 +191,20 @@ class Stack(object):
|
||||||
stack.update_and_save({'status': new_status,
|
stack.update_and_save({'status': new_status,
|
||||||
'status_reason': reason})
|
'status_reason': reason})
|
||||||
|
|
||||||
def _timeout(self):
|
def create(self, timeout_in_minutes=60):
|
||||||
'''Return the stack creation timeout in seconds'''
|
|
||||||
if 'Timeout' in self.t:
|
|
||||||
try:
|
|
||||||
# Timeout is in minutes
|
|
||||||
return int(self.t['Timeout']) * 60
|
|
||||||
except ValueError:
|
|
||||||
logger.exception('create timeout conversion')
|
|
||||||
|
|
||||||
# Default to 1 hour
|
|
||||||
return 60 * 60
|
|
||||||
|
|
||||||
def create(self):
|
|
||||||
'''
|
'''
|
||||||
Create the stack and all of the resources.
|
Create the stack and all of the resources.
|
||||||
|
|
||||||
|
Creation will fail if it exceeds the specified timeout. The default is
|
||||||
|
60 minutes.
|
||||||
'''
|
'''
|
||||||
self.state_set(self.IN_PROGRESS, 'Stack creation started')
|
self.state_set(self.IN_PROGRESS, 'Stack creation started')
|
||||||
|
|
||||||
stack_status = self.CREATE_COMPLETE
|
stack_status = self.CREATE_COMPLETE
|
||||||
reason = 'Stack successfully created'
|
reason = 'Stack successfully created'
|
||||||
|
res = None
|
||||||
|
|
||||||
with eventlet.Timeout(self._timeout()) as tmo:
|
with eventlet.Timeout(timeout_in_minutes * 60) as tmo:
|
||||||
try:
|
try:
|
||||||
for res in self:
|
for res in self:
|
||||||
if stack_status != self.CREATE_FAILED:
|
if stack_status != self.CREATE_FAILED:
|
||||||
|
@ -231,10 +223,10 @@ class Stack(object):
|
||||||
res.state_set(res.CREATE_FAILED,
|
res.state_set(res.CREATE_FAILED,
|
||||||
'Stack creation aborted')
|
'Stack creation aborted')
|
||||||
|
|
||||||
except eventlet.Timeout, t:
|
except eventlet.Timeout as t:
|
||||||
if t is tmo:
|
if t is tmo:
|
||||||
stack_status = self.CREATE_FAILED
|
stack_status = self.CREATE_FAILED
|
||||||
reason = 'Timed out waiting for %s' % (res.name)
|
reason = 'Timed out waiting for %s' % str(res)
|
||||||
else:
|
else:
|
||||||
# not my timeout
|
# not my timeout
|
||||||
raise
|
raise
|
||||||
|
|
|
@ -71,7 +71,7 @@ test_template_ref = '''
|
||||||
"Properties": {
|
"Properties": {
|
||||||
"ImageId": "image_name",
|
"ImageId": "image_name",
|
||||||
"InstanceType": "m1.large",
|
"InstanceType": "m1.large",
|
||||||
"KeyName": "test_KeyName"
|
"KeyName": { "Ref" : "KeyName" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DataVolume" : {
|
"DataVolume" : {
|
||||||
|
@ -112,7 +112,7 @@ test_template_findinmap_valid = '''
|
||||||
"Properties": {
|
"Properties": {
|
||||||
"ImageId": "image_name",
|
"ImageId": "image_name",
|
||||||
"InstanceType": "m1.large",
|
"InstanceType": "m1.large",
|
||||||
"KeyName": "test_KeyName"
|
"KeyName": { "Ref" : "KeyName" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DataVolume" : {
|
"DataVolume" : {
|
||||||
|
@ -176,7 +176,7 @@ test_template_findinmap_invalid = '''
|
||||||
'"InstanceType" }, "Arch" ] } ] },' + \
|
'"InstanceType" }, "Arch" ] } ] },' + \
|
||||||
'''
|
'''
|
||||||
"InstanceType": "m1.large",
|
"InstanceType": "m1.large",
|
||||||
"KeyName": "test_KeyName"
|
"KeyName": { "Ref" : "KeyName"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DataVolume" : {
|
"DataVolume" : {
|
||||||
|
|
Loading…
Reference in New Issue