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:
Al Bailey 2019-06-06 11:56:45 -05:00
parent d89438f86a
commit 6c3afad3e7
8 changed files with 2 additions and 755 deletions

View File

@ -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']

View File

@ -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])

View File

@ -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

View File

@ -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()

View File

@ -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>
"""

View File

@ -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

View File

@ -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