This ensures `isort` is applied to all files in the repo. Change-Id: Ib7ced1c924ef1639542bf0d1a01c5737f6ba43e9
287 lines
8.7 KiB
Python
287 lines
8.7 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (c) 2023 The Regents of the University of California
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met: redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer;
|
|
# redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution;
|
|
# neither the name of the copyright holders nor the names of its
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
from itertools import cycle
|
|
from shutil import get_terminal_size
|
|
from threading import Thread
|
|
from time import sleep
|
|
|
|
from api.create_resources_json import ResourceJsonCreator
|
|
from dotenv import load_dotenv
|
|
from pymongo import MongoClient
|
|
|
|
load_dotenv()
|
|
|
|
# read MONGO_URI from environment variable
|
|
MONGO_URI = os.getenv("MONGO_URI")
|
|
|
|
|
|
class Loader:
|
|
def __init__(self, desc="Loading...", end="Done!", timeout=0.1):
|
|
"""
|
|
A loader-like context manager
|
|
|
|
Args:
|
|
desc (str, optional): The loader's description.
|
|
Defaults to "Loading...".
|
|
end (str, optional): Final print. Defaults to "Done!".
|
|
timeout (float, optional): Sleep time between prints.
|
|
Defaults to 0.1.
|
|
"""
|
|
self.desc = desc
|
|
self.end = end
|
|
self.timeout = timeout
|
|
|
|
self._thread = Thread(target=self._animate, daemon=True)
|
|
self.steps = ["⢿", "⣻", "⣽", "⣾", "⣷", "⣯", "⣟", "⡿"]
|
|
self.done = False
|
|
|
|
def start(self):
|
|
self._thread.start()
|
|
return self
|
|
|
|
def _animate(self):
|
|
for c in cycle(self.steps):
|
|
if self.done:
|
|
break
|
|
print(f"\r{self.desc} {c}", flush=True, end="")
|
|
sleep(self.timeout)
|
|
|
|
def __enter__(self):
|
|
self.start()
|
|
|
|
def stop(self):
|
|
self.done = True
|
|
cols = get_terminal_size((80, 20)).columns
|
|
print("\r" + " " * cols, end="", flush=True)
|
|
print(f"\r{self.end}", flush=True)
|
|
|
|
def __exit__(self, exc_type, exc_value, tb):
|
|
# handle exceptions with those variables ^
|
|
self.stop()
|
|
|
|
|
|
def get_database(collection="versions_test", uri=MONGO_URI, db="gem5-vision"):
|
|
"""
|
|
Retrieves the MongoDB database for gem5-vision.
|
|
"""
|
|
CONNECTION_STRING = uri
|
|
try:
|
|
client = MongoClient(CONNECTION_STRING)
|
|
client.server_info()
|
|
except:
|
|
print("\nCould not connect to MongoDB")
|
|
exit(1)
|
|
return client[db][collection]
|
|
|
|
|
|
collection = None
|
|
|
|
|
|
def cli():
|
|
parser = argparse.ArgumentParser(
|
|
description="CLI for gem5-resources.",
|
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
)
|
|
parser.add_argument(
|
|
"-u",
|
|
"--uri",
|
|
help="The URI of the MongoDB database.",
|
|
type=str,
|
|
default=MONGO_URI,
|
|
)
|
|
parser.add_argument(
|
|
"-d",
|
|
"--database",
|
|
help="The MongoDB database to use.",
|
|
type=str,
|
|
default="gem5-vision",
|
|
)
|
|
parser.add_argument(
|
|
"-c",
|
|
"--collection",
|
|
help="The MongoDB collection to use.",
|
|
type=str,
|
|
default="versions_test",
|
|
)
|
|
|
|
subparsers = parser.add_subparsers(
|
|
help="The command to run.", dest="command", required=True
|
|
)
|
|
|
|
parser_get_resource = subparsers.add_parser(
|
|
"get_resource",
|
|
help=(
|
|
"Retrieves a resource from the collection based on the given ID."
|
|
"\n if a resource version is provided, it will retrieve the "
|
|
"resource with the given ID and version."
|
|
),
|
|
)
|
|
req_group = parser_get_resource.add_argument_group(
|
|
title="required arguments"
|
|
)
|
|
req_group.add_argument(
|
|
"-i",
|
|
"--id",
|
|
help="The ID of the resource to retrieve.",
|
|
type=str,
|
|
required=True,
|
|
)
|
|
parser_get_resource.add_argument(
|
|
"-v",
|
|
"--version",
|
|
help="The version of the resource to retrieve.",
|
|
type=str,
|
|
required=False,
|
|
)
|
|
parser_get_resource.set_defaults(func=get_resource)
|
|
|
|
parser_backup_mongodb = subparsers.add_parser(
|
|
"backup_mongodb",
|
|
help="Backs up the MongoDB collection to a JSON file.",
|
|
)
|
|
req_group = parser_backup_mongodb.add_argument_group(
|
|
title="required arguments"
|
|
)
|
|
req_group.add_argument(
|
|
"-f",
|
|
"--file",
|
|
help="The JSON file to back up the MongoDB collection to.",
|
|
type=str,
|
|
required=True,
|
|
)
|
|
parser_backup_mongodb.set_defaults(func=backup_mongodb)
|
|
|
|
parser_update_mongodb = subparsers.add_parser(
|
|
"restore_backup",
|
|
help="Restores a backup of the MongoDB collection from a JSON file.",
|
|
)
|
|
req_group = parser_update_mongodb.add_argument_group(
|
|
title="required arguments"
|
|
)
|
|
req_group.add_argument(
|
|
"-f",
|
|
"--file",
|
|
help="The JSON file to restore the MongoDB collection from.",
|
|
type=str,
|
|
)
|
|
parser_update_mongodb.set_defaults(func=restore_backup)
|
|
|
|
parser_create_resources_json = subparsers.add_parser(
|
|
"create_resources_json",
|
|
help="Creates a JSON file of all the resources in the collection.",
|
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
)
|
|
parser_create_resources_json.add_argument(
|
|
"-v",
|
|
"--version",
|
|
help="The version of the resources to create the JSON file for.",
|
|
type=str,
|
|
default="dev",
|
|
)
|
|
parser_create_resources_json.add_argument(
|
|
"-o",
|
|
"--output",
|
|
help="The JSON file to create.",
|
|
type=str,
|
|
default="resources.json",
|
|
)
|
|
parser_create_resources_json.add_argument(
|
|
"-s",
|
|
"--source",
|
|
help="The path to the gem5 source code.",
|
|
type=str,
|
|
default="",
|
|
)
|
|
parser_create_resources_json.set_defaults(func=create_resources_json)
|
|
|
|
args = parser.parse_args()
|
|
if args.collection:
|
|
global collection
|
|
with Loader("Connecting to MongoDB...", end="Connected to MongoDB"):
|
|
collection = get_database(args.collection, args.uri, args.database)
|
|
args.func(args)
|
|
|
|
|
|
def get_resource(args):
|
|
# set the end after the loader is created
|
|
loader = Loader("Retrieving resource...").start()
|
|
resource = None
|
|
if args.version:
|
|
resource = collection.find_one(
|
|
{"id": args.id, "resource_version": args.version}, {"_id": 0}
|
|
)
|
|
else:
|
|
resource = collection.find({"id": args.id}, {"_id": 0})
|
|
resource = list(resource)
|
|
if resource:
|
|
loader.end = json.dumps(resource, indent=4)
|
|
else:
|
|
loader.end = "Resource not found"
|
|
|
|
loader.stop()
|
|
|
|
|
|
def backup_mongodb(args):
|
|
"""
|
|
Backs up the MongoDB collection to a JSON file.
|
|
|
|
:param file: The JSON file to back up the MongoDB collection to.
|
|
"""
|
|
with Loader(
|
|
"Backing up the database...",
|
|
end="Backed up the database to " + args.file,
|
|
):
|
|
# get all the data from the collection
|
|
resources = collection.find({}, {"_id": 0})
|
|
# write to resources.json
|
|
with open(args.file, "w") as f:
|
|
json.dump(list(resources), f, indent=4)
|
|
|
|
|
|
def restore_backup(args):
|
|
with Loader("Restoring backup...", end="Updated the database\n"):
|
|
with open(args.file) as f:
|
|
resources = json.load(f)
|
|
# clear the collection
|
|
collection.delete_many({})
|
|
# push the new data
|
|
collection.insert_many(resources)
|
|
|
|
|
|
def create_resources_json(args):
|
|
with Loader("Creating resources JSON...", end="Created " + args.output):
|
|
creator = ResourceJsonCreator()
|
|
creator.create_json(args.version, args.source, args.output)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
cli()
|