Skip to content

Commit

Permalink
Revert Library Singleton, start with the server side isntallation of …
Browse files Browse the repository at this point in the history
…packages
  • Loading branch information
Minkiu committed Dec 12, 2023
1 parent 2a469de commit 903ab76
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 65 deletions.
12 changes: 6 additions & 6 deletions api/addons/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@ async def list_addons(

# TODO: for each version, return the information
# whether it has settings (and don't show the addon in the settings editor if not)
addon_library = AddonLibrary()
active_versions = await addon_library.get_active_versions()
library = AddonLibrary.getinstance()
active_versions = await library.get_active_versions()

for addon_name, addon_version_dict in addon_library.get_available_addons().items():
for addon_name, addon_version_dict in library.get_available_addons().items():
addon_active_versions = active_versions.get(addon_name, {})

if addon_active_versions and addon_active_versions["production"] is not None:
addon = addon_library.addon(addon_name, str(addon_active_versions["production"]))
addon = library.addon(addon_name, str(addon_active_versions["production"]))
else:
latest_version = addon_library.get_latest_version(addon_name)
addon = addon_library.addon(addon_name, str(latest_version.version))
latest_version = library.get_latest_version(addon_name)
addon = library.addon(addon_name, str(latest_version.version))

versions = {}
is_system = False
Expand Down
12 changes: 4 additions & 8 deletions api/addons/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ async def remove_override(
variant: str = "production",
project_name: str | None = None,
):
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, addon_version)) is None:
if (addon := AddonLibrary.addon(addon_name, addon_version)) is None:
raise NotFoundException(f"Addon {addon_name} {addon_version} not found")

# TODO: ensure the path is not a part of a group
Expand Down Expand Up @@ -63,8 +62,7 @@ async def pin_override(
variant: str = "production",
project_name: str | None = None,
):
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, addon_version)) is None:
if (addon := AddonLibrary.addon(addon_name, addon_version)) is None:
raise NotFoundException(f"Addon {addon_name} {addon_version} not found")

if project_name:
Expand Down Expand Up @@ -138,8 +136,7 @@ async def remove_site_override(
user_name: str,
path: list[str],
):
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, addon_version)) is None:
if (addon := AddonLibrary.addon(addon_name, addon_version)) is None:
raise NotFoundException(f"Addon {addon_name} {addon_version} not found")

overrides = await addon.get_project_site_overrides(project_name, user_name, site_id)
Expand Down Expand Up @@ -174,8 +171,7 @@ async def pin_site_override(
user_name: str,
path: list[str],
):
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, addon_version)) is None:
if (addon := AddonLibrary.addon(addon_name, addon_version)) is None:
raise NotFoundException(f"Addon {addon_name} {addon_version} not found")

overrides = await addon.get_project_site_overrides(project_name, user_name, site_id)
Expand Down
15 changes: 5 additions & 10 deletions api/addons/project_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ async def get_addon_project_settings_schema(
site: str | None = Query(None, regex="^[a-z0-9-]+$"),
) -> dict[str, Any]:
"""Return the JSON schema of the addon settings."""
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, version)) is None:
if (addon := AddonLibrary.addon(addon_name, version)) is None:
raise NotFoundException(f"Addon {addon_name} {version} not found")

model = addon.get_settings_model()
Expand Down Expand Up @@ -78,8 +77,7 @@ async def get_addon_project_settings(
site: str | None = Query(None, regex="^[a-z0-9-]+$"),
) -> dict[str, Any]:

addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, version)) is None:
if (addon := AddonLibrary.addon(addon_name, version)) is None:
raise NotFoundException(f"Addon {addon_name} {version} not found")

if site:
Expand All @@ -103,8 +101,7 @@ async def get_addon_project_overrides(
variant: str = Query("production"),
site: str | None = Query(None, regex="^[a-z0-9-]+$"),
):
addon_library = AddonLibrary()
addon = addon_library.addon(addon_name, version)
addon = AddonLibrary.addon(addon_name, version)
studio_settings = await addon.get_studio_settings(variant=variant)
if studio_settings is None:
return {}
Expand Down Expand Up @@ -146,8 +143,7 @@ async def set_addon_project_settings(
) -> EmptyResponse:
"""Set the studio overrides of the given addon."""

