177 lines
5.9 KiB
Python
Executable File
177 lines
5.9 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright (c) 2023 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import yaml
|
|
|
|
from controllerconfig.common import log
|
|
|
|
|
|
LOG = log.get_logger(__name__)
|
|
|
|
|
|
def get_list_of_keys(from_release, to_release):
|
|
keys = {"static": [], "secure_static": []}
|
|
if from_release == "22.12":
|
|
keys["secure_static"] = ["usm::keystone::auth::password",
|
|
"usm::keystone::authtoken::password",
|
|
"usm::api::keystone_password"]
|
|
keys["static"] = ["usm::api::keystone_user"]
|
|
|
|
return keys
|
|
|
|
|
|
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]
|
|
elif arg == 4:
|
|
# optional port parameter for USM upgrade
|
|
# port = sys.argv[arg]
|
|
pass
|
|
else:
|
|
print("Invalid option %s." % sys.argv[arg])
|
|
return 1
|
|
arg += 1
|
|
|
|
log.configure()
|
|
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":
|
|
try:
|
|
res = do_update(from_release, to_release)
|
|
except Exception:
|
|
LOG.exception("Updating static hieradata action failed")
|
|
res = 1
|
|
|
|
return res
|
|
|
|
|
|
def do_update(from_release, to_release):
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
_do_update_under_temp(from_release, to_release, tempdir)
|
|
|
|
|
|
def _do_update_under_temp(from_release, to_release, tempdir):
|
|
SYSTEM_STATIC_FILE = "static.yaml"
|
|
SECURE_STATIC_FILE = "secure_static.yaml"
|
|
HIERADATA_PATH = "/opt/platform/puppet/%s/hieradata"
|
|
|
|
# copy static hieradata yaml files to tempdir
|
|
system_static_file = \
|
|
os.path.join(HIERADATA_PATH % to_release, SYSTEM_STATIC_FILE)
|
|
secure_static_file = \
|
|
os.path.join(HIERADATA_PATH % to_release, SECURE_STATIC_FILE)
|
|
tmp_system_static_file = os.path.join(tempdir, SYSTEM_STATIC_FILE)
|
|
tmp_secure_static_file = os.path.join(tempdir, SECURE_STATIC_FILE)
|
|
files_to_copy = {system_static_file: tmp_system_static_file,
|
|
secure_static_file: tmp_secure_static_file}
|
|
|
|
for src in files_to_copy:
|
|
dest = files_to_copy[src]
|
|
try:
|
|
shutil.copyfile(src, dest)
|
|
except IOError as e:
|
|
LOG.error("Failed copying file %s to %s. Error %s", src, dest, e)
|
|
raise
|
|
|
|
# generate static config to /opt/platform/puppet/<ver>/hieradata
|
|
cmd = ["sysinv-puppet", "create-static-config"]
|
|
process = subprocess.Popen(
|
|
cmd,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
universal_newlines=True)
|
|
|
|
out, err = process.communicate()
|
|
if process.returncode != 0:
|
|
msg = "Failed to generate static config. Command output: \n%s" % err
|
|
LOG.error(msg)
|
|
raise Exception(msg)
|
|
|
|
src_file_mapping = {"static": system_static_file,
|
|
"secure_static": secure_static_file}
|
|
|
|
tmp_file_mapping = {"static": tmp_system_static_file,
|
|
"secure_static": tmp_secure_static_file}
|
|
list_of_keys = get_list_of_keys(from_release, to_release)
|
|
|
|
# find the new generated static data and update the static hieradata
|
|
# from previous release
|
|
for tag in list_of_keys:
|
|
keys = list_of_keys[tag]
|
|
if len(keys) > 0:
|
|
tmp_file = tmp_file_mapping[tag]
|
|
src_file = src_file_mapping[tag]
|
|
# read the key/value from src_file
|
|
# (generated by sysinv-puppet create-static-config)
|
|
# at /opt/platform/puppet/hieradata/<to_release>
|
|
# write the key/value to tmp_file at temp directory
|
|
with open(src_file, "r") as src:
|
|
try:
|
|
src_data = yaml.load(src, Loader=yaml.Loader)
|
|
except Exception as e:
|
|
LOG.error("Failed to load %s. Error %s" % (src_file, e))
|
|
raise
|
|
|
|
with open(tmp_file, "r") as dest:
|
|
try:
|
|
dest_data = yaml.load(dest, Loader=yaml.Loader)
|
|
except Exception as e:
|
|
LOG.error("Failed to load %s. Error %s" % (tmp_file, e))
|
|
raise
|
|
|
|
for key in keys:
|
|
if key in src_data:
|
|
dest_data[key] = src_data[key]
|
|
else:
|
|
LOG.warn("Expect %s generated in %s, but is not found" %
|
|
(key, src_file))
|
|
|
|
with open(tmp_file, "w") as dest:
|
|
try:
|
|
yaml.dump(dest_data, dest, default_flow_style=False)
|
|
except Exception as e:
|
|
LOG.error("Failed to update %s. Error %s" %
|
|
(tmp_file, e))
|
|
raise
|
|
|
|
# copy the updated static hieradata yaml files to hieradata directory
|
|
# of to release
|
|
dest_system_static_file = \
|
|
os.path.join(HIERADATA_PATH % to_release, SYSTEM_STATIC_FILE)
|
|
dest_secure_static_file = \
|
|
os.path.join(HIERADATA_PATH % to_release, SECURE_STATIC_FILE)
|
|
dest_file_mapping = {"static": dest_system_static_file,
|
|
"secure_static": dest_secure_static_file}
|
|
for tag in ["static", "secure_static"]:
|
|
try:
|
|
shutil.copyfile(tmp_file_mapping[tag], dest_file_mapping[tag])
|
|
except Exception as e:
|
|
msg = "Failed to copy file %s to %s. Error %s" % (
|
|
tmp_file_mapping[tag],
|
|
dest_file_mapping[tag],
|
|
e)
|
|
LOG.error(msg)
|
|
raise Exception(msg)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|