Skip to content

Commit

Permalink
Add a Registry abstraction
Browse files Browse the repository at this point in the history
This removes a bit of if() condition wars in the BaseContainerImage
and delegates it into its own class hierarchy, which allows to
build a python container for appcol without having to do more
subclasses.
  • Loading branch information
dirkmueller committed Sep 27, 2024
1 parent 406b588 commit b11d643
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 93 deletions.
41 changes: 14 additions & 27 deletions src/bci_build/package/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import jinja2
from packaging import version

from bci_build.registry import RegistryABC
from bci_build.registry import get_registry
from bci_build.templates import DOCKERFILE_TEMPLATE
from bci_build.templates import INFOHEADER_TEMPLATE
from bci_build.templates import KIWI_TEMPLATE
Expand Down Expand Up @@ -552,6 +554,13 @@ class BaseContainerImage(abc.ABC):
#: webui sorting)
_min_release_counter: int | None = None

#: The registry implementation for which this container is being built.
_publish_registry: RegistryABC | None = None

@property
def publish_registry(self):
return self._publish_registry

def __post_init__(self) -> None:
self.pretty_name = self.pretty_name.strip()

Expand All @@ -577,6 +586,8 @@ def __post_init__(self) -> None:
if self.os_version.is_tumbleweed
else "SUSE LLC (https://www.suse.com/)"
)
if not self._publish_registry:
self._publish_registry = get_registry(self)

