Skip to content

Commit

Permalink
ContainerFamily class added
Browse files Browse the repository at this point in the history
  • Loading branch information
rcmadhankumar committed Jan 15, 2025
1 parent 1b8328d commit c3d28ef
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 64 deletions.
50 changes: 0 additions & 50 deletions src/bci_build/containercrate.py

This file was deleted.

93 changes: 89 additions & 4 deletions src/bci_build/package/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from dataclasses import field
from pathlib import Path
from typing import Literal
from typing import Sequence
from typing import overload

import jinja2
Expand All @@ -22,7 +23,6 @@
from bci_build.container_attributes import PackageType
from bci_build.container_attributes import ReleaseStage
from bci_build.container_attributes import SupportLevel
from bci_build.containercrate import ContainerCrate
from bci_build.os_version import ALL_OS_LTSS_VERSIONS
from bci_build.os_version import RELEASED_OS_VERSIONS
from bci_build.os_version import OsVersion
Expand Down Expand Up @@ -209,7 +209,7 @@ class BaseContainerImage(abc.ABC):
build_flavor: str | None = None

#: create that this container is part of
crate: ContainerCrate = None
family: ContainerFamily = None

#: Add any replacements via `obs-service-replace_using_package_version
#: <https://github.com/openSUSE/obs-service-replace_using_package_version>`_
Expand Down Expand Up @@ -1108,11 +1108,17 @@ async def write_file_to_dest(fname: str, contents: str | bytes) -> None:

if self.build_flavor:
dfile = "Dockerfile"
tasks.append(write_file_to_dest(dfile, self.crate.default_dockerfile(self)))
tasks.append(
write_file_to_dest(
dfile, self.family.get_default_dockerfile_content(self)
)
)
files.append(dfile)

mname = "_multibuild"
tasks.append(write_file_to_dest(mname, self.crate.multibuild(self)))
tasks.append(
write_file_to_dest(mname, self.family.get_multibuild_file_content(self))
)
files.append(mname)