addon_library = AddonLibrary()
addon = addon_library.addon(addon_name, version)
addon = AddonLibrary.addon(addon_name, version)
model = addon.get_settings_model()
if model is None:
raise BadRequestException(f"Addon {addon_name} has no settings")
Expand Down Expand Up @@ -246,8 +242,7 @@ async def delete_addon_project_overrides(
site: str | None = Query(None, regex="^[a-z0-9-]+$"),
):
# Ensure the addon and the project exist
addon_library = AddonLibrary()
_ = addon_library.addon(addon_name, version)
_ = AddonLibrary.addon(addon_name, version)
_ = await ProjectEntity.load(project_name)

if not site:
Expand Down
11 changes: 5 additions & 6 deletions api/addons/site_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ async def get_addon_site_settings_schema(
user: CurrentUser,
) -> dict[str, Any]:
"""Return the JSON schema of the addon site settings."""
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, version)) is None:
don_library = AddonLibrary()
if (addon := AddonLibrary.addon(addon_name, version)) is None:
raise NotFoundException(f"Addon {addon_name} {version} not found")

model = addon.get_site_settings_model()
Expand Down Expand Up @@ -54,8 +54,7 @@ async def get_addon_site_settings(
site: str = Query(...),
) -> dict[str, Any]:
"""Return the JSON schema of the addon site settings."""
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, version)) is None:
if (addon := AddonLibrary.addon(addon_name, version)) is None:
raise NotFoundException(f"Addon {addon_name} {version} not found")

model = addon.get_site_settings_model()
Expand Down Expand Up @@ -84,8 +83,8 @@ async def set_addon_site_settings(
user: CurrentUser,
site: str = Query(..., title="Site ID", regex="^[a-z0-9-]+$"),
) -> EmptyResponse:
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, version)) is None:
don_library = AddonLibrary()
if (addon := AddonLibrary.addon(addon_name, version)) is None:
raise NotFoundException(f"Addon {addon_name} {version} not found")

model = addon.get_site_settings_model()
Expand Down
15 changes: 5 additions & 10 deletions api/addons/studio_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ async def get_addon_settings_schema(
variant: str = Query("production"),
) -> dict[str, Any]:
"""Return the JSON schema of the addon settings."""
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, addon_version)) is None:
if (addon := AddonLibrary.addon(addon_name, addon_version)) is None:
raise NotFoundException(f"Addon {addon_name} {addon_version} not found")

model = addon.get_settings_model()
Expand Down Expand Up @@ -63,8 +62,7 @@ async def get_addon_studio_settings(
variant: str = Query("production"),
) -> dict[str, Any]:
"""Return the settings (including studio overrides) of the given addon."""
addon_library = AddonLibrary()
if (addon := addon_library.addon(addon_name, addon_version)) is None:
if (addon := AddonLibrary.addon(addon_name, addon_version)) is None:
raise NotFoundException(f"Addon {addon_name} {addon_version} not found")

