Merge "Remove deprecated upgrade scripts"

This commit is contained in:
Zuul 2022-06-16 23:47:49 +00:00 committed by Gerrit Code Review
commit 4e46f2ac6a
5 changed files with 0 additions and 675 deletions

View File

@ -1,267 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import math
import psycopg2
import sys
import subprocess
from controllerconfig.common import log
from operator import itemgetter
from psycopg2.extras import RealDictCursor
LOG = log.get_logger(__name__)
BACKUP_GUID = 'ba5eba11-0000-1111-2222-000000000002'
SYSINV_GUID = 'ba5eba11-0000-1111-2222-000000000001'
def main():
action = None
from_release = None
to_release = None # noqa
arg = 1
while arg < len(sys.argv):
if arg == 1:
from_release = sys.argv[arg]
elif arg == 2:
to_release = sys.argv[arg] # noqa
elif arg == 3:
action = sys.argv[arg]
else:
print("Invalid option %s." % sys.argv[arg])
return 1
arg += 1
log.configure()
LOG.debug("%s invoked with from_release = %s to_release = %s action = %s"
% (sys.argv[0], from_release, to_release, action))
if from_release == "21.05" and action == "migrate":
try:
adjust_backup_partition()
except Exception as ex:
LOG.exception(ex)
return 1
def adjust_backup_partition():
installed_backup_size = get_backup_size()
conn = psycopg2.connect("dbname=sysinv user=postgres")
with conn:
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute("select i_host.id, i_host.rootfs_device from i_host "
"where personality='controller'")
controllers = cur.fetchall()
if not controllers:
LOG.exception("Failed to fetch controller host information")
raise
for controller in controllers:
controller_rootfs_disk = get_host_rootfs(cur, controller)
db_partitions = get_db_partitions(
cur, controller, controller_rootfs_disk)
LOG.info("Database partition data: %s" % db_partitions)
backup_partition = next(p for p in db_partitions if
p['type_guid'].lower() == BACKUP_GUID)
original_backup_size = backup_partition['size_mib']
if installed_backup_size == original_backup_size:
LOG.info("Backup partition size unchanged, nothing to do. "
"Installed: %s DB: %s" %
(installed_backup_size, original_backup_size))
continue
backup_change = installed_backup_size - original_backup_size
adjusted_partitions = move_partitions(
db_partitions, backup_partition, backup_change)
# Ensure the last partition will fit on the disk
disk_size = controller_rootfs_disk['size_mib'] - 1
last_partition = adjusted_partitions[-1]
required_space = max(0, last_partition['end_mib'] - disk_size)
if required_space == 0:
update_partitions(cur, adjusted_partitions)
LOG.info("Adjusted partitions fit rootfs, can continue. "
"Partitions: %s " % adjusted_partitions)
continue
added_partitions = [p for p in db_partitions if
p['type_guid'].lower() == SYSINV_GUID]
unassigned_partitions = [p for p in added_partitions if
p['foripvid'] is None]
if not added_partitions:
# This is not an AIO system, we'll resize the last partiton
added_partitions.append(last_partition)
partitions = unassigned_partitions if unassigned_partitions else added_partitions # noqa
partition = max(partitions, key=itemgetter('size_mib'))
if partition['size_mib'] < required_space:
LOG.exception(
"Insufficient space to resize partition %s - %s" %
(partition, required_space))
raise
reduced_partitions = move_partitions(
adjusted_partitions, partition, required_space * -1)
final_partitions = adjusted_partitions[:adjusted_partitions.index(partition)] # noqa
final_partitions.extend(reduced_partitions)
update_partitions(cur, final_partitions)
host_pvs = get_pvs(cur, controller)
partition_vg_name = get_vg_name(partition, host_pvs)
if partition_vg_name == 'cgts-vg':
resize_cgts_vg(cur, controller, required_space)
def get_host_rootfs(cursor, host):
disk_query = "select * from i_idisk where forihostid=%s and capabilities like %s" # noqa: E501
cursor.execute(disk_query, (host['id'], '%rootfs%',))
return cursor.fetchone()
def get_db_partitions(cursor, host, rootfs):
partition_query = "select * from partition where forihostid = %s and idisk_uuid = %s" # noqa: E501
cursor.execute(partition_query, (host['id'], rootfs['uuid'],))
return cursor.fetchall()
def get_backup_size():
lsblk_command = 'lsblk -pno PKNAME $(findmnt -n / -o SOURCE)'
lsblk = subprocess.Popen(lsblk_command, stdout=subprocess.PIPE, shell=True)
root_disk_path = lsblk.stdout.read()
part_info = get_sgdisk_info(root_disk_path)
backup_size = next(part['size_mib'] for part in part_info if
part['type_guid'].lower() == BACKUP_GUID)
return int(backup_size)
def get_sgdisk_info(device_path):
"""Obtain partition info: type GUID, type name, UUID, start, end, size.
:param: device_path: the disk's device path
:returns: list of partition info
"""
sgdisk_part_info = []
fields = ['part_number', 'device_node', 'type_guid', 'type_name', 'uuid',
'start_mib', 'end_mib', 'size_mib']
sgdisk_command = '{} {}'.format('/usr/bin/partition_info.sh',
device_path)
try:
sgdisk_process = subprocess.Popen(sgdisk_command,
stdout=subprocess.PIPE,
shell=True)
except Exception as e:
LOG.exception("Could not retrieve partition information: %s" % e)
raise
sgdisk_output = sgdisk_process.stdout.read()
rows = [row for row in sgdisk_output.split(';') if row.strip()]
for row in rows:
values = row.split()
partition = dict(zip(fields, values))
if 'part_number' in partition.keys():
partition['part_number'] = int(partition['part_number'])
sgdisk_part_info.append(partition)
return sgdisk_part_info
def move_partitions(db_values, start, size):
"""
Updates the list of partitions based on the new size of a given partition
:param: db_values: A list of partitions to adjust
:param: start: The partition being adjusted
:param: size: The change in size of the partition
:returns: A sorted list of updated partitions
"""
partitions = sorted(db_values, key=itemgetter('start_mib'))
partitions = partitions[partitions.index(start):]
# Update the specified partition size and end_mib
partitions[0]['size_mib'] += size
partitions[0]['end_mib'] += size
# Shift the rest of the partitions
for partition in partitions[1:]:
partition['start_mib'] += size
partition['end_mib'] += size
return partitions
def update_partitions(cursor, updated_partitions):
LOG.info("Updating partitions to: %s" % updated_partitions)
update_query = "update partition set start_mib=%s, end_mib=%s, size_mib=%s where id=%s" # noqa: E501
for partition in updated_partitions:
cursor.execute(update_query,
(partition['start_mib'], partition['end_mib'],
partition['size_mib'], partition['id']))
def get_pvs(cursor, host):
query = "select * from i_pv where forihostid=%s"
cursor.execute(query, (host['id'],))
return cursor.fetchall()
def get_vg_name(partition, pvs):
pv_id = partition['foripvid']
if not pv_id:
return None
return next(pv['lvm_vg_name'] for pv in pvs if pv['id'] == pv_id)
def resize_cgts_vg(cursor, host, required_space):
cgts_vg = get_cgts_vg(cursor, host)
cgts_vg_free_space = int(cgts_vg['lvm_vg_size'] / cgts_vg['lvm_vg_total_pe']) * cgts_vg['lvm_vg_free_pe'] # noqa: E501
# There may be available space in the cgts_vg
if cgts_vg_free_space >= required_space:
LOG.info("cgts_vg has sufficient space, can continue. "
"cgts_vg: %s " % cgts_vg)
return
# Otherwise we'll reduce the backup fs by up to 15GB and remove
# the rest from the docker fs
required_space -= cgts_vg_free_space
required_gb = int(math.ceil(required_space / 1024.0))
backup_fs_reduction = min(15, required_gb)
update_host_fs(cursor, host, 'backup', backup_fs_reduction)
required_gb -= backup_fs_reduction
if required_gb > 0:
update_host_fs(cursor, host, 'docker', required_gb)
def get_cgts_vg(cursor, host):
query = "select * from i_lvg where lvm_vg_name='cgts-vg' and forihostid=%s"
cursor.execute(query, (host['id'],))
return cursor.fetchone()
def update_host_fs(cursor, host, fs_name, reduction):
size_query = "select size from host_fs where name=%s and forihostid=%s"
cursor.execute(size_query, (fs_name, host['id']))
original_size = cursor.fetchone()['size']
new_size = original_size - reduction
LOG.info("Updating %s host fs to %s" % (fs_name, new_size))
update_query = "update host_fs set size=%s where name=%s and forihostid=%s"
cursor.execute(update_query, (new_size, fs_name, host['id']))
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,106 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This script will add service parameters specific to handling of ghcr.io
# registry into the sysinv database during migration phase of upgrade
# procedure.
# Also, the previous horizon parameters will be removed without necessity
# to keep the old unused values.
import sys
import psycopg2
from datetime import datetime
from oslo_utils import uuidutils
from psycopg2.extras import RealDictCursor
from controllerconfig.common import log
LOG = log.get_logger(__name__)
def main():
action = None
from_release = None
to_release = None
arg = 1
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:
print("Invalid option %s." % sys.argv[arg])
return 1
arg += 1
log.configure()
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 == '21.05':
try:
conn = psycopg2.connect("dbname=sysinv user=postgres")
with conn:
add_ghcr_registry(conn)
remove_horizon_params(conn)
return 0
except Exception as ex:
LOG.exception(ex)
return 1
def get_gcr_rows(db_conn):
with db_conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute("select name, value, personality, resource from "
"service_parameter where service='docker' and "
"section='gcr-registry'")
return cur.fetchall()
def add_ghcr_registry(db_conn):
cmd = """
INSERT INTO service_parameter (created_at, uuid, name,
value, service, section, personality, resource) VALUES
(%s, %s, %s, %s, %s, %s, %s, %s);
"""
rows = get_gcr_rows(db_conn)
for row in rows:
timestamp = str(datetime.now())
uuid = uuidutils.generate_uuid()
value = row.get('value')
# There are two names where we expect to need to
# replace the registry name in the corresponding value.
for key in ['additional-overrides', 'url']:
if value and row.get('name') == key:
value = value.replace('gcr.io', 'ghcr.io')
LOG.info("Adding %s=%s to db for ghcr-registry"
% (row['name'], value))
with db_conn.cursor() as cur:
cur.execute(
cmd,
(timestamp, uuid, row['name'], value,
'docker', 'ghcr-registry', row['personality'],
row['resource']))
LOG.info("ghcr_registry parameters upgrade completed")
def remove_horizon_params(db_conn):
cmd_delete = "DELETE FROM service_parameter WHERE " \
"service='horizon' and section='auth'"
LOG.info("Removing horizon auth params from db")
with db_conn.cursor() as cur:
cur.execute(cmd_delete)
LOG.info("Horizon auth params removed")
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,65 +0,0 @@
#!/usr/bin/python
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This script updates armada to add tolerations for the
# node-role.kubernetes.io/master:NoSchedule taint on armada-api pod.
#
# This script can be removed in the release that follows stx6
import subprocess
import sys
from controllerconfig.common import log
LOG = log.get_logger(__name__)
def main():
action = None
from_release = None
to_release = None
arg = 1
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:
print("Invalid option %s." % sys.argv[arg])
return 1
arg += 1
log.configure()
if action == 'activate' and from_release == '21.05':
LOG.info("%s invoked with from_release = %s to_release = %s "
"action = %s"
% (sys.argv[0], from_release, to_release, action))
update_armada_toleration()
def update_armada_toleration():
"""Run upgrade-k8s-armada-helm.yml to update armada helm chart.
When this script is run, all hosts have been upgraded and the new helm
chart and the armada-overrides.yaml.j2 file with the tolerations override
are available on the active controller.
This function will run the upgrade-k8s-armada-helm.yml playbook that
upgrades the armada chart with overrides present on armada-overrides.yaml.
"""
playbooks_root = '/usr/share/ansible/stx-ansible/playbooks'
upgrade_script = 'upgrade-k8s-armada-helm.yml'
cmd = 'ansible-playbook {}/{}'.format(playbooks_root, upgrade_script)
sub = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = sub.communicate()
if sub.returncode != 0:
LOG.error('Command failed:\n %s\n. %s\n%s' % (cmd, stdout, stderr))
raise Exception('Cannot update armada')
LOG.info('Toleration applied to armada successfully')
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,89 +0,0 @@
#!/bin/bash
#
# Copyright (c) 2021 Intel Corporation.
#
# SPDX-License-Identifier: Apache-2.0
#
# Enable separate etcd ca during upgrade.
#
# Note: this can be removed in the release after STX6.0
. /etc/platform/platform.conf
# This will log to /var/log/platform.log
function log {
logger -p local1.info $1
}
FROM_REL=$1
TO_REL=$2
ACTION=$3
# below function is cloned from ../scripts/controller_config
get_ip()
{
HOST_NAME=$1
# Check /etc/hosts for the hostname
HOST_IP=$(cat /etc/hosts | grep "${HOST_NAME}" | awk '{print $1}')
if [ -n "${HOST_IP}" ]; then
echo "${HOST_IP}"
return
fi
# Try the DNS query
# Because dnsmasq can resolve both a hostname to both an IPv4 and an IPv6
# address in certain situations, and the last address is the IPv6, which
# would be the management, this is preferred over the IPv4 pxeboot address,
# so take the last address only.
HOST_IP=$(dig +short ANY $host|tail -1)
if [[ "${HOST_IP}" =~ ^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$ ]]; then
echo "${HOST_IP}"
return
fi
if [[ "${HOST_IP}" =~ ^[0-9a-z]*\:[0-9a-z\:]*$ ]]; then
echo "${HOST_IP}"
return
fi
}
enable_separate_etcd_ca()
{
STATIC_YAML="/opt/platform/puppet/${sw_version}/hieradata/static.yaml"
SYSTEM_YAML="/opt/platform/puppet/${sw_version}/hieradata/system.yaml"
if [[ ! -f ${STATIC_YAML} ]] || [[ ! -f ${SYSTEM_YAML} ]]; then
log "Could not find specific static/system yaml files in /opt/platform/puppet/${sw_version}/hieradata!"
exit 1
fi
CLUSTER_FLOATING_ADDRESS=$(grep "platform::network::cluster_host::params::controller_address" ${SYSTEM_YAML} | awk '{print $2}')
CLUSTER_FLOATING_ADDRESS_VERSION=$(grep "platform::network::cluster_host::params::subnet_version" ${SYSTEM_YAML} | awk '{print $2}')
HOST_ADDR=$(get_ip $(hostname))
ansible-playbook /usr/share/ansible/stx-ansible/playbooks/separate_etcd_ca.yml \
-e "cluster_floating_address=${CLUSTER_FLOATING_ADDRESS}" \
-e "etcd_listen_address_version=${CLUSTER_FLOATING_ADDRESS_VERSION}" \
-e "puppet_permdir=/opt/platform/puppet/${sw_version}" \
-e "config_permdir=/opt/platform/config/${sw_version}" \
-e "ipaddress=${HOST_ADDR}" \
-e "etcd_root_ca_cert=''" \
-e "etcd_root_ca_key=''"
if [ $? -ne 0 ]; then
log "Failed to run ansible playbook!"
exit 1
fi
}
log "${0} invoked with from_release = ${FROM_REL} to_release = ${TO_REL} action = ${ACTION}"
if [ ${FROM_REL} == "21.05" -a ${ACTION} == "activate" ]; then
enable_separate_etcd_ca
else
log "Only execute this upgrade code when the activate action is being done and the from release is 21.05!"
fi
exit 0

