Add a Timeout (-t) to the heat options (and make -f for templates).
This makes the cli more consistent with AWS and implements the timeout feature. Note: the timeout is in minutes and defaults to 60 minutes. Change-Id: I41dea75170c871c1ee47948643311752d9d5e41e Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
parent
7e02a65f79
commit
aca71be770
7
bin/heat
7
bin/heat
@ -137,6 +137,8 @@ def stack_create(options, arguments):
|
||||
parameters['Parameters.member.%d.ParameterValue' % count] = v
|
||||
count = count + 1
|
||||
|
||||
parameters['Timeout'] = options.timeout
|
||||
|
||||
if options.template_file:
|
||||
parameters['TemplateBody'] = open(options.template_file).read()
|
||||
elif options.template_url:
|
||||
@ -367,8 +369,11 @@ def create_options(parser):
|
||||
|
||||
parser.add_option('-u', '--template-url', metavar="template_url",
|
||||
default=None, help="URL of template. Default: None")
|
||||
parser.add_option('-t', '--template-file', metavar="template_file",
|
||||
parser.add_option('-f', '--template-file', metavar="template_file",
|
||||
default=None, help="Path to the template. Default: None")
|
||||
parser.add_option('-t', '--timeout', metavar="timeout",
|
||||
default='60',
|
||||
help='Stack creation timeout in minutes. Default: 60')
|
||||
|
||||
parser.add_option('-P', '--parameters', metavar="parameters", default=None,
|
||||
help="Parameter values used to create the stack.")
|
||||
|
@ -34,7 +34,7 @@ heat command\&.
|
||||
.RE
|
||||
.SH "OPTIONS"
|
||||
.PP
|
||||
\fB\-t\fR, \fB\-\-template\fR
|
||||
\fB\-f\fR, \fB\-\-template\fR
|
||||
.RS 4
|
||||
The template to use set up a stack\&.
|
||||
.RE
|
||||
|
@ -138,6 +138,8 @@ class StackController(object):
|
||||
msg = _("The Template must be a JSON document.")
|
||||
return webob.exc.HTTPBadRequest(explanation=msg)
|
||||
stack['StackName'] = req.params['StackName']
|
||||
if 'Timeout' in req.params:
|
||||
stack['Timeout'] = req.params['Timeout']
|
||||
|
||||
try:
|
||||
return rpc.call(con, 'engine',
|
||||
|
@ -16,4 +16,4 @@
|
||||
SUPPORTED_PARAMS = ('StackName', 'TemplateBody', 'TemplateUrl',
|
||||
'NotificationARNs', 'Parameters', 'Version',
|
||||
'SignatureVersion', 'Timestamp', 'AWSAccessKeyId',
|
||||
'Signature', 'KeyStoneCreds')
|
||||
'Signature', 'KeyStoneCreds', 'Timeout')
|
||||
|
@ -115,11 +115,12 @@ class EngineManager(manager.Manager):
|
||||
mem['updated_at'] = str(s.updated_at)
|
||||
mem['NotificationARNs'] = 'TODO'
|
||||
mem['Parameters'] = ps.t['Parameters']
|
||||
mem['StackStatusReason'] = 'TODO'
|
||||
mem['TimeoutInMinutes'] = 'TODO'
|
||||
mem['TimeoutInMinutes'] = ps.t.get('Timeout', '60')
|
||||
mem['TemplateDescription'] = ps.t.get('Description',
|
||||
'No description')
|
||||
mem['StackStatus'] = ps.t.get('stack_status', 'unknown')
|
||||
mem['StackStatusReason'] = ps.t.get('stack_status_reason',
|
||||
'State changed')
|
||||
|
||||
# only show the outputs on a completely created stack
|
||||
if ps.t['stack_status'] == ps.CREATE_COMPLETE:
|
||||
|
@ -40,6 +40,7 @@ class Stack(object):
|
||||
self.t = template
|
||||
self.maps = self.t.get('Mappings', {})
|
||||
self.outputs = self.t.get('Outputs', {})
|
||||
self.timeout = self.t.get('Timeout', None)
|
||||
self.res = {}
|
||||
self.doc = None
|
||||
self.name = stack_name
|
||||
@ -174,6 +175,7 @@ class Stack(object):
|
||||
def status_set(self, new_status, reason='change in resource state'):
|
||||
|
||||
self.t['stack_status'] = new_status
|
||||
self.t['stack_status_reason'] = reason
|
||||
self.update_parsed_template()
|
||||
|
||||
def create_blocking(self):
|
||||
@ -181,17 +183,30 @@ class Stack(object):
|
||||
create all the resources in the order specified by get_create_order
|
||||
'''
|
||||
order = self.get_create_order()
|
||||
failed = False
|
||||
self.status_set(self.IN_PROGRESS)
|
||||
self.status_set(self.IN_PROGRESS, 'Stack creation started')
|
||||
|
||||
stack_status = self.CREATE_COMPLETE
|
||||
reason = 'Stack successfully created'
|
||||
|
||||
# Timeout is in minutes (default to 1 hour)
|
||||
secs_tmo = 60 * 60
|
||||
if self.timeout:
|
||||
try:
|
||||
secs_tmo = int(self.timeout) * 60
|
||||
except ValueError as ve:
|
||||
logger.exception('create timeout conversion')
|
||||
tmo = eventlet.Timeout(secs_tmo)
|
||||
try:
|
||||
for r in order:
|
||||
res = self.resources[r]
|
||||
if not failed:
|
||||
if stack_status != self.CREATE_FAILED:
|
||||
try:
|
||||
res.create()
|
||||
except Exception as ex:
|
||||
logger.exception('create')
|
||||
failed = True
|
||||
stack_status = self.CREATE_FAILED
|
||||
reason = 'resource %s failed with: %s' % (res.name,
|
||||
str(ex))
|
||||
res.state_set(res.CREATE_FAILED, str(ex))
|
||||
|
||||
try:
|
||||
@ -202,7 +217,17 @@ class Stack(object):
|
||||
else:
|
||||
res.state_set(res.CREATE_FAILED)
|
||||
|
||||
self.status_set(failed and self.CREATE_FAILED or self.CREATE_COMPLETE)
|
||||
except eventlet.Timeout, t:
|
||||
if t is not tmo:
|
||||
# not my timeout
|
||||
raise
|
||||
else:
|
||||
stack_status = self.CREATE_FAILED
|
||||
reason = 'Timed out waiting for %s' % (res.name)
|
||||
finally:
|
||||
tmo.cancel()
|
||||
|
||||
self.status_set(stack_status, reason)
|
||||
|
||||
def create(self):
|
||||
|
||||
@ -222,9 +247,17 @@ class Stack(object):
|
||||
res = self.resources[r]
|
||||
try:
|
||||
res.delete()
|
||||
except Exception as ex:
|
||||
failed = True
|
||||
res.state_set(res.DELETE_FAILED)
|
||||
logger.error('delete: %s' % str(ex))
|
||||
try:
|
||||
re = db_api.resource_get(self.context, self.resources[r].id)
|
||||
re.delete()
|
||||
except Exception as ex:
|
||||
# don't fail the delete if the db entry has
|
||||
# not been created yet.
|
||||
if 'not found' not in str(ex):
|
||||
failed = True
|
||||
res.state_set(res.DELETE_FAILED)
|
||||
logger.error('delete: %s' % str(ex))
|
||||
|
Loading…
Reference in New Issue
Block a user