# limit to tech preview for beta releases
if (
Expand Down Expand Up @@ -673,36 +684,12 @@ def url(self) -> str:
``org.opencontainers.image.url`` label
"""
if self.os_version.is_tumbleweed:
return "https://www.opensuse.org"
if self.os_version.is_ltss:
return "https://www.suse.com/products/long-term-service-pack-support/"

return "https://www.suse.com/products/base-container-images/"

@property
def vendor(self) -> str:
"""The vendor that is put into the ``org.opencontainers.image.vendor``
label
"""
if self.os_version.is_tumbleweed:
return "openSUSE Project"
return "SUSE LLC"

@property
def base_image_registry(self) -> str:
"""The registry where the base image is available on."""
if self.os_version.is_tumbleweed:
return "registry.opensuse.org"
return "registry.suse.com"
return self._publish_registry.url(container=self)

@property
def registry(self) -> str:
"""The registry where the image is available on."""
if self.os_version.is_tumbleweed:
return "registry.opensuse.org"
return "registry.suse.com"
return self._publish_registry.registry

@property
def dockerfile_custom_end(self) -> str:
Expand Down Expand Up @@ -837,7 +824,7 @@ def dockerfile_from_target_ref(self) -> str:
return (
self.from_target_image
if self.os_version.is_tumbleweed
else f"{self.base_image_registry}/{self.from_target_image}"
else f"{self.registry}/{self.from_target_image}"
)

@property
Expand Down
15 changes: 9 additions & 6 deletions src/bci_build/package/apache_tomcat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

from bci_build.package import CAN_BE_LATEST_OS_VERSION
from bci_build.package import DOCKERFILE_RUN
from bci_build.package import ApplicationStackContainer
from bci_build.package import OsContainer
from bci_build.package import OsVersion
from bci_build.package import Package
from bci_build.package import PackageType
from bci_build.package import Replacement
from bci_build.package import _build_tag_prefix

from .appcollection import ApplicationCollectionContainer
from bci_build.registry import ApplicationCollectionRegistry

# last version needs to be the newest
_TOMCAT_VERSIONS: list[str] = ["9", "10.1"]
Expand Down Expand Up @@ -50,11 +50,14 @@ def _get_sac_supported_until(


TOMCAT_CONTAINERS = [
ApplicationCollectionContainer(
ApplicationStackContainer(
name="apache-tomcat",
package_name=f"apache-tomcat-{tomcat_ver.partition('.')[0]}-java-{jre_version}-image"
if os_version.is_tumbleweed
else f"sac-apache-tomcat-{tomcat_ver.partition('.')[0]}-java{jre_version}-image",
package_name=(
f"apache-tomcat-{tomcat_ver.partition('.')[0]}-java-{jre_version}-image"
if os_version.is_tumbleweed
else f"sac-apache-tomcat-{tomcat_ver.partition('.')[0]}-java{jre_version}-image"
),
_publish_registry=ApplicationCollectionRegistry(),
pretty_name="Apache Tomcat",
custom_description=(
"Apache Tomcat is a free and open-source implementation of the Jakarta Servlet, "
Expand Down
53 changes: 0 additions & 53 deletions src/bci_build/package/appcollection.py

This file was deleted.

2 changes: 1 addition & 1 deletion src/bci_build/package/dotnet-aspnet/README.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ and it is optimized for running ASP.NET Core applications in production.
To compile and deploy an application, copy the sources and build the binary:

```Dockerfile
FROM registry.suse.com/bci/dotnet-sdk:{{ image.tag_version }} AS build
FROM {{ image.registry }}/bci/dotnet-sdk:{{ image.tag_version }} AS build
WORKDIR /source

# copy csproj and restore as distinct layers
Expand Down
9 changes: 6 additions & 3 deletions src/bci_build/package/postfix.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
from bci_build.package import ALL_NONBASE_OS_VERSIONS
from bci_build.package import CAN_BE_LATEST_OS_VERSION
from bci_build.package import DOCKERFILE_RUN
from bci_build.package import ApplicationStackContainer
from bci_build.package import OsVersion
from bci_build.package import ParseVersion
from bci_build.package import Replacement
from bci_build.package import SupportLevel

from .appcollection import ApplicationCollectionContainer
from bci_build.registry import ApplicationCollectionRegistry

_POSTFIX_FILES = {}
for filename in (
Expand All @@ -34,9 +34,12 @@


POSTFIX_CONTAINERS = [
ApplicationCollectionContainer(
ApplicationStackContainer(
name="postfix",
package_name=None if os_version.is_tumbleweed else "sac-postfix-image",
_publish_registry=None
if os_version.is_tumbleweed
else ApplicationCollectionRegistry(),
pretty_name="Postfix",
custom_description="Postfix container is fast and secure mail server, {based_on_container}.",
os_version=os_version,
Expand Down
4 changes: 4 additions & 0 deletions src/bci_build/package/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from bci_build.package import OsVersion
from bci_build.package import Replacement
from bci_build.package import SupportLevel
from bci_build.registry import ApplicationCollectionRegistry

_PYTHON_VERSIONS = Literal["3.6", "3.9", "3.10", "3.11", "3.12"]

Expand Down Expand Up @@ -112,6 +113,9 @@ def _get_python_kwargs(py3_ver: _PYTHON_VERSIONS, os_version: OsVersion):
PythonDevelopmentContainer(
**_get_python_kwargs("3.9", os_version),
package_name="python-3.9-image",
_publish_registry=(
None if os_version.is_tumbleweed else ApplicationCollectionRegistry()
),
)
for os_version in (OsVersion.SP6,)
)
Expand Down
60 changes: 60 additions & 0 deletions src/bci_build/registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Registry classes for container images."""

import dataclasses
from abc import ABC
from abc import abstractmethod
from dataclasses import dataclass


@dataclass(frozen=True, kw_only=True)
class RegistryABC(ABC):
"""Abstract Base Class for defining Registry specific content."""

_: dataclasses.KW_ONLY
"""The base hostname for this registry instance"""
registry: str
"""The vendor that is put into the ``org.opencontainers.image.vendor`` label"""
vendor: str

@abstractmethod
def url(self, container) -> str:
pass


class ApplicationCollectionRegistry(RegistryABC):
"""Registry for the Rancher Application Collection Distribution Platform."""

def __init__(self):
super().__init__(registry="dp.apps.rancher.io", vendor="SUSE LLC")

def url(self, container) -> str:
return f"https://apps.rancher.io/applications/{container.name}"


class SUSERegistry(RegistryABC):
"""Registry for the SUSE Registry."""

def __init__(self):
super().__init__(registry="registry.suse.com", vendor="SUSE LLC")

def url(self, container) -> str:
if container.os_version.is_ltss:
return "https://www.suse.com/products/long-term-service-pack-support/"
return "https://www.suse.com/products/base-container-images/"


class openSUSERegistry(RegistryABC):
"""Registry for the openSUSE registry."""

def __init__(self):
super().__init__(registry="registry.opensuse.org", vendor="openSUSE Project")

def url(self, container) -> str:
return "https://www.opensuse.org"


def get_registry(container) -> RegistryABC:
"""Return the appropriate registry for the container."""
if container.os_version.is_tumbleweed:
return openSUSERegistry()
return SUSERegistry()
6 changes: 3 additions & 3 deletions src/bci_build/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
LABEL org.opencontainers.image.version="{{ image.oci_version }}"
LABEL org.opencontainers.image.url="{{ image.url }}"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opencontainers.image.vendor="{{ image.vendor }}"
LABEL org.opencontainers.image.vendor="{{ image.publish_registry.vendor }}"
LABEL org.opencontainers.image.source="%SOURCEURL%"
LABEL org.opencontainers.image.ref.name="{{ image.image_ref_name }}"
LABEL org.opensuse.reference="{{ image.reference }}"
Expand Down Expand Up @@ -120,7 +120,7 @@
<image schemaversion="7.4" name="{{ image.uid }}-image" xmlns:suse_label_helper="com.suse.label_helper">
<description type="system">
<author>{{ image.vendor }}</author>
<author>{{ image.publish_registry.vendor }}</author>
<contact>https://www.suse.com/</contact>
<specification>{{ image.title }} Container Image</specification>
</description>
Expand All @@ -145,7 +145,7 @@
<label name="org.opencontainers.image.description" value="{{ image.description }}"/>
<label name="org.opencontainers.image.version" value="{{ image.oci_version }}"/>
<label name="org.opencontainers.image.created" value="%BUILDTIME%"/>
<label name="org.opencontainers.image.vendor" value="{{ image.vendor }}"/>
<label name="org.opencontainers.image.vendor" value="{{ image.publish_registry.vendor }}"/>
<label name="org.opencontainers.image.source" value="%SOURCEURL%"/>
<label name="org.opencontainers.image.url" value="{{ image.url }}"/>
<label name="org.opencontainers.image.ref.name" value="{{ image.image_ref_name }}"/>
Expand Down

0 comments on commit b11d643

Please sign in to comment.