Merge "[PTP dual NIC config] Avoid late old-PTP update"

This commit is contained in:
Zuul 2022-03-01 00:31:41 +00:00 committed by Gerrit Code Review
commit db218804e0
3 changed files with 88 additions and 55 deletions

View File

@ -18,6 +18,7 @@
# 'ptp4l' entry in 'ptp_instances' and inserts the corresponding entry
# in 'ptp_parameters'.
import os
import sys
import psycopg2
from controllerconfig.common import log
@ -28,6 +29,11 @@ from psycopg2.extras import DictCursor
LOG = log.get_logger(__name__)
INTERFACE_PTP_ROLE_NONE = 'none'
PLATFORM_PATH = '/opt/platform' # following tsconfig
# Hidden file indicating the update/upgrade from legacy configuration
# has been already run
PTP_UPDATE_PARAMETERS_DONE = '.update_ptp_parameters_done'
# PTP instance types
PTP_INSTANCE_TYPE_PTP4L = 'ptp4l'
@ -88,42 +94,52 @@ def main():
LOG.info("%s invoked from_release = %s to_release = %s action = %s"
% (sys.argv[0], from_release, to_release, action))
res = 0
if action == "migrate" and (
from_release == '21.05' or from_release == '21.12'):
conn = psycopg2.connect("dbname=sysinv user=postgres")
try:
if _legacy_ptp4l_not_found(conn):
_move_ptp_parameters(conn)
res = 0
except psycopg2.Error as ex:
LOG.exception(ex)
res = 1
except Exception as ex:
LOG.exception(ex)
res = 1
finally:
conn.close()
return res
# Avoid attempt of updating PTP configuration after this upgrade
TO_CONFIG_PATH = PLATFORM_PATH + '/config/' + to_release + '/'
to_file = os.path.join(TO_CONFIG_PATH, PTP_UPDATE_PARAMETERS_DONE)
open(to_file, 'w').close()
# First check on filesystem to detect if some update from old PTP
# configuration has been already done (before upgrading)
FROM_CONFIG_PATH = PLATFORM_PATH + '/config/' + from_release + '/'
from_file = os.path.join(FROM_CONFIG_PATH, PTP_UPDATE_PARAMETERS_DONE)
if not os.path.isfile(from_file):
conn = psycopg2.connect("dbname=sysinv user=postgres")
try:
# Second check, using the restored database contents
if _legacy_instances_not_found(conn):
_move_ptp_parameters(conn)
except psycopg2.Error as ex:
LOG.exception(ex)
res = 1
except Exception as ex:
LOG.exception(ex)
res = 1
finally:
conn.close()
return res
def _legacy_ptp4l_not_found(connection):
def _legacy_instances_not_found(connection):
with connection.cursor(cursor_factory=DictCursor) as cur:
# Look for legacy ptp4l instance already in database, which is an
# indication this migration was performed before (probably when
# applying an update/patch)
cur.execute("SELECT id FROM ptp_instances WHERE name = %s;",
(PTP_INSTANCE_LEGACY_PTP4L,))
ptp4l_instance = cur.fetchone()
if ptp4l_instance is not None:
LOG.info("Legacy ptp4l instance found with id = %s" %
ptp4l_instance['id'])
cur.execute("SELECT id FROM ptp_instances WHERE "
"name = %s OR name = %s;",
(PTP_INSTANCE_LEGACY_PTP4L,
PTP_INSTANCE_LEGACY_PHC2SYS))
instance = cur.fetchone()
if instance is not None:
LOG.info("Legacy instance found with id = %s" % instance['id'])
return False
LOG.info("No legacy ptp4l instance found")
return True
LOG.info("No legacy instances found")
return True
def _insert_ptp_parameter_owner(connection, type, capabilities=None):
def _insert_ptp_parameter_owner(connection, owner_type, capabilities=None):
owner_uuid = uuidutils.generate_uuid()
with connection.cursor(cursor_factory=DictCursor) as cur:
@ -131,7 +147,7 @@ def _insert_ptp_parameter_owner(connection, type, capabilities=None):
cur.execute("INSERT INTO ptp_parameter_owners "
"(created_at, uuid, type, capabilities)"
"VALUES (%s, %s, %s, %s);",
(datetime.now(), owner_uuid, type, capabilities))
(datetime.now(), owner_uuid, owner_type, capabilities))
cur.execute("SELECT id FROM ptp_parameter_owners WHERE uuid = %s;",
(owner_uuid,))
row = cur.fetchone()
@ -233,12 +249,12 @@ def _move_ptp_parameters(connection):
return
with connection.cursor(cursor_factory=DictCursor) as cur:
# List all the interfaces with ptp_role=slave
# List all the interfaces with ptp_role!=none
cur.execute("SELECT id FROM interfaces WHERE ptp_role <> %s;",
(INTERFACE_PTP_ROLE_NONE,))
slave_ifaces = cur.fetchall()
ptp_ifaces = cur.fetchall()
LOG.debug("There are %d interfaces with ptp_role != none" %
len(slave_ifaces))
len(ptp_ifaces))
LOG.info("Creating PTP instances for legacy parameters")
@ -297,8 +313,8 @@ def _move_ptp_parameters(connection):
_assign_instance_to_host(connection, ptp4l_id, host['id'])
_assign_instance_to_host(connection, phc2sys_id, host['id'])
# Assign legacy PTP interfaces to all interfaces with ptp_role=slave
for iface in slave_ifaces:
# Assign legacy PTP interfaces to all interfaces with ptp_role!=none
for iface in ptp_ifaces:
_assign_ptp_to_interface(connection, ptp4lif_id, iface['id'])
_assign_ptp_to_interface(connection, phc2sysif_id, iface['id'])
@ -386,6 +402,10 @@ def _move_ptp_parameters(connection):
connection, PTP_PARAMETER_BC_JBOD, PTP_BOUNDARY_CLOCK_JBOD_1)
_add_parameter_to_instance(connection, ptp4l_uuid, bc_clock_jbod_uuid)
# Committing all changes
LOG.info("Committing PTP legacy configuration into database")
connection.commit()
if __name__ == "__main__":
sys.exit(main())

View File

@ -7174,11 +7174,6 @@ class ConductorManager(service.PeriodicService):
(ptp_interface_id, interface_id))
def _update_ptp_parameters(self):
# TODO: this method is supposed to be called in the context of the same
# patch that is deprecating the former PTP APIs. Thus, in a future
# release (probably the next one) it can be removed
LOG.info("Checking for pending update of PTP parameters")
"""This function moves PTP legacy configuration from other tables. Once
it is done, the subsequent calls will find the generated PTP instance at
database and will return quickly.
@ -7197,18 +7192,32 @@ class ConductorManager(service.PeriodicService):
'ptp4l' entry in 'ptp_instances' and inserts the corresponding entry
in 'ptp_parameters'.
"""
# TODO: this method is supposed to be called in the context of the same
# patch that is deprecating the former PTP APIs. Thus, in a future
# release (probably the next one) it can be removed
check_file = tsc.PTP_UPDATE_PARAMETERS_FLAG
if os.path.isfile(check_file):
LOG.debug("Already done with legacy PTP configuration")
return
# Add check file to avoid re-running this method (with late creation of
# legacy instances)
open(check_file, 'w').close()
try:
# Look for legacy ptp4l instance already in database, which is an
# indication this migration was performed before (probably when
# upgrading the release)
try:
ptp_instance = self.dbapi.ptp_instance_get_by_name(
constants.PTP_INSTANCE_LEGACY_PTP4L)
LOG.debug("Legacy ptp4l instance found with id = %s" %
ptp_instance['id'])
return
except exception.NotFound:
LOG.debug("No legacy ptp4l instance found")
# This additional check ensures that patch re-apply won't fail
# because legacy entries weren't removed together with the check
# file and the patch itself, when it got removed earlier
legacy_names = [constants.PTP_INSTANCE_LEGACY_PTP4L,
constants.PTP_INSTANCE_LEGACY_PHC2SYS]
for name in legacy_names:
try:
ptp_instance = self.dbapi.ptp_instance_get_by_name(name)
LOG.info("Legacy PTP instance %s found with id = %s, "
"skipping update" % (name, ptp_instance['id']))
return
except exception.NotFound:
LOG.debug("Legacy PTP instance %s not found" % name)
# List all the hosts with clock_synchronization=ptp
hosts_list = self.dbapi.ihost_get_list()
@ -7230,14 +7239,14 @@ class ConductorManager(service.PeriodicService):
# No need for upgrade
return
# List all the interfaces with ptp_role=slave
# List all the interfaces with ptp_role!=none
ifaces_list = self.dbapi.iinterface_get_list()
slave_ifaces_list = [
ptp_ifaces_list = [
iface
for iface in ifaces_list
if iface['ptp_role'] != constants.INTERFACE_PTP_ROLE_NONE]
LOG.debug("There are %d interfaces with ptp_role != none" %
len(slave_ifaces_list))
len(ptp_ifaces_list))
LOG.info("Creating PTP instances for legacy parameters")
@ -7281,9 +7290,8 @@ class ConductorManager(service.PeriodicService):
self._update_ptp_assign_instance_to_host(ptp4l_id, host['id'])
self._update_ptp_assign_instance_to_host(phc2sys_id, host['id'])
# Assign legacy PTP interfaces to all interfaces with
# ptp_role=slave
for iface in slave_ifaces_list:
# Assign legacy PTP interfaces to all interfaces with ptp_role!=none
for iface in ptp_ifaces_list:
self._update_ptp_assign_ptp_to_interface(ptp4lif_id,
iface['id'])
self._update_ptp_assign_ptp_to_interface(phc2sysif_id,

View File

@ -241,6 +241,11 @@ UPGRADE_ROLLBACK_FLAG = os.path.join(
UPGRADE_ABORT_FILE = '.upgrade_abort'
UPGRADE_ABORT_FLAG = os.path.join(
CONFIG_PATH, UPGRADE_ABORT_FILE)
# Update/upgrade from legacy PTP configuration has been already run
# TODO(douglashenrique.koerich): remove it in a later release # pylint: disable=fixme
PTP_UPDATE_PARAMETERS_DONE = '.update_ptp_parameters_done'
PTP_UPDATE_PARAMETERS_FLAG = os.path.join(CONFIG_PATH,
PTP_UPDATE_PARAMETERS_DONE)
# Set on controller-0 (by controller-1) to indicate that data migration has
# started