Controller Services swact/failover time reduction
Add full support for Active/Active redudancy model. 1. services could have enable dependency to services in other service groups (standby group) 2. An active/active service failure will degraded the service group it is in 3. A failure of active/active service would not prevent a swact 4. Locking a controller that is sole active/active service provider will be rejected. But lock with force option will still proceed to lock the node. 5. sm-api bind to port 7777 on mgmt interface. (was localhost:7777) Change-Id: I62fbfa8ba66a055ee7cda4f995b3a4a4e5b3fdde
This commit is contained in:
parent
a691d3f9bb
commit
80c8a52d58
|
@ -86,10 +86,12 @@ from sysinv.openstack.common import log
|
|||
from sysinv.openstack.common import uuidutils
|
||||
from sysinv.openstack.common.gettextutils import _
|
||||
from sysinv.common.storage_backend_conf import StorageBackendConfig
|
||||
from sysinv.common import health
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
KEYRING_BM_SERVICE = "BM"
|
||||
ERR_CODE_LOCK_SOLE_SERVICE_PROVIDER = "-1003"
|
||||
|
||||
|
||||
def _get_controller_address(hostname):
|
||||
|
@ -4621,6 +4623,33 @@ class HostController(rest.RestController):
|
|||
constants.CONTROLLER_1_HOSTNAME,
|
||||
constants.STORAGE_0_HOSTNAME))
|
||||
|
||||
if not force:
|
||||
# sm-lock-pre-check
|
||||
node_name = hostupdate.displayid
|
||||
response = sm_api.lock_pre_check(node_name, timeout=30)
|
||||
if response:
|
||||
error_code = response.get('error_code')
|
||||
if ERR_CODE_LOCK_SOLE_SERVICE_PROVIDER == error_code:
|
||||
impact_svc_list = response.get('impact_service_list')
|
||||
svc_list = ','.join(impact_svc_list)
|
||||
if len(impact_svc_list) > 1:
|
||||
msg = _("Services {svc_list} are only running on "
|
||||
"{host}, locking {host} will result "
|
||||
"service outage. If lock {host} is required, "
|
||||
"please use \"force lock\" command.").format(
|
||||
svc_list=svc_list, host=node_name)
|
||||
else:
|
||||
msg = _("Service {svc_list} is only running on "
|
||||
"{host}, locking {host} will result "
|
||||
"service outage. If lock {host} is required, "
|
||||
"please use \"force lock\" command.").format(
|
||||
svc_list=svc_list, host=node_name)
|
||||
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
elif "0" != error_code:
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("%s" % response['error_details']))
|
||||
|
||||
def check_unlock_controller(self, hostupdate):
|
||||
"""Pre unlock semantic checks for controller"""
|
||||
LOG.info("%s ihost check_unlock_controller" % hostupdate.displayid)
|
||||
|
@ -4988,10 +5017,20 @@ class HostController(rest.RestController):
|
|||
|
||||
if (ihost_ctr.availability ==
|
||||
constants.AVAILABILITY_DEGRADED):
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("%s has degraded availability status. "
|
||||
"Standby controller must be in available status.") %
|
||||
(ihost_ctr.hostname))
|
||||
health_helper = health.Health(pecan.request.dbapi)
|
||||
degrade_alarms = health_helper.get_alarms_degrade(
|
||||
alarm_ignore_list=[
|
||||
fm_constants.FM_ALARM_ID_HA_SERVICE_GROUP_STATE,
|
||||
fm_constants.FM_ALARM_ID_HA_SERVICE_GROUP_REDUNDANCY,
|
||||
fm_constants.FM_ALARM_ID_HA_NODE_LICENSE,
|
||||
fm_constants.FM_ALARM_ID_HA_COMMUNICATION_FAILURE
|
||||
],
|
||||
entity_instance_id_filter=ihost_ctr.hostname)
|
||||
if degrade_alarms:
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("%s has degraded availability status. "
|
||||
"Standby controller must be in available status.") %
|
||||
(ihost_ctr.hostname))
|
||||
|
||||
if constants.COMPUTE in ihost_ctr.subfunctions:
|
||||
if (ihost_ctr.subfunction_oper !=
|
||||
|
|
|
@ -4,18 +4,24 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
import json
|
||||
import socket
|
||||
from rest_api import rest_api_request
|
||||
|
||||
from sysinv.openstack.common import log
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
SM_API_HOST = socket.gethostname()
|
||||
SM_API_PORT = 7777
|
||||
SM_API_PATH = "http://{host}:{port}".\
|
||||
format(host=SM_API_HOST, port=SM_API_PORT)
|
||||
|
||||
|
||||
def swact_pre_check(hostname, timeout):
|
||||
"""
|
||||
Sends a Swact Pre-Check command to SM.
|
||||
"""
|
||||
api_cmd = "http://localhost:7777"
|
||||
api_cmd = SM_API_PATH
|
||||
api_cmd += "/v1/servicenode/%s" % hostname
|
||||
|
||||
api_cmd_headers = dict()
|
||||
|
@ -35,11 +41,35 @@ def swact_pre_check(hostname, timeout):
|
|||
return response
|
||||
|
||||
|
||||
def lock_pre_check(hostname, timeout):
|
||||
"""
|
||||
Sends a Lock Pre-Check command to SM.
|
||||
"""
|
||||
api_cmd = SM_API_PATH
|
||||
api_cmd += "/v1/servicenode/%s" % hostname
|
||||
|
||||
api_cmd_headers = dict()
|
||||
api_cmd_headers['Content-type'] = "application/json"
|
||||
api_cmd_headers['User-Agent'] = "sysinv/1.0"
|
||||
|
||||
api_cmd_payload = dict()
|
||||
api_cmd_payload['origin'] = "sysinv"
|
||||
api_cmd_payload['action'] = "lock-pre-check"
|
||||
api_cmd_payload['admin'] = "unknown"
|
||||
api_cmd_payload['oper'] = "unknown"
|
||||
api_cmd_payload['avail'] = ""
|
||||
|
||||
response = rest_api_request(None, "PATCH", api_cmd, api_cmd_headers,
|
||||
json.dumps(api_cmd_payload), timeout)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def service_list():
|
||||
"""
|
||||
Sends a service list command to SM.
|
||||
"""
|
||||
api_cmd = "http://localhost:7777"
|
||||
api_cmd = SM_API_PATH
|
||||
api_cmd += "/v1/services"
|
||||
|
||||
api_cmd_headers = dict()
|
||||
|
@ -56,7 +86,7 @@ def service_show(hostname):
|
|||
"""
|
||||
Sends a service show command to SM.
|
||||
"""
|
||||
api_cmd = "http://localhost:7777"
|
||||
api_cmd = SM_API_PATH
|
||||
api_cmd += "/v1/services/%s" % hostname
|
||||
|
||||
api_cmd_headers = dict()
|
||||
|
@ -72,7 +102,7 @@ def servicenode_list():
|
|||
"""
|
||||
Sends a service list command to SM.
|
||||
"""
|
||||
api_cmd = "http://localhost:7777"
|
||||
api_cmd = SM_API_PATH
|
||||
api_cmd += "/v1/nodes"
|
||||
|
||||
api_cmd_headers = dict()
|
||||
|
@ -89,7 +119,7 @@ def servicenode_show(hostname):
|
|||
"""
|
||||
Sends a service show command to SM.
|
||||
"""
|
||||
api_cmd = "http://localhost:7777"
|
||||
api_cmd = SM_API_PATH
|
||||
api_cmd += "/v1/nodes/%s" % hostname
|
||||
|
||||
api_cmd_headers = dict()
|
||||
|
@ -106,7 +136,7 @@ def sm_servicegroup_list():
|
|||
"""
|
||||
Sends a service list command to SM.
|
||||
"""
|
||||
api_cmd = "http://localhost:7777"
|
||||
api_cmd = SM_API_PATH
|
||||
api_cmd += "/v1/sm_sda"
|
||||
|
||||
api_cmd_headers = dict()
|
||||
|
@ -128,7 +158,7 @@ def sm_servicegroup_show(hostname):
|
|||
"""
|
||||
Sends a service show command to SM.
|
||||
"""
|
||||
api_cmd = "http://localhost:7777"
|
||||
api_cmd = SM_API_PATH
|
||||
api_cmd += "/v1/sm_sda/%s" % hostname
|
||||
|
||||
api_cmd_headers = dict()
|
||||
|
|
Loading…
Reference in New Issue