Remove references to pacemaker from sysinv
Sysinv use of pacemaker was replaced by SM a long time ago and the code that referenced it is being removed. Change-Id: Ic2a55698f64757bffeb9b53f4a105ea6ccb3dd2f Story: 2004764 Task: 30665 Signed-off-by: Al Bailey <Al.Bailey@windriver.com>
This commit is contained in:
parent
d89438f86a
commit
6c3afad3e7
@ -23,7 +23,7 @@ class sysinv::agent (
|
||||
|
||||
include sysinv::params
|
||||
|
||||
# Pacemaker should be starting up agent
|
||||
# SM should be starting up agent
|
||||
Sysinv_config<||> ~> Service['sysinv-agent']
|
||||
Sysinv_api_paste_ini<||> ~> Service['sysinv-agent']
|
||||
|
||||
|
@ -1,138 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2014 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
"""
|
||||
Cluster Services
|
||||
"""
|
||||
|
||||
import sys
|
||||
from sysinv.cluster import cluster_xml as xml
|
||||
import logging
|
||||
|
||||
from lxml import etree
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
SERVICE_ACTIVITY_NOT_SET = ''
|
||||
SERVICE_ACTIVITY_UNKNOWN = 'unknown'
|
||||
SERVICE_ACTIVITY_ACTIVE = 'active'
|
||||
SERVICE_ACTIVITY_STANDBY = 'standby'
|
||||
|
||||
SERVICE_STATE_NOT_SET = ''
|
||||
SERVICE_STATE_UNKNOWN = 'unknown'
|
||||
SERVICE_STATE_ENABLED = 'enabled'
|
||||
SERVICE_STATE_DISABLED = 'disabled'
|
||||
SERVICE_STATE_FAILED = 'failed'
|
||||
|
||||
|
||||
class ClusterServiceInstance(object):
|
||||
""" Cluster Service Instance information about the service running
|
||||
on a particular host in the cluster (state and activity)
|
||||
"""
|
||||
|
||||
def __init__(self, name, host_name):
|
||||
self.name = name
|
||||
self.host_name = host_name
|
||||
self.activity = SERVICE_ACTIVITY_NOT_SET
|
||||
self.state = SERVICE_STATE_NOT_SET
|
||||
self.reason = []
|
||||
|
||||
|
||||
class ClusterService(object):
|
||||
""" Cluster Service contains information about the service running
|
||||
in the cluster (overall service state and service instances state)
|
||||
"""
|
||||
|
||||
def __init__(self, service_name):
|
||||
self.name = service_name
|
||||
self.state = SERVICE_STATE_NOT_SET
|
||||
self.instances = []
|
||||
self.activity_follows = []
|
||||
self.resources = []
|
||||
self.migration_timeout = 0
|
||||
|
||||
|
||||
class ClusterServices(object):
|
||||
""" Cluster Services holds a listing of all services running
|
||||
in the cluster
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.list = []
|
||||
self.__cluster_data = ""
|
||||
self.__loaded = False
|
||||
|
||||
def load(self, host_names):
|
||||
""" Load services
|
||||
"""
|
||||
|
||||
if self.__loaded:
|
||||
if self.__cluster_data == xml.CLUSTER_DATA:
|
||||
return
|
||||
|
||||
self.__cluster_data = ""
|
||||
self.__loaded = False
|
||||
self.list[:] = []
|
||||
|
||||
try:
|
||||
xmlroot = etree.fromstring(xml.CLUSTER_DATA)
|
||||
|
||||
if not etree.iselement(xmlroot):
|
||||
return
|
||||
|
||||
if len(xmlroot) == 0:
|
||||
return
|
||||
|
||||
xmlservices = xmlroot.find(".//services")
|
||||
if not etree.iselement(xmlservices):
|
||||
return
|
||||
|
||||
for xmlservice in xmlservices.iterchildren():
|
||||
|
||||
service = ClusterService(xmlservice.attrib["id"])
|
||||
|
||||
# Hosts that the service runs on
|
||||
for host_name in host_names:
|
||||
instance = ClusterServiceInstance(xmlservice.attrib["id"],
|
||||
host_name)
|
||||
service.instances.append(instance)
|
||||
|
||||
# Get migration attributes of a service
|
||||
xmlmigration = xmlroot.find(".//services/service[@id='%s']/"
|
||||
"migration"
|
||||
% xmlservice.attrib["id"])
|
||||
if not etree.iselement(xmlmigration):
|
||||
return
|
||||
|
||||
service.migration_timeout = xmlmigration.attrib["timeout"]
|
||||
|
||||
# Get resources that determine activity of service
|
||||
xmlactivity = xmlroot.find(".//services/service[@id='%s']/"
|
||||
"activity"
|
||||
% xmlservice.attrib["id"])
|
||||
if not etree.iselement(xmlactivity):
|
||||
return
|
||||
|
||||
for xmlresource in xmlactivity.iterchildren():
|
||||
service.activity_follows.append(xmlresource.attrib["id"])
|
||||
|
||||
# Get resources that make up service
|
||||
xmlresources = xmlroot.find(".//services/service[@id='%s']/"
|
||||
"resources"
|
||||
% xmlservice.attrib["id"])
|
||||
if not etree.iselement(xmlresources):
|
||||
return
|
||||
|
||||
for xmlresource in xmlresources.iterchildren():
|
||||
service.resources.append(xmlresource.attrib["id"])
|
||||
|
||||
self.list.append(service)
|
||||
|
||||
self.__cluster_data = xml.CLUSTER_DATA
|
||||
self.__loaded = True
|
||||
|
||||
except Exception:
|
||||
LOG.error("error:", sys.exc_info()[0])
|
@ -1,294 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2014 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
"""
|
||||
Cluster Services API
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from sysinv.cluster import pacemaker as crm
|
||||
from sysinv.cluster import cluster_services as cluster
|
||||
import logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CLUSTER_NODE_STATE_ONLINE = "online"
|
||||
CLUSTER_NODE_STATE_OFFLINE = "offline"
|
||||
|
||||
|
||||
def __set_service_overall_state__(service):
|
||||
""" Internal function used to set the overall state of a
|
||||
service based on the state of the service instances.
|
||||
"""
|
||||
|
||||
service.state = cluster.SERVICE_STATE_DISABLED
|
||||
|
||||
for instance in service.instances:
|
||||
if instance.activity == cluster.SERVICE_ACTIVITY_ACTIVE:
|
||||
service.state = cluster.SERVICE_STATE_ENABLED
|
||||
|
||||
|
||||
def __set_service_instance_state__(instance, resource_name, crm_resource):
|
||||
""" Internal function used to set the state of a service
|
||||
instance based on a cluster resource manager resource.
|
||||
"""
|
||||
|
||||
if crm_resource is None:
|
||||
if (instance.state != cluster.SERVICE_STATE_DISABLED and
|
||||
instance.state != cluster.SERVICE_STATE_FAILED):
|
||||
instance.state = cluster.SERVICE_STATE_UNKNOWN
|
||||
instance.reason.append("%s is unknown" % resource_name)
|
||||
return
|
||||
|
||||
if crm_resource.state == crm.RESOURCE_STATE_UNKNOWN:
|
||||
if (instance.state != cluster.SERVICE_STATE_DISABLED and
|
||||
instance.state != cluster.SERVICE_STATE_FAILED):
|
||||
instance.state = cluster.SERVICE_STATE_UNKNOWN
|
||||
instance.reason.append("%s is unknown" % crm_resource.name)
|
||||
|
||||
elif crm_resource.state == crm.RESOURCE_STATE_ENABLED:
|
||||
if instance.state == cluster.SERVICE_STATE_NOT_SET:
|
||||
instance.state = cluster.SERVICE_STATE_ENABLED
|
||||
instance.reason.append("")
|
||||
|
||||
elif crm_resource.state == crm.RESOURCE_STATE_DISABLED:
|
||||
if instance.state != cluster.SERVICE_STATE_FAILED:
|
||||
instance.state = cluster.SERVICE_STATE_DISABLED
|
||||
instance.reason.append("%s is disabled" % crm_resource.name)
|
||||
|
||||
elif crm_resource.state == crm.RESOURCE_STATE_FAILED:
|
||||
instance.state = cluster.SERVICE_STATE_FAILED
|
||||
instance.reason.append("%s is failed" % crm_resource.name)
|
||||
|
||||
else:
|
||||
if (instance.state != cluster.SERVICE_STATE_DISABLED and
|
||||
instance.state != cluster.SERVICE_STATE_FAILED):
|
||||
instance.state = cluster.SERVICE_STATE_UNKNOWN
|
||||
instance.reason.append("%s unknown state" % crm_resource.name)
|
||||
|
||||
# Remove any empty strings from reason if the state is not enabled.
|
||||
if instance.state != cluster.SERVICE_STATE_ENABLED:
|
||||
instance.reason = [_f for _f in instance.reason if _f]
|
||||
|
||||
|
||||
def __set_service_instance_activity__(instance, crm_resource):
|
||||
""" Internal function used to set the activity of a service
|
||||
instance based on a cluster resource manager resource.
|
||||
"""
|
||||
|
||||
if crm_resource is None:
|
||||
instance.activity = cluster.SERVICE_ACTIVITY_STANDBY
|
||||
return
|
||||
|
||||
if crm_resource.state == crm.RESOURCE_STATE_ENABLED:
|
||||
if instance.activity == cluster.SERVICE_ACTIVITY_NOT_SET:
|
||||
instance.activity = cluster.SERVICE_ACTIVITY_ACTIVE
|
||||
|
||||
else:
|
||||
instance.activity = cluster.SERVICE_ACTIVITY_STANDBY
|
||||
|
||||
|
||||
def _get_cluster_controller_services(host_names):
|
||||
""" Internal function used to fetches the state of nodes and
|
||||
resources from the cluster resource manager and calculate
|
||||
the state of the services making up the cluster.
|
||||
|
||||
returns: services
|
||||
"""
|
||||
|
||||
services = cluster.ClusterServices()
|
||||
manager = crm.Pacemaker()
|
||||
|
||||
services.load(host_names)
|
||||
manager.load()
|
||||
|
||||
for service in services.list:
|
||||
for instance in service.instances:
|
||||
crm_node = manager.get_node(instance.host_name)
|
||||
|
||||
if crm_node is None:
|
||||
instance.activity = cluster.SERVICE_ACTIVITY_STANDBY
|
||||
instance.state = cluster.SERVICE_STATE_DISABLED
|
||||
instance.reason.append("%s is unavailable"
|
||||
% instance.host_name)
|
||||
else:
|
||||
if crm_node.state == crm.NODE_STATE_OFFLINE:
|
||||
instance.activity = cluster.SERVICE_ACTIVITY_STANDBY
|
||||
instance.state = cluster.SERVICE_STATE_DISABLED
|
||||
instance.reason.append("%s is offline"
|
||||
% instance.host_name)
|
||||
|
||||
elif crm_node.state == crm.NODE_STATE_ONLINE:
|
||||
for resource_name in service.activity_follows:
|
||||
crm_resource = manager.get_resource(instance.host_name,
|
||||
resource_name)
|
||||
__set_service_instance_activity__(instance,
|
||||
crm_resource)
|
||||
|
||||
for resource_name in service.resources:
|
||||
crm_resource = manager.get_resource(instance.host_name,
|
||||
resource_name)
|
||||
__set_service_instance_state__(instance, resource_name,
|
||||
crm_resource)
|
||||
|
||||
if instance.state != cluster.SERVICE_STATE_ENABLED:
|
||||
instance.activity = cluster.SERVICE_ACTIVITY_STANDBY
|
||||
|
||||
# Remap standby disabled service instance to standby
|
||||
# enabled for now. Needed to make the presentation
|
||||
# better for cold-standby.
|
||||
if instance.activity == cluster.SERVICE_ACTIVITY_STANDBY:
|
||||
if instance.state == cluster.SERVICE_STATE_DISABLED:
|
||||
instance.state = cluster.SERVICE_STATE_ENABLED
|
||||
|
||||
__set_service_overall_state__(service)
|
||||
|
||||
return services
|
||||
|
||||
|
||||
def get_cluster_controller_services(host_names, print_to_screen=False,
|
||||
print_json_str=False):
|
||||
""" Fetches the state of nodes and resources from the cluster
|
||||
resource manager and calculate the state of the services
|
||||
making up the cluster.
|
||||
|
||||
returns: json string
|
||||
"""
|
||||
|
||||
services = _get_cluster_controller_services(host_names)
|
||||
|
||||
# Build Json Data
|
||||
services_data = []
|
||||
|
||||
for service in services.list:
|
||||
if print_to_screen:
|
||||
print(" ")
|
||||
print("servicename: %s" % service.name)
|
||||
print("status : %s" % service.state)
|
||||
|
||||
instances_data = []
|
||||
|
||||
for instance in service.instances:
|
||||
if print_to_screen:
|
||||
print("\thostname: %s" % instance.host_name)
|
||||
print("\tactivity: %s" % instance.activity)
|
||||
print("\tstate : %s" % instance.state)
|
||||
print("\treason : %s" % instance.reason)
|
||||
print(" ")
|
||||
|
||||
instances_data += ([{'hostname': instance.host_name,
|
||||
'activity': instance.activity,
|
||||
'state': instance.state,
|
||||
'reason': instance.reason}])
|
||||
|
||||
services_data += ([{'servicename': service.name,
|
||||
'state': service.state,
|
||||
'instances': instances_data}])
|
||||
|
||||
if print_json_str:
|
||||
print(json.dumps(services_data))
|
||||
|
||||
return json.dumps(services_data)
|
||||
|
||||
|
||||
def cluster_controller_node_exists(host_name):
|
||||
""" Cluster node exists.
|
||||
|
||||
returns: True exists, otherwise False
|
||||
"""
|
||||
|
||||
manager = crm.Pacemaker()
|
||||
manager.load()
|
||||
|
||||
crm_node = manager.get_node(host_name)
|
||||
|
||||
return crm_node is not None
|
||||
|
||||
|
||||
def get_cluster_controller_node_state(host_name, print_to_screen=False,
|
||||
print_json_str=False):
|
||||
""" Fetches the state of a cluster node.
|
||||
|
||||
returns: json string
|
||||
"""
|
||||
|
||||
manager = crm.Pacemaker()
|
||||
manager.load()
|
||||
|
||||
crm_node = manager.get_node(host_name)
|
||||
|
||||
if crm_node is None:
|
||||
state = "unknown"
|
||||
else:
|
||||
if crm_node.state == crm.NODE_STATE_OFFLINE:
|
||||
state = "offline"
|
||||
elif crm_node.state == crm.NODE_STATE_ONLINE:
|
||||
state = "online"
|
||||
else:
|
||||
state = "unknown"
|
||||
|
||||
if print_to_screen:
|
||||
print(" ")
|
||||
print("%s state is %s" % (host_name, state))
|
||||
|
||||
# Build Json Data
|
||||
node_data = ({'hostname': host_name, 'state': state})
|
||||
|
||||
if print_json_str:
|
||||
print(json.dumps(node_data))
|
||||
|
||||
return json.dumps(node_data)
|
||||
|
||||
|
||||
def set_cluster_controller_node_state(host_name, state):
|
||||
""" Set the state of a cluster node
|
||||
|
||||
returns: True success, otherwise False
|
||||
"""
|
||||
|
||||
if state == CLUSTER_NODE_STATE_OFFLINE:
|
||||
node_state = crm.NODE_STATE_OFFLINE
|
||||
elif state == CLUSTER_NODE_STATE_ONLINE:
|
||||
node_state = crm.NODE_STATE_ONLINE
|
||||
else:
|
||||
LOG.warning("Unsupported state (%s) given for %s."
|
||||
% (state, host_name))
|
||||
return False
|
||||
|
||||
manager = crm.Pacemaker()
|
||||
|
||||
return manager.set_node_state(host_name, node_state)
|
||||
|
||||
|
||||
def have_active_cluster_controller_services(host_name):
|
||||
""" Determine if there are any active services on the given host.
|
||||
|
||||
returns: True success, otherwise False
|
||||
"""
|
||||
|
||||
services = _get_cluster_controller_services([host_name])
|
||||
for service in services.list:
|
||||
for instance in service.instances:
|
||||
if instance.activity == cluster.SERVICE_ACTIVITY_ACTIVE:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def migrate_cluster_controller_services(host_name):
|
||||
""" Migrates all services to a particular host.
|
||||
|
||||
returns: True success, otherwise False
|
||||
"""
|
||||
|
||||
manager = crm.Pacemaker()
|
||||
|
||||
services = _get_cluster_controller_services(host_name)
|
||||
for service in services.list:
|
||||
for resource_name in service.activity_follows:
|
||||
manager.migrate_resource_to_node(resource_name, host_name,
|
||||
service.migration_timeout)
|
||||
return True
|
@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2014 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
"""
|
||||
Cluster Services Watch
|
||||
"""
|
||||
|
||||
import sysinv.cluster.cluster_services_api as cluster_services_api
|
||||
|
||||
|
||||
def main():
|
||||
host_names = ["controller-0", "controller-1"]
|
||||
|
||||
cluster_services_api.get_cluster_controller_services(host_names, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,76 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2014-2016 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
"""
|
||||
Cluster XML
|
||||
"""
|
||||
|
||||
CLUSTER_DATA = """
|
||||
<cluster-mappings>
|
||||
<services>
|
||||
<service id="Cloud Services">
|
||||
<migration timeout="120"/>
|
||||
<activity>
|
||||
<follows id="management_ip"/>
|
||||
</activity>
|
||||
<resources>
|
||||
<resource id="keystone"/>
|
||||
<resource id="glance-reg"/>
|
||||
<resource id="glance-api"/>
|
||||
<resource id="neutron-svr"/>
|
||||
<resource id="nova-api"/>
|
||||
<resource id="nova-sched"/>
|
||||
<resource id="nova-conductor"/>
|
||||
<resource id="nova-conauth"/>
|
||||
<resource id="nova-novnc"/>
|
||||
<resource id="cinder-api"/>
|
||||
<resource id="cinder-schedule"/>
|
||||
<resource id="cinder-volume"/>
|
||||
<resource id="ceilometer-agent-central"/>
|
||||
<resource id="ceilometer-collector"/>
|
||||
<resource id="ceilometer-api"/>
|
||||
<resource id="ceilometer-alarm-evaluator"/>
|
||||
<resource id="ceilometer-alarm-notifier"/>
|
||||
</resources>
|
||||
</service>
|
||||
<service id="Platform Services">
|
||||
<migration timeout="120"/>
|
||||
<activity>
|
||||
<follows id="management_ip"/>
|
||||
</activity>
|
||||
<resources>
|
||||
<resource id="sysinv-inv"/>
|
||||
<resource id="sysinv-conductor"/>
|
||||
<resource id="mtcAgent"/>
|
||||
<resource id="hbsAgent"/>
|
||||
<resource id="dnsmasq"/>
|
||||
<resource id="platform_fs"/>
|
||||
<resource id="p_export_platform_fs"/>
|
||||
</resources>
|
||||
</service>
|
||||
<service id="Messaging Services">
|
||||
<migration timeout="120"/>
|
||||
<activity>
|
||||
<follows id="management_ip"/>
|
||||
</activity>
|
||||
<resources>
|
||||
<resource id="rabbit_fs"/>
|
||||
<resource id="rabbit_ocf"/>
|
||||
</resources>
|
||||
</service>
|
||||
<service id="Database Services">
|
||||
<migration timeout="120"/>
|
||||
<activity>
|
||||
<follows id="management_ip"/>
|
||||
</activity>
|
||||
<resources>
|
||||
<resource id="pg_fs"/>
|
||||
<resource id="pg_ocf"/>
|
||||
</resources>
|
||||
</service>
|
||||
</services>
|
||||
</cluster-mappings>
|
||||
"""
|
@ -1,222 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2014 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
"""
|
||||
PaceMaker
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
import logging
|
||||
from lxml import etree
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
NODE_STATE_NOT_SET = ''
|
||||
NODE_STATE_OFFLINE = 'offline'
|
||||
NODE_STATE_ONLINE = 'online'
|
||||
|
||||
RESOURCE_STATE_NOT_SET = ''
|
||||
RESOURCE_STATE_UNKNOWN = 'unknown'
|
||||
RESOURCE_STATE_ENABLED = 'enabled'
|
||||
RESOURCE_STATE_DISABLED = 'disabled'
|
||||
RESOURCE_STATE_FAILED = 'failed'
|
||||
|
||||
|
||||
class PaceMakerNode(object):
|
||||
""" Pacemaker Node information about a node making up the cluster
|
||||
"""
|
||||
|
||||
def __init__(self, node_name):
|
||||
self.name = node_name
|
||||
self.state = NODE_STATE_NOT_SET
|
||||
|
||||
|
||||
class PaceMakerResource(object):
|
||||
""" Pacemaker Resource information on a resource running on a node
|
||||
in the cluster
|
||||
"""
|
||||
|
||||
def __init__(self, node_name, resource_name):
|
||||
self.name = resource_name
|
||||
self.node_name = node_name
|
||||
self.last_operation = ""
|
||||
self.state = RESOURCE_STATE_NOT_SET
|
||||
|
||||
|
||||
class Pacemaker(object):
|
||||
""" Pacemaker
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._xmldoc = None
|
||||
|
||||
def load(self):
|
||||
""" Ask for the latest information on the cluster
|
||||
"""
|
||||
|
||||
pacemaker_xml_filename = ('/tmp/pacemaker_%s.xml'
|
||||
% str(uuid.uuid4()))
|
||||
|
||||
try:
|
||||
if not os.path.exists('/usr/sbin/cibadmin'):
|
||||
return
|
||||
|
||||
os.system("/usr/sbin/cibadmin --query > %s"
|
||||
% pacemaker_xml_filename)
|
||||
|
||||
if not os.path.exists(pacemaker_xml_filename):
|
||||
return
|
||||
|
||||
self._xmldoc = etree.parse(pacemaker_xml_filename)
|
||||
if self._xmldoc is None:
|
||||
os.remove(pacemaker_xml_filename)
|
||||
return
|
||||
|
||||
if not etree.iselement(self._xmldoc.getroot()):
|
||||
self._xmldoc = None
|
||||
os.remove(pacemaker_xml_filename)
|
||||
return
|
||||
|
||||
if len(self._xmldoc.getroot()) == 0:
|
||||
self._xmldoc = None
|
||||
os.remove(pacemaker_xml_filename)
|
||||
return
|
||||
|
||||
os.remove(pacemaker_xml_filename)
|
||||
|
||||
except Exception:
|
||||
if os.path.exists(pacemaker_xml_filename):
|
||||
os.remove(pacemaker_xml_filename)
|
||||
|
||||
LOG.error("error:", sys.exc_info()[0])
|
||||
|
||||
def get_resource(self, node_name, resource_name):
|
||||
""" Get a resource's information and state
|
||||
"""
|
||||
|
||||
if self._xmldoc is None:
|
||||
return None
|
||||
|
||||
xmlroot = self._xmldoc.getroot()
|
||||
|
||||
xmlresource = xmlroot.find(".//status/node_state[@id='%s']/"
|
||||
"lrm[@id='%s']/lrm_resources/"
|
||||
"lrm_resource[@id='%s']/lrm_rsc_op"
|
||||
% (node_name, node_name, resource_name))
|
||||
if not etree.iselement(xmlresource):
|
||||
return None
|
||||
|
||||
resource = PaceMakerResource(node_name, resource_name)
|
||||
|
||||
resource.last_operation = xmlresource.attrib["operation"]
|
||||
|
||||
if (xmlresource.attrib["operation"] == "start" or
|
||||
xmlresource.attrib["operation"] == "promote"):
|
||||
if xmlresource.attrib["rc-code"] == "0":
|
||||
resource.state = RESOURCE_STATE_ENABLED
|
||||
else:
|
||||
resource.state = RESOURCE_STATE_FAILED
|
||||
|
||||
elif (xmlresource.attrib["operation"] == "stop" or
|
||||
xmlresource.attrib["operation"] == "demote"):
|
||||
if xmlresource.attrib["rc-code"] == "0":
|
||||
resource.state = RESOURCE_STATE_DISABLED
|
||||
else:
|
||||
resource.state = RESOURCE_STATE_FAILED
|
||||
|
||||
elif xmlresource.attrib["operation"] == "monitor":
|
||||
if xmlresource.attrib["rc-code"] == "0":
|
||||
resource.state = RESOURCE_STATE_ENABLED
|
||||
elif xmlresource.attrib["rc-code"] == "7":
|
||||
resource.state = RESOURCE_STATE_DISABLED
|
||||
else:
|
||||
resource.state = RESOURCE_STATE_FAILED
|
||||
else:
|
||||
resource.state = RESOURCE_STATE_UNKNOWN
|
||||
|
||||
return resource
|
||||
|
||||
def get_node(self, node_name):
|
||||
""" Get a node's information and state
|
||||
"""
|
||||
|
||||
if self._xmldoc is None:
|
||||
return None
|
||||
|
||||
node = PaceMakerNode(node_name)
|
||||
|
||||
xmlroot = self._xmldoc.getroot()
|
||||
|
||||
# Check the static configuration for state.
|
||||
xmlnode = xmlroot.find((".//nodes/node[@id='%s']"
|
||||
"/instance_attributes[@id='nodes-%s']"
|
||||
"/nvpair[@id='nodes-%s-standby']"
|
||||
% (node_name, node_name, node_name)))
|
||||
if etree.iselement(xmlnode):
|
||||
if xmlnode.attrib["name"] == "standby":
|
||||
if xmlnode.attrib["value"] == "on":
|
||||
node.state = NODE_STATE_OFFLINE
|
||||
return node
|
||||
|
||||
# Now check the running status for state.
|
||||
xmlnode = xmlroot.find(".//status/node_state[@id='%s']"
|
||||
% node_name)
|
||||
if not etree.iselement(xmlnode):
|
||||
return None
|
||||
|
||||
if xmlnode.attrib["in_ccm"] == "true":
|
||||
if xmlnode.attrib["crmd"] == "online":
|
||||
node.state = NODE_STATE_ONLINE
|
||||
else:
|
||||
node.state = NODE_STATE_OFFLINE
|
||||
else:
|
||||
node.state = NODE_STATE_OFFLINE
|
||||
|
||||
return node
|
||||
|
||||
def set_node_state(self, node_name, node_state):
|
||||
""" Set the state of a node in the cluster
|
||||
"""
|
||||
|
||||
try:
|
||||
if not os.path.exists('/usr/sbin/crm'):
|
||||
return False
|
||||
|
||||
if node_state == NODE_STATE_OFFLINE:
|
||||
action = "standby"
|
||||
elif node_state == NODE_STATE_ONLINE:
|
||||
action = "online"
|
||||
else:
|
||||
LOG.warning("Unsupported state (%s) requested for %s."
|
||||
% (node_state, node_name))
|
||||
return False
|
||||
|
||||
os.system("/usr/sbin/crm node %s %s" % (action, node_name))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
LOG.error("error:", sys.exc_info()[0])
|
||||
return False
|
||||
|
||||
def migrate_resource_to_node(self, resource_name, node_name, lifetime):
|
||||
""" Migrate resource to a node in the cluster.
|
||||
"""
|
||||
|
||||
try:
|
||||
if not os.path.exists('/usr/sbin/crm'):
|
||||
return False
|
||||
|
||||
# Lifetime follows the duration format specified in ISO_8601
|
||||
os.system("/usr/sbin/crm resource migrate %s %s P%sS"
|
||||
% (resource_name, node_name, lifetime))
|
||||
return True
|
||||
|
||||
except Exception:
|
||||
os.system("/usr/sbin/crm resource unmigrate %s" % resource_name)
|
||||
LOG.error("error:", sys.exc_info()[0])
|
||||
return False
|
@ -85,8 +85,7 @@ deps = -r{toxinidir}/test-requirements.txt
|
||||
commands =
|
||||
flake8 {posargs} . \
|
||||
sysinv/cmd/manage-partitions \
|
||||
sysinv/cmd/query_pci_id \
|
||||
sysinv/cluster/cluster_services_dump
|
||||
sysinv/cmd/query_pci_id
|
||||
|
||||
[testenv:py27]
|
||||
basepython = python2.7
|
||||
|
Loading…
Reference in New Issue
Block a user