Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CASMTRIAGE-6953: IMS import tool: More accurately determine IMS data file paths #5373

Merged
merged 1 commit into from
Sep 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 48 additions & 14 deletions scripts/operations/configuration/update_ims_data_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# MIT License
#
# (C) Copyright 2023 Hewlett Packard Enterprise Development LP
# (C) Copyright 2023-2024 Hewlett Packard Enterprise Development LP
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -39,39 +39,66 @@
# target for this update script)
ImsPodDataDir = os.path.join("/", "var", "ims", "data")

# Location of IMS app.py file with names of IMS data files in it
ImsAppPyPath = os.path.join("/", "app", "src", "server", "app.py")

# IMS data files will be named in one of two formats:
# v#_<type>.json (e.g. v2_recipes.json)
# or
# v#.#_<type>.json (e.g. v3.1_recipes.json)
ImsDataTypeRe = {
data_type: re.compile(f"^v[1-9][0-9]*(?:[.][1-9][0-9]*)?_{data_type}[.]json$")
BaseImsDataTypePattern = {
data_type: fr"v[1-9][0-9]*(?:[.][1-9][0-9]*)?_{data_type}[.]json"
for data_type in [ 'images', 'public_keys', 'recipes' ]
}

# In the app.py file, they will be surrounded by quotes
ImsDataTypePattern = {
data_type: fr"'{regex}'|\"{regex}\""
for data_type, regex in BaseImsDataTypePattern.items()
}

ImsDataTypeRe = {
data_type: re.compile(regex)
for data_type, regex in ImsDataTypePattern.items()
}


class ImsDataError(Exception):
"""
Base custom exception type for the script
"""

def get_data_file_path(data_type: str) -> str:

def get_data_file_path(data_type: str, ims_app_py_text: str) -> str:
"""
data_type must be 'images', 'public_keys', or 'recipes'
Finds data file for that type in ImsPodDataDir directory and returns its path
Looks up the name for that file in the IMS app Python file
Finds that data file in ImsPodDataDir directory and returns its path
Raises ImsDataError exception if not found or if multiple found
Raises ImsDataError exception if not found (in app.py or in actual directory)
or if multiple found (in app.py)
"""
try:
file_re = ImsDataTypeRe[data_type]
except KeyError as exc:
raise ImsDataError(f"get_data_file_basename: Invalid data_type specified: '{data_type}'") from exc
matching_files = [ file_name for file_name in os.listdir(ImsPodDataDir) if file_re.match(file_name) ]
if len(matching_files) > 1:
raise ImsDataError(f"Multiple {data_type} data files found in directory '{ImsPodDataDir}': "
", ".join(matching_files))
raise ImsDataError(
f"get_data_file_path: Invalid data_type specified: '{data_type}'") from exc
# Strip away surrounding quotes from the names
matching_filenames = [ file_name[1:-1] for file_name in file_re.findall(ims_app_py_text) ]
if len(matching_filenames) > 1:
raise ImsDataError(f"Multiple {data_type} data files found in {ImsAppPyPath}: " +
", ".join(matching_filenames))
try:
return os.path.join(ImsPodDataDir, matching_files[0])
data_file_path = os.path.join(ImsPodDataDir, matching_filenames[0])
except IndexError as exc:
raise ImsDataError(f"No {data_type} data file found in directory '{ImsPodDataDir}'") from exc
raise ImsDataError(
f"No filename found for data type {data_type} in {ImsAppPyPath}") from exc
if os.path.isfile(data_file_path):
return data_file_path
if os.path.exists(data_file_path):
raise ImsDataError(f"Data file exists but is not a regular file: {data_file_path}")
raise ImsDataError(f"Data file does not exist: {data_file_path}")


def main() -> None:
"""
Expand All @@ -81,18 +108,25 @@ def main() -> None:
Exceptions are raised if anything goes wrong.
"""
# Read in the data to be imported
with open(DataFilePath, "rt") as datafile:
loaded_ims_data = json.load(datafile)

# Read in the contents of the app.py file (needed to know the correct names for the IMS data files)
with open(ImsAppPyPath, "rt") as appfile:
ims_app_py_text = appfile.read()

# This just serves as a double check that the JSON file has all of these fields
updated_ims_data = { data_type: loaded_ims_data[data_type] for data_type in ImsDataTypeRe }
ims_output_file = { data_type: get_data_file_path(data_type) for data_type in ImsDataTypeRe }
ims_output_file = { data_type: get_data_file_path(data_type, ims_app_py_text)
for data_type in ImsDataTypeRe }

for data_type, updated_data in updated_ims_data.items():
with open(ims_output_file[data_type], "wt") as outfile:
json.dump(updated_data, outfile)

print("IMS data update successful")


if __name__ == "__main__":
main()