6a5e10492c
This decouples the build and packaging of guest-server, guest-agent from mtce, by splitting guest component into stx-nfv repo. This leaves existing C++ code, scripts, and resource files untouched, so there is no functional change. Code refactoring is beyond the scope of this update. Makefiles were modified to include devel headers directories /usr/include/mtce-common and /usr/include/mtce-daemon. This ensures there is no contamination with other system headers. The cgts-mtce-common package is renamed and split into: - repo stx-metal: mtce-common, mtce-common-dev - repo stx-metal: mtce - repo stx-nfv: mtce-guest - repo stx-ha: updates package dependencies to mtce-pmon for service-mgmt, sm, and sm-api mtce-common: - contains common and daemon shared source utility code mtce-common-dev: - based on mtce-common, contains devel package required to build mtce-guest and mtce - contains common library archives and headers mtce: - contains components: alarm, fsmon, fsync, heartbeat, hostw, hwmon, maintenance, mtclog, pmon, public, rmon mtce-guest: - contains guest component guest-server, guest-agent Story: 2002829 Task: 22748 Change-Id: I9c7a9b846fd69fd566b31aa3f12a043c08f19f1f Signed-off-by: Jim Gauld <james.gauld@windriver.com>
385 lines
13 KiB
C++
385 lines
13 KiB
C++
/*
|
|
* Copyright (c) 2013, 2015 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* Wind River CGTS Platform Controller Maintenance
|
|
* Access to Service Manager via REST API Interface.
|
|
*
|
|
*/
|
|
|
|
#ifdef __AREA__
|
|
#undef __AREA__
|
|
#endif
|
|
#define __AREA__ "mgr"
|
|
|
|
#include "nodeClass.h" /* for ... maintenance class nodeLinkClass */
|
|
#include "mtcSmgrApi.h" /* for ... this module header */
|
|
#include "jsonUtil.h" /* for ... jsonUtil_get_key_val */
|
|
|
|
/*******************************************/
|
|
/* Internal Private utilities and handlers */
|
|
/*******************************************/
|
|
|
|
/* The handles the inventory PATCH request's response message */
|
|
void nodeLinkClass::mtcSmgrApi_handler ( struct evhttp_request *req, void *arg )
|
|
{
|
|
if ( ! req )
|
|
{
|
|
elog ("%s %s %s Request Timeout (%d)\n",
|
|
smgrEvent.hostname.c_str(),
|
|
smgrEvent.service.c_str(),
|
|
smgrEvent.operation.c_str(),
|
|
smgrEvent.timeout);
|
|
|
|
smgrEvent.status = FAIL_TIMEOUT ;
|
|
goto mtcSmgrApi_handler_out ;
|
|
}
|
|
|
|
mtcHttpUtil_status ( smgrEvent );
|
|
if ( smgrEvent.status != PASS )
|
|
{
|
|
wlog ("%s '%s' HTTP %s Request Failed (%d)\n",
|
|
smgrEvent.hostname.c_str(),
|
|
smgrEvent.service.c_str(),
|
|
smgrEvent.operation.c_str(),
|
|
smgrEvent.status);
|
|
}
|
|
|
|
smgrEvent.response.clear();
|
|
if (( mtcHttpUtil_get_response ( smgrEvent )) && ( smgrEvent.response.empty() ))
|
|
{
|
|
wlog ("%s failed to get a response\n", smgrEvent.hostname.c_str() );
|
|
}
|
|
|
|
mtcSmgrApi_handler_out:
|
|
|
|
mtcHttpUtil_log_event ( smgrEvent );
|
|
|
|
if ( smgrEvent.blocking == true )
|
|
{
|
|
mtcHttpUtil_free_conn ( smgrEvent );
|
|
mtcHttpUtil_free_base ( smgrEvent );
|
|
|
|
/* This is needed to get out of the loop in the blocking case
|
|
* Calling this here in non-blocking calls can lead to segfault */
|
|
event_base_loopbreak((struct event_base *)arg);
|
|
}
|
|
smgrEvent.active = false ;
|
|
}
|
|
|
|
/*
|
|
* Name : mtcSmgrApi_request
|
|
*
|
|
* Description: Submit any of the following requests to
|
|
* system management against the specified
|
|
* conroller hostname.
|
|
*
|
|
* General Operation - Event Lib Request
|
|
* ------------------- ---------------------------------
|
|
* CONTROLLER_QUERY - SMGR_QUERY_SWACT (non-blocking)
|
|
* CONTROLLER_SWACT - SMGR_START_SWACT (non-blocking)
|
|
* CONTROLLER_DISABLED - SMGR_HOST_DISABLED ( blocking)
|
|
* CONTROLLER_ENABLED - SMGR_HOST_ENABLED ( blocking)
|
|
* CONTROLLER_LOCKED - SMGR_HOST_LOCKED ( blocking)
|
|
* CONTROLLER_UNLOCKED - SMGR_HOST_UNLOCKED ( blocking)
|
|
*
|
|
* Notes : Retries are ignored for non-blocking operations
|
|
*/
|
|
int nodeLinkClass::mtcSmgrApi_request ( struct nodeLinkClass::node * node_ptr, mtc_cmd_enum operation, int retries )
|
|
{
|
|
int count = 0 ;
|
|
int rc = PASS ;
|
|
string operation_string = "unknown" ;
|
|
|
|
if ( system_type == SYSTEM_TYPE__CPE_MODE__SIMPLEX )
|
|
{
|
|
dlog ("%s simpex mode ; SM '%d' request not sent\n", node_ptr->hostname.c_str(), operation );
|
|
return ( PASS );
|
|
}
|
|
|
|
if ( smgrEvent.active == true )
|
|
{
|
|
wlog ("%s Service Manager %s Request - In-Progress (retry)\n",
|
|
node_ptr->hostname.c_str(),
|
|
smgrEvent.operation.c_str());
|
|
|
|
smgrEvent.status = FAIL_MUTEX_ERROR ;
|
|
return (RETRY);
|
|
}
|
|
|
|
rc = mtcHttpUtil_event_init ( &smgrEvent,
|
|
my_hostname,
|
|
"mtcSmgrApi_request",
|
|
hostUtil_getServiceIp (SERVICE_SMGR),
|
|
hostUtil_getServicePort(SERVICE_SMGR));
|
|
if ( rc )
|
|
{
|
|
elog ("%s failed to allocate libEvent memory (%d)\n", node_ptr->hostname.c_str(), rc );
|
|
return (rc);
|
|
}
|
|
|
|
#ifdef WANT_FIT_TESTING
|
|
string value = "" ;
|
|
if ( daemon_want_fit ( FIT_CODE__FAIL_SWACT, node_ptr->hostname, "port", value ))
|
|
{
|
|
smgrEvent.port = atoi(value.data());
|
|
}
|
|
#endif
|
|
|
|
/* Set the common context of this new operation */
|
|
smgrEvent.status = RETRY ;
|
|
smgrEvent.hostname = node_ptr->hostname ;
|
|
smgrEvent.uuid = get_uuid ( node_ptr->hostname );
|
|
|
|
/* Clear payload and response */
|
|
smgrEvent.address = MTC_SMGR_LABEL ;
|
|
smgrEvent.address.append(node_ptr->hostname);
|
|
smgrEvent.token.url = smgrEvent.address ;
|
|
smgrEvent.blocking = true ;
|
|
|
|
smgrEvent.payload = "{\"origin\":\"mtce\"," ;
|
|
|
|
if ( operation == CONTROLLER_QUERY )
|
|
{
|
|
smgrEvent.operation = "Query" ;
|
|
smgrEvent.request = SMGR_QUERY_SWACT ;
|
|
string availStatus = availStatus_enum_to_str (get_availStatus (node_ptr->hostname));
|
|
smgrEvent.blocking = false ;
|
|
smgrEvent.payload = "" ;
|
|
ilog ("%s sending 'query services' request to HA Service Manager\n",
|
|
smgrEvent.hostname.c_str());
|
|
|
|
rc = mtcHttpUtil_api_request ( smgrEvent ) ;
|
|
if ( rc )
|
|
{
|
|
elog ("%s mtcHttpUtil_api_request (rc:%d)\n",
|
|
node_ptr->hostname.c_str(), rc );
|
|
}
|
|
return ( rc ) ;
|
|
}
|
|
else if ( operation == CONTROLLER_SWACT )
|
|
{
|
|
smgrEvent.operation = "Swact" ;
|
|
smgrEvent.request = SMGR_START_SWACT ;
|
|
string availStatus = availStatus_enum_to_str (get_availStatus (node_ptr->hostname));
|
|
smgrEvent.blocking = false ;
|
|
smgrEvent.payload.append ("\"action\":\"swact\",");
|
|
smgrEvent.payload.append ("\"admin\":\"unlocked\",");
|
|
smgrEvent.payload.append ("\"oper\":\"enabled\",");
|
|
smgrEvent.payload.append ("\"avail\":\"");
|
|
smgrEvent.payload.append (availStatus);
|
|
smgrEvent.payload.append ("\"}");
|
|
ilog ("%s sending 'swact' request to HA Service Manager\n",
|
|
smgrEvent.hostname.c_str());
|
|
|
|
return ( mtcHttpUtil_api_request ( smgrEvent )) ;
|
|
}
|
|
else if ( operation == CONTROLLER_DISABLED )
|
|
{
|
|
operation_string = "disabled" ;
|
|
smgrEvent.operation = "Disable" ;
|
|
smgrEvent.request = SMGR_HOST_DISABLED ;
|
|
|
|
string availStatus = availStatus_enum_to_str (get_availStatus (node_ptr->hostname));
|
|
string adminState = adminState_enum_to_str (get_adminState (node_ptr->hostname));
|
|
string adminAction = adminAction_enum_to_str (get_adminAction (node_ptr->hostname));
|
|
|
|
smgrEvent.payload.append ("\"action\":\"");
|
|
if (adminAction.compare("lock"))
|
|
adminAction = "event" ;
|
|
smgrEvent.payload.append (adminAction);
|
|
smgrEvent.payload.append ("\",");
|
|
|
|
smgrEvent.payload.append ("\"admin\":\"");
|
|
smgrEvent.payload.append (adminState);
|
|
smgrEvent.payload.append ("\",");
|
|
|
|
smgrEvent.payload.append ("\"oper\":\"disabled\",");
|
|
|
|
smgrEvent.payload.append ("\"avail\":\"");
|
|
smgrEvent.payload.append (availStatus);
|
|
smgrEvent.payload.append ("\"}");
|
|
|
|
ilog ("%s sending '%s-disabled' request to HA Service Manager\n",
|
|
smgrEvent.hostname.c_str(), adminState.c_str() );
|
|
}
|
|
else if ( operation == CONTROLLER_ENABLED )
|
|
{
|
|
smgrEvent.request = SMGR_HOST_ENABLED ;
|
|
smgrEvent.operation = "Enable" ;
|
|
operation_string = "enabled" ;
|
|
|
|
string availStatus = availStatus_enum_to_str (get_availStatus (node_ptr->hostname));
|
|
string adminState = adminState_enum_to_str (get_adminState (node_ptr->hostname));
|
|
string adminAction = adminAction_enum_to_str (get_adminAction (node_ptr->hostname));
|
|
|
|
smgrEvent.payload.append ("\"action\":\"");
|
|
if (adminAction.compare("unlock"))
|
|
adminAction = "event" ;
|
|
smgrEvent.payload.append (adminAction);
|
|
smgrEvent.payload.append ("\",");
|
|
|
|
smgrEvent.payload.append ("\"admin\":\"");
|
|
smgrEvent.payload.append (adminState);
|
|
smgrEvent.payload.append ("\",");
|
|
|
|
smgrEvent.payload.append ("\"oper\":\"enabled\",");
|
|
|
|
smgrEvent.payload.append ("\"avail\":\"");
|
|
smgrEvent.payload.append (availStatus);
|
|
smgrEvent.payload.append ("\"}");
|
|
|
|
ilog ("%s sending 'unlocked-enabled' request to HA Service Manager\n",
|
|
smgrEvent.hostname.c_str());
|
|
}
|
|
else if ( operation == CONTROLLER_LOCKED )
|
|
{
|
|
operation_string = "locked" ;
|
|
smgrEvent.request = SMGR_HOST_LOCKED ;
|
|
smgrEvent.operation = "Lock" ;
|
|
smgrEvent.payload.append ("\"action\":\"lock\",");
|
|
smgrEvent.payload.append ("\"admin\":\"locked\",");
|
|
smgrEvent.payload.append ("\"oper\":\"disabled\",");
|
|
smgrEvent.payload.append ("\"avail\":\"online\"}");
|
|
|
|
ilog ("%s sending 'locked-disabled' request to HA Service Manager\n",
|
|
smgrEvent.hostname.c_str());
|
|
|
|
}
|
|
else if ( operation == CONTROLLER_UNLOCKED )
|
|
{
|
|
operation_string = "unlocked" ;
|
|
smgrEvent.request = SMGR_HOST_UNLOCKED ;
|
|
smgrEvent.operation = "Unlock" ;
|
|
smgrEvent.payload.append ("\"action\":\"unlock\",");
|
|
smgrEvent.payload.append ("\"admin\":\"unlocked\",");
|
|
smgrEvent.payload.append ("\"oper\":\"enabled\",");
|
|
smgrEvent.payload.append ("\"avail\":\"available\"}");
|
|
|
|
ilog ("%s sending 'unlocked-enabled' request to Service Manager\n",
|
|
smgrEvent.hostname.c_str());
|
|
}
|
|
else
|
|
{
|
|
return (FAIL_BAD_CASE);
|
|
}
|
|
do
|
|
{
|
|
rc = mtcHttpUtil_api_request ( smgrEvent ) ;
|
|
|
|
if ((( operation == CONTROLLER_DISABLED ) ||
|
|
( operation == CONTROLLER_LOCKED )) &&
|
|
( rc == HTTP_NOTFOUND ))
|
|
{
|
|
dlog ("%s Service Management (%d)\n", node_ptr->hostname.c_str(), rc );
|
|
rc = PASS ;
|
|
}
|
|
if ( rc != PASS )
|
|
{
|
|
count++ ;
|
|
wlog ("%s failed sending '%s' state to SM (rc:%d) ... retrying (cnt:%d)\n",
|
|
node_ptr->hostname.c_str(), operation_string.c_str(),
|
|
rc, count );
|
|
}
|
|
} while ( ( rc != PASS ) && ( count < retries ) ) ;
|
|
|
|
if ( rc )
|
|
{
|
|
elog ("%s failed sending '%s' state to Service Management failed (%d) ; giving up (cnt:%d)\n",
|
|
node_ptr->hostname.c_str(),
|
|
operation_string.c_str(),
|
|
rc , count );
|
|
}
|
|
else
|
|
{
|
|
ilog ("%s is '%s' to Service Management\n", node_ptr->hostname.c_str(), operation_string.c_str());
|
|
}
|
|
return ( rc );
|
|
}
|
|
|
|
int mtcSmgrApi_service_state ( libEvent & event , bool & swactable_services )
|
|
{
|
|
int rc = FAIL ;
|
|
|
|
swactable_services = false ;
|
|
|
|
if ( event.response.empty() )
|
|
{
|
|
elog ("%s Query Service State Failed - Empty Response\n",
|
|
event.hostname.c_str());
|
|
return (rc);
|
|
}
|
|
else
|
|
{
|
|
/* O.K. Lets look at the response - load it into the strings */
|
|
string origin = "" ;
|
|
string hn = "" ;
|
|
string yesno = "" ;
|
|
string origin_key = "origin" ;
|
|
string hostname_key = "hostname" ;
|
|
string swactable_services_key = "swactable_services" ;
|
|
/*
|
|
* {
|
|
* "origin" : "sm "
|
|
* "admin" : "unlocked | locked " don't care
|
|
* "oper" : "enabled | disabled " don't care
|
|
* "avail" : "any availability state " don't care
|
|
* "hostname" : "controller-0 | controller-1"
|
|
* "active_services" : "yes | no "
|
|
* "swactable_services": "yes | no "
|
|
* }
|
|
*/
|
|
|
|
int rc1 = jsonUtil_get_key_val((char*)event.response.c_str(),
|
|
hostname_key, hn );
|
|
int rc2 = jsonUtil_get_key_val((char*)event.response.c_str(),
|
|
origin_key, origin );
|
|
int rc3 = jsonUtil_get_key_val((char*)event.response.c_str(),
|
|
swactable_services_key, yesno );
|
|
if (( rc1 != PASS ) ||
|
|
( rc2 != PASS ) ||
|
|
( rc3 != PASS ) )
|
|
{
|
|
elog ("%s Query Services Failed - Read Key:Values (hn:%d or:%d yn:%d)\n",
|
|
event.hostname.c_str(),
|
|
rc1, rc2, rc3 );
|
|
}
|
|
else if ( event.hostname.compare (hn) )
|
|
{
|
|
elog ("%s Query Services Failed - Wrong Controller (%s)\n",
|
|
event.hostname.c_str(),
|
|
hn.c_str());
|
|
}
|
|
else if ( !yesno.compare("yes") )
|
|
{
|
|
swactable_services = true ;
|
|
rc = PASS ;
|
|
}
|
|
else if ( !yesno.compare("no") )
|
|
{
|
|
swactable_services = false ;
|
|
rc = PASS ;
|
|
}
|
|
else
|
|
{
|
|
elog ("%s Query Services Failed - %s service state (%s:%s)\n",
|
|
event.hostname.c_str(),
|
|
yesno.c_str(),
|
|
hn.c_str(),
|
|
yesno.c_str());
|
|
}
|
|
}
|
|
return (rc);
|
|
}
|
|
|
|
/* The Neutron request handler wrapper abstracted from nodeLinkClass */
|
|
void mtcSmgrApi_Handler ( struct evhttp_request *req, void *arg )
|
|
{
|
|
get_mtcInv_ptr()->mtcSmgrApi_handler ( req , arg );
|
|
}
|