settings = await addon.get_studio_settings(variant=variant)
Expand All @@ -85,8 +83,7 @@ async def set_addon_studio_settings(

if not user.is_manager:
raise ForbiddenException
addon_library = AddonLibrary()
addon = addon_library.addon(addon_name, addon_version)
addon = AddonLibrary.addon(addon_name, addon_version)
original = await addon.get_studio_settings(variant=variant)
existing = await addon.get_studio_overrides(variant=variant)
model = addon.get_settings_model()
Expand Down Expand Up @@ -142,8 +139,7 @@ async def get_addon_studio_overrides(
):
if not user.is_manager:
raise ForbiddenException
addon_library = AddonLibrary()
addon = addon_library.addon(addon_name, addon_version)
addon = AddonLibrary.addon(addon_name, addon_version)
settings = await addon.get_studio_settings(variant=variant)
if settings is None:
return {}
Expand All @@ -164,8 +160,7 @@ async def delete_addon_studio_overrides(
raise ForbiddenException

# Ensure addon exists
addon_library = AddonLibrary()
_ = addon_library.addon(addon_name, addon_version)
_ = AddonLibrary.addon(addon_name, addon_version)

await Postgres.execute(
"""
Expand Down
2 changes: 1 addition & 1 deletion api/system/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ async def get_sso_options(request: Request) -> list[SSOOption]:
base_url = "http://localhost:5000"

result = []
library = AddonLibrary()
library = AddonLibrary().getinstance()
active_versions = await library.get_active_versions()

for _name, definition in library.items():
Expand Down
2 changes: 1 addition & 1 deletion ayon_server/addons/addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __repr__(self) -> str:
@property
def friendly_name(self) -> str:
"""Return the friendly name of the addon."""
return f"{self.name.capitalize()}"
return f"{self.definition.friendly_name} {self.version}"

async def is_production(self) -> bool:
"""Return True if the addon is in production bundle."""
Expand Down
47 changes: 31 additions & 16 deletions ayon_server/addons/rezlibrary.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ class RezRepo:
_instance = None
rez_repo = ayonconfig.rez_dir

@classmethod
def getinstance(cls) -> "AddonLibrary":
if cls._instance is None:
cls._instance = RezRepo()
return cls._instance

def __init__(self) -> None:
self.restart_requested = False
self.packages = {}
Expand Down Expand Up @@ -47,12 +53,6 @@ def __init__(self) -> None:
logging.info("No addons found for 'ayon_server'")
return

def __new__(cls, *args, **kwargs):
# Make it a Singleton
if not isinstance(cls._instance, cls):
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance

def _create_ayon_server_package(self):
from rez.package_maker import make_package

Expand Down Expand Up @@ -154,13 +154,28 @@ def get_available_addons(self) -> dict[str, dict[str, Package]]:
return self.packages

async def get_active_versions(self) -> dict[str, dict[str, str]]:
active_versions = {}
async for row in Postgres.iterate("SELECT * FROM addon_versions"):
active_versions[row["name"]] = {
"production": row["production_version"],
"staging": row["staging_version"],
production_bundle = await Postgres.fetch(
"SELECT data->'addons' as addons FROM bundles WHERE is_production is true"
)
staging_bundle = await Postgres.fetch(
"SELECT data->'addons' as addons FROM bundles WHERE is_staging is true"
)

res = {}
for addon_name in self.initialized_addons.keys():
res[addon_name] = {
"production": None,
"staging": None,
}
return active_versions

if production_bundle and (addons := production_bundle[0]["addons"]):
if addon_name in addons:
res[addon_name]["production"] = addons[addon_name]
if staging_bundle and (addons := staging_bundle[0]["addons"]):
if addon_name in addons:
res[addon_name]["staging"] = addons[addon_name]

return res

async def get_active_addon(
self,
Expand Down Expand Up @@ -208,10 +223,10 @@ async def initialize_active_addons(self) -> dict[str, BaseServerAddon]:
except NotFoundException as e:
logging.error(e)

def items(self) -> ItemsView[str, BaseServerAddon]:
return self.initialized_addons.items()


@classmethod
def items(cls) -> ItemsView[str, BaseServerAddon]:
instance = cls.getinstance()
return instance.initialized_addons.items()



Expand Down
5 changes: 3 additions & 2 deletions ayon_server/api/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,8 @@ async def startup_event() -> None:

start_event = await dispatch_event("server.started", finished=False)

library = AddonLibrary()

library = AddonLibrary.getinstance()
addon_records = list(AddonLibrary.items())
if library.restart_requested:
logging.warning("Restart requested, skipping addon setup")
await dispatch_event(
Expand Down Expand Up @@ -514,3 +514,4 @@ async def shutdown_event() -> None:
await messaging.shutdown()
await Postgres.shutdown()
logging.info("Server stopped", handlers=None)

13 changes: 8 additions & 5 deletions ayon_server/installer/addons.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ def get_addon_zip_info(path: str) -> tuple[str, str]:
"""Returns the addon name and version from the zip file"""
with zipfile.ZipFile(path, "r") as zip_ref:
names = zip_ref.namelist()
if "manifest.json" not in names:
raise RuntimeError("Addon manifest not found in zip file")
if "package.py" not in names:
raise RuntimeError("Addon package.py not found in zip file")

if "addon/__init__.py" not in names:
raise RuntimeError("Addon __init__.py not found in zip file")
if "rezbuild.py" not in names:
raise RuntimeError("Addon rezbuild.py not found in zip file")

with zip_ref.open("manifest.json") as manifest_file:
if "server/__init__.py" not in names:
raise RuntimeError("Addon __init__.py not found in zip file")

with zip_ref.open("package.py") as pacakge_manifest:
manifest = json.load(manifest_file)

addon_name = manifest.get("addon_name")
Expand Down

0 comments on commit 903ab76

Please sign in to comment.