tasks.append(
Expand Down Expand Up @@ -1435,6 +1441,85 @@ def prepare_template(self) -> None:
pass


class ContainerFamily:
"""ContainerFamily is grouping multiple containers build flavors.
This provides package-central functions like generating _service and
_multibuild files, checking version_uid
"""

def __init__(
self,
containers: Sequence[BaseContainerImage],
):
# Assign the family for every container build flavor based on os version and package name
# Sample family structure:
# {
# (OsVersion.TumbleWeed, "test-package-name"): {"flavor1", "flavor2"}
# }
self._container_families: dict[tuple, set] = {}
for container in containers:
if container.build_flavor:
self._container_families.setdefault(
(container.os_version, container.package_name), set()
).add(container.build_flavor)

for container in containers:
if container.family is not None:
raise ValueError("Container is already part of a ContainerFamily")
container.family = self

def get_all_build_flavors(
self,
container: BaseContainerImage,
) -> list[str]:
"""Return all available build flavors for this container in based on its family"""
return sorted(
self._container_families.get(
(container.os_version, container.package_name), [""]
)
)

def get_default_dockerfile_content(
self,
container: BaseContainerImage,
) -> str:
buildrelease: str = ""
if container.build_release:
buildrelease = f"\n#!BuildVersion: workaround-for-an-obs-bug\n#!BuildRelease: {container.build_release}"
"""Return a default Dockerfile to disable build on default flavor."""
return f"""#!ExclusiveArch: do-not-build
#!ForceMultiVersion{buildrelease}
# For this container we only build the Dockerfile.$flavor builds.
"""

def get_multibuild_file_content(
self,
container: BaseContainerImage,
) -> str:
"""Return the _multibuild file string to write for this container based on its family."""
if not self.check_version_in_uid(container):
return ""

flavors: str = "\n".join(
" " * 4 + f"<package>{pkg}</package>"
for pkg in self.get_all_build_flavors(container)
)
return f"<multibuild>\n{flavors}\n</multibuild>"

def check_version_in_uid(
self,
container: BaseContainerImage,
) -> bool:
"""check if version_in_uid is set to False if a container has more than one flavour"""
if len(self.get_all_build_flavors(container)) > 1 and getattr(
container, "version_in_uid", False
):
return False
return True


def generate_disk_size_constraints(size_gb: int) -> str:
"""Creates the contents of a :file:`_constraints` file for OBS to require
workers with at least ``size_gb`` GB of disk space.
Expand Down
4 changes: 2 additions & 2 deletions src/bci_build/package/apache_tomcat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

from bci_build.container_attributes import TCP
from bci_build.container_attributes import PackageType
from bci_build.containercrate import ContainerCrate
from bci_build.os_version import CAN_BE_LATEST_OS_VERSION
from bci_build.os_version import OsVersion
from bci_build.package import DOCKERFILE_RUN
from bci_build.package import ApplicationStackContainer
from bci_build.package import ContainerFamily
from bci_build.package import OsContainer
from bci_build.package import Package
from bci_build.package import Replacement
Expand Down Expand Up @@ -150,4 +150,4 @@ def _get_java_packages(jre_major: int) -> list[str]:
)
]

TOMCAT_CRATE = ContainerCrate(TOMCAT_CONTAINERS)
TOMCAT_FAMILIES = ContainerFamily(TOMCAT_CONTAINERS)
4 changes: 2 additions & 2 deletions src/bci_build/package/package_versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"5": "2.35",
"6": "2.43",
"7": "2.43",
"Tumbleweed": "2.47",
"Tumbleweed": "2.48",
"version_format": "minor"
},
"helm": {
Expand Down Expand Up @@ -54,7 +54,7 @@
},
"spack": {
"6": "0.21.3",
"7": "0.21.3",
"7": "0.23.0",
"Tumbleweed": "0.23.0"
},
"valkey": {
Expand Down
4 changes: 2 additions & 2 deletions src/bci_build/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@
<service mode="buildtime" name="{{ image.build_recipe_type }}_label_helper"/>
<service mode="buildtime" name="kiwi_metainfo_helper"/>
{%- set all_build_flavors = [""] %}
{%- if image.crate and image.build_flavor %}
{%- set all_build_flavors = image.crate.all_build_flavors(image) %}
{%- if image.family and image.build_flavor %}
{%- set all_build_flavors = image.family.get_all_build_flavors(image) %}
{%- endif %}
{%- for flavor in all_build_flavors %}
{%- for replacement in image.replacements_via_service %}
Expand Down
5 changes: 3 additions & 2 deletions tests/test_crate.py → tests/test_container_family.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from bci_build.container_attributes import BuildType
from bci_build.containercrate import ContainerCrate
from bci_build.os_version import OsVersion
from bci_build.package import ContainerFamily
from bci_build.package import DevelopmentContainer

_BASE_KWARGS = {
Expand All @@ -19,11 +19,12 @@ def test_multibuild_with_multi_flavor_docker():
**_BASE_KWARGS,
build_recipe_type=BuildType.DOCKER,
build_flavor=flavor,
version_in_uid=False,
)
for flavor in ("flavor1", "flavor2")
]
assert (
ContainerCrate(containers).multibuild(containers[0])
ContainerFamily(containers).get_multibuild_file_content(containers[0])
== """<multibuild>
<package>flavor1</package>
<package>flavor2</package>
Expand Down
4 changes: 2 additions & 2 deletions tests/test_service.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import pytest

from bci_build.container_attributes import BuildType
from bci_build.containercrate import ContainerCrate
from bci_build.os_version import OsVersion
from bci_build.package import ContainerFamily
from bci_build.package import DevelopmentContainer
from bci_build.package import ParseVersion
from bci_build.package import Replacement
Expand Down Expand Up @@ -181,7 +181,7 @@ def test_service_with_multi_flavor_docker():
)
for flavor in ("flavor1", "flavor2")
]
ContainerCrate(containers)
ContainerFamily(containers)

assert (
SERVICE_TEMPLATE.render(
Expand Down

0 comments on commit c3d28ef

Please sign in to comment.