View File

@ -1,148 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This script will run during the upgrade activation step after all nodes have
# been upgraded.
#
# This will set the required_osd_release to 'nautilus' and enable the straw2
# bucket algorithm. 'straw2' has improvements over the previous 'straw'
# algorithm. For more information see:
# https://docs.ceph.com/en/latest/rados/operations/crush-map/#hammer-crush-v4
#
# This script can be removed in the release that follows 21.12.
import json
import subprocess
import sys
from controllerconfig.common import log
LOG = log.get_logger(__name__)
def main():
action = None
from_release = None
to_release = None
arg = 1
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:
print("Invalid option %s." % sys.argv[arg])
return 1
arg += 1
log.configure()
LOG.debug("%s invoked with from_release = %s to_release = %s action = %s"
% (sys.argv[0], from_release, to_release, action))
if from_release == "21.05" and action == "activate":
try:
upgrade_ceph()
except Exception as e:
LOG.exception('Upgrade failed due to the following exception: %s'
% e)
return 1
def upgrade_ceph():
if not is_ceph_configured():
LOG.info("Ceph backend absent. "
"No further upgrade actions are required."
)
return
else:
LOG.info("Ceph backend present. Verifying Ceph upgrade to Nautilus is "
"complete.")
osd_release = get_required_osd_release()
straw2_enabled = is_straw2_enabled()
if osd_release != 'nautilus' or not straw2_enabled:
LOG.info("Completing upgrade to Ceph Nautilus...")
# Setting to nautilus release first is mandatory
if osd_release != 'nautilus':
set_required_osd_release()
if not straw2_enabled:
enable_straw2()
LOG.info("Upgrade complete to Ceph Nautilus")
else:
LOG.info("No additional Ceph upgraded actions required")
def is_ceph_configured():
# This command was used because it was not possible to connect to
# the sysinv database using the psycopg2 module when in 'activate'
# action
command = ("sudo -u postgres psql -U postgres -d sysinv -t -A -q -c "
"\"SELECT count(*) FROM storage_backend "
"where backend='ceph' AND name='ceph-store';\"")
out = exec_command(command)
return out.strip() == "1"
def get_required_osd_release():
command = "ceph osd dump -f json"
out = exec_ceph_command(command)
json_out = json.loads(out)
return json_out.get('require_osd_release')
def is_straw2_enabled():
command = "ceph osd crush dump -f json"
out = exec_ceph_command(command)
json_out = json.loads(out)
algs = [b['alg'] for b in json_out.get('buckets')]
return algs.count('straw') == 0
def set_required_osd_release():
LOG.info("Set 'nautilus' for require_osd_release...")
command = "ceph osd require-osd-release nautilus"
exec_ceph_command(command)
release = get_required_osd_release()
if release != 'nautilus':
raise Exception("Could not set nautilus release 'require_osd_release'")
def enable_straw2():
LOG.info("Enabling straw2 bucket algorithm...")
command = "ceph osd crush set-all-straw-buckets-to-straw2"
exec_ceph_command(command)
if not is_straw2_enabled():
raise Exception("Could not enable straw2 bucket algorithm")
def exec_command(command):
LOG.debug("Running command: %s" % command)
process = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
stdout, stderr = process.communicate()
rc = process.returncode
if rc != 0:
raise Exception("Failed to run command: %s | rc=%s | stdout: %s"
" | stderr: %s" %
(command, rc, stdout, stderr))
return stdout
def exec_ceph_command(command):
command = 'timeout 60s %s' % command
return exec_command(command)
if __name__ == "__main__":
sys.exit(main())