config/controllerconfig/controllerconfig/upgrade-scripts/69-update-nfs-ip-address-alias.py
Fabiano Mercer 8c18514af3 Keep platform-nfs-ip for upgrade process
The platform-nfs-ip service is not necessary for fresh installs
because it is just an alias for the controller IP.
But for old releases like StarlingX rel. 6 or 7 the
platform-nfs-ip uses a specific IP, If for some reason an error
occurs during the upgrade process, the upgrade will be aborted
and the nodes will downgrade to the older release again.
At this moment the nodes will try to communicate with the
previous platform-nfs-ip IP configured in /etc/hosts.
But if the active controller is using the new Release
this IP doesn't exist anymore and the downgrade will fail.
For this reason the platform-nfs-ip service will be available
just for upgrade operations and will be deprovisioned for fresh
installs or at the end of the upgrade process
( upgrade-activate phase ).

Test plan
PASS Fresh install on AIO-SX
     Fresh install on AIO-DX
PASS Upgrade AIO-DX system from CENTOS Rel 7 to DEBIAN Rel 8
PASS Reboot controller-0 during upgrade of AIO-DX
     controller-1 was the active one with the new release ( Rel 8 )
     controller-0 using old release.
     reboot controller-0 and check if it could connect to
     controller-1 using old platform-nfs-ip.
PASS Upgrade-abort during AIO-DX upgrade
     controller-1 was the active controller and already upgraded
     controller-0 was upgraded but locked.
     Abort the upgrade and downgrade to old release ( Rel 7 )

Partial-Bug: #2012387
Depends-On: https://review.opendev.org/c/starlingx/stx-puppet/+/878122

Signed-off-by: Fabiano Mercer <fabiano.correamercer@windriver.com>
Change-Id: Ia7217544f2c954a83af71d488e0f2d722e17ec64
2023-03-22 15:24:14 -03:00

126 lines
4.1 KiB
Python

#!/usr/bin/env python
# Copyright (c) 2022 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This migration script is used for update controller-platform-nfs
# during migrate stage of platform upgrade. It will:
# - create controller-platform-nfs alias for controller mgmt IP in
# /opt/platform/config/<to_release>/hosts file
# - remove the controller-platform-nfs-mgmt IP address from address DB
import sys
import psycopg2
from psycopg2.extras import DictCursor
import subprocess
import os.path
from controllerconfig.common import log
LOG = log.get_logger(__name__)
def _add_nfs_alias_to_hosts_file(connection, to_release):
with connection.cursor(cursor_factory=DictCursor) as cur:
# during the upgrade-start the hosts file is copied from:
# /opt/platform/config/<from_release>/
# to
# /opt/platform/config/<to_release>/
# and /opt/platform/config/<to_release>/host is used to upgrade
# other controller/storage/worker nodes
# the host files from this path must be updated
CONFIG_PERMDIR = "/opt/platform/config/{}".format(to_release)
host_file = "{}/hosts".format(CONFIG_PERMDIR)
LOG.info("updating hosts in {}".format(CONFIG_PERMDIR))
if (not os.path.exists(host_file)):
LOG.info("Skipping update of {}. File does not exists"
.format(host_file))
return None
LOG.info("Get controller-mgmt floating ip from 'addresses' table")
cur.execute("SELECT address FROM addresses WHERE "
"name='controller-mgmt';")
ctrl_mgmt_ip = cur.fetchone()
# remove the controller-platform-nfs line from ${host_file}
sed_cmd = "sed -i '/controller\-platform\-nfs/d' {}".format(host_file)
# Find the controller mgmt floating IP
# copy entire line and put in ctrl_float
grep_cmd = "grep -w '{}' {} | xargs -I ctrl_float" \
.format(ctrl_mgmt_ip['address'], host_file)
# Add the alias controller-platform-nfs to controller IP
# replacing the ${ctrl_float} by
# "${ctrl_float} controller-platform-nfs"
sed_concat = "sed -i -e " \
"'s|ctrl_float|ctrl_float controller-platform-nfs|' {}" \
.format(host_file)
command = "{} && {} {}".format(sed_cmd, grep_cmd, sed_concat)
sub = subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = sub.communicate()
if sub.returncode != 0:
LOG.error('Cmd Failed:\n%s\n.%s\n%s' % (command, stdout, stderr))
raise Exception('Error controller-platform-nfs IP: {} '
'in etc/hosts'.format(ctrl_mgmt_ip['address']))
LOG.info('alias controller-platform-nfs added for IP: {} '
'in {}'.format(ctrl_mgmt_ip['address'], host_file))
def main():
action = None
from_release = None
to_release = None
arg = 1
res = 0
log.configure()
while arg < len(sys.argv):
if arg == 1:
from_release = sys.argv[arg]
elif arg == 2:
to_release = sys.argv[arg]
elif arg == 3:
action = sys.argv[arg]
else:
LOG.error("Invalid option %s." % sys.argv[arg])
return 1
arg += 1
LOG.info("%s invoked with from_release = %s to_release = %s action = %s"
% (sys.argv[0], from_release, to_release, action))
if action == "migrate" and from_release in ['21.12', '22.06']:
conn = psycopg2.connect("dbname=sysinv user=postgres")
try:
_add_nfs_alias_to_hosts_file(conn, to_release)
except psycopg2.Error as ex:
LOG.exception(ex)
LOG.warning("DB Connection error")
res = 1
except Exception as ex:
LOG.exception(ex)
LOG.warning("Exception")
res = 1
else:
LOG.info("controller-platform-nfs alias updated")
finally:
LOG.info("Closing DB connection")
conn.close()
return res
if __name__ == "__main__":
sys.exit(main())