Merge "Fix GET /v1/maintenance/{session}/{project}"

This commit is contained in:
Zuul 2018-10-03 04:17:41 +00:00 committed by Gerrit Code Review
commit 2a5fe75ddf
3 changed files with 63 additions and 33 deletions

View File

@ -135,7 +135,7 @@ class EngineEndpoint(object):
return None
LOG.info("EngineEndpoint: project_get_session")
instance_ids = (self.workflow_sessions[session_id].session_data.
instance_ids_by_project(project_id))
state_instance_ids(project_id))
return {'instance_ids': instance_ids}
def project_update_session(self, ctx, session_id, project_id, data):

View File

@ -46,11 +46,13 @@ class Project(object):
def __init__(self, name):
self.name = name
self.state = None
self.state_instances = []
class SessionData(object):
def __init__(self, data):
def __init__(self, data, session_id):
self.session_id = session_id
self.projects = []
self.hosts = data['hosts']
self.maintenance_at = str(data['maintenance_at'])
@ -68,7 +70,7 @@ class SessionData(object):
def add_instance(self, project, instance_id, instance_name, host,
ha=False):
if host not in self.hosts:
LOG.error('%s: instance %s in invalid host ' %
LOG.error('%s: instance %s in invalid host %s' %
(self.session_id, instance_id, host))
if project not in self.project_names():
self.projects.append(Project(project))
@ -85,6 +87,40 @@ class SessionData(object):
def set_projets_state(self, state):
for project in self.projects:
project.state = state
project.state_instances = []
def project_has_state_instances(self, name):
project = self.project(name)
if project.state_instances:
return True
else:
return False
def set_projects_state_and_host_instances(self, state, host):
some_project_has_instances = False
for project in self.projects:
project.state = state
project.state_instances = (
self.instance_ids_by_host_and_project(host, project.name))
if project.state_instances:
some_project_has_instances = True
project.state = state
else:
project.state = None
if not some_project_has_instances:
LOG.error('%s: No project has instances on host %s' %
(self.session_id, host))
def get_projects_with_state(self):
return ([project for project in self.projects if project.state
is not None])
def state_instance_ids(self, name):
instances = ([project.state_instances for project in self.projects if
project.name == name][0])
if not instances:
instances = self.instance_ids_by_project(name)
return instances
def instances_by_project(self, project):
return [instance for instance in self.instances if
@ -94,10 +130,15 @@ class SessionData(object):
return [instance.instance_id for instance in self.instances if
instance.project == project]
def instance_ids_by_host_and_project(self, host, project):
return [instance.instance_id for instance in self.instances
if instance.host == host and
instance.project == project]
def instances_by_host_and_project(self, host, project):
return [instance for instance in self.instances
if instance.host == host
and instance.project == project]
if instance.host == host and
instance.project == project]
def instance_action_by_project_reply(self, project, instance_id):
return self.proj_instance_actions[project][instance_id]
@ -125,7 +166,7 @@ class BaseWorkflow(Thread):
self.thg = threadgroup.ThreadGroup()
self.timer = {}
self.state = 'MAINTENANCE'
self.session_data = SessionData(data)
self.session_data = SessionData(data, session_id)
self.states_methods = {'MAINTENANCE': 'maintenance',
'SCALE_IN': 'scale_in',
'PREPARE_MAINTENANCE': 'prepare_maintenance',

View File

@ -181,15 +181,10 @@ class Workflow(BaseWorkflow):
self.notif_admin.info({'some': 'context'}, 'maintenance.host', payload)
def projects_answer(self, state, projects=None):
def projects_answer(self, state, projects):
state_ack = 'ACK_%s' % state
state_nack = 'NACK_%s' % state
if projects:
state_projects = ([p for p in self.session_data.projects if
p.name in projects])
else:
state_projects = self.session_data.projects
for project in state_projects:
for project in projects:
pstate = project.state
if pstate == state:
break
@ -205,9 +200,13 @@ class Workflow(BaseWorkflow):
break
return pstate
def wait_projects_state(self, state, timer_name, projects=None):
def wait_projects_state(self, state, timer_name):
state_ack = 'ACK_%s' % state
state_nack = 'NACK_%s' % state
projects = self.session_data.get_projects_with_state()
if not projects:
LOG.error('%s: wait_projects_state %s. Emtpy project list' %
(self.session_id, state))
while not self.is_timer_expired(timer_name):
answer = self.projects_answer(state, projects)
if answer == state:
@ -263,7 +262,7 @@ class Workflow(BaseWorkflow):
metadata = self.session_data.metadata
self._project_notify(project, instance_ids, allowed_actions,
actions_at, reply_at, state, metadata)
self.start_timer(self.conf.project_maintenance_reply,
self.start_timer(self.conf.project_scale_in_reply,
'SCALE_IN_TIMEOUT')
return self.wait_projects_state(state, 'SCALE_IN_TIMEOUT')
@ -350,24 +349,16 @@ class Workflow(BaseWorkflow):
# if instances on this host fits to other hosts
return host_to_be_empty
def confirm_host_to_be_emptied(self, host, statebase):
state = statebase
def confirm_host_to_be_emptied(self, host, state):
allowed_actions = ['MIGRATE', 'LIVE_MIGRATE', 'OWN_ACTION']
actions_at = self.reply_time_str(self.conf.project_maintenance_reply)
reply_at = actions_at
self.session_data.set_projets_state(statebase)
projects = []
self.session_data.set_projects_state_and_host_instances(state, host)
for project in self.session_data.project_names():
instances = (
self.session_data.instances_by_host_and_project(host, project))
if not instances:
if not self.session_data.project_has_state_instances(project):
continue
projects.append(project)
LOG.info('%s to project %s' % (state, project))
info = "Instances\n"
for instance in instances:
info += ('%s\n' % instance)
LOG.info(info)
instance_ids = '%s/v1/maintenance/%s/%s' % (self.url,
self.session_id,
project)
@ -375,9 +366,8 @@ class Workflow(BaseWorkflow):
self._project_notify(project, instance_ids, allowed_actions,
actions_at, reply_at, state, metadata)
self.start_timer(self.conf.project_maintenance_reply,
'%s_TIMEOUT' % statebase)
return self.wait_projects_state(state, '%s_TIMEOUT' % statebase,
projects)
'%s_TIMEOUT' % state)
return self.wait_projects_state(state, '%s_TIMEOUT' % state)
def confirm_maintenance_complete(self):
state = 'MAINTENANCE_COMPLETE'
@ -534,7 +524,7 @@ class Workflow(BaseWorkflow):
(self.session_id))
self.state = 'PREPARE_MAINTENANCE'
else:
LOG.info('Empty host found %')
LOG.info('Empty host found')
self.state = 'START_MAINTENANCE'
maint_at = self.str_to_datetime(
@ -572,9 +562,8 @@ class Workflow(BaseWorkflow):
(self.session_id))
self.state = 'PREPARE_MAINTENANCE'
else:
LOG.info('Empty host found %')
LOG.info('Empty host found')
self.state = 'START_MAINTENANCE'
self.update_server_info()
def prepare_maintenance(self):
LOG.info("%s: prepare_maintenance called" % self.session_id)