cs-image-system-default-os-plugin 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cs_image_system/default_os_plugin/__init__.py +3 -0
- cs_image_system/default_os_plugin/alpine_os_builder.py +14 -0
- cs_image_system/default_os_plugin/alpine_type.py +38 -0
- cs_image_system/default_os_plugin/apt_type.py +39 -0
- cs_image_system/default_os_plugin/aws_os_source_types.py +19 -0
- cs_image_system/default_os_plugin/debian_os_builder.py +23 -0
- cs_image_system/default_os_plugin/debian_type.py +29 -0
- cs_image_system/default_os_plugin/dnf_type.py +65 -0
- cs_image_system/default_os_plugin/docker_os_source_types.py +35 -0
- cs_image_system/default_os_plugin/fedora_os_builder.py +14 -0
- cs_image_system/default_os_plugin/fedora_type.py +24 -0
- cs_image_system/default_os_plugin/helpers.py +9 -0
- cs_image_system/default_os_plugin/main.py +61 -0
- cs_image_system/default_os_plugin/os__image_bldr_config_builder.py +17 -0
- cs_image_system/default_os_plugin/os_sources.py +26 -0
- cs_image_system/default_os_plugin/rhel_os_builder.py +15 -0
- cs_image_system/default_os_plugin/rhel_type.py +56 -0
- cs_image_system/default_os_plugin/ubuntu_os_builder.py +19 -0
- cs_image_system/default_os_plugin/ubuntu_os_type.py +22 -0
- cs_image_system_default_os_plugin-0.1.1.dist-info/METADATA +643 -0
- cs_image_system_default_os_plugin-0.1.1.dist-info/RECORD +24 -0
- cs_image_system_default_os_plugin-0.1.1.dist-info/WHEEL +4 -0
- cs_image_system_default_os_plugin-0.1.1.dist-info/entry_points.txt +2 -0
- cs_image_system_default_os_plugin-0.1.1.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.basic.builder_base_os import OsBuilderBase
|
|
6
|
+
from .alpine_type import ALPINE_TYPE
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AlpineOsBuilder(OsBuilderBase):
|
|
10
|
+
"""Alpine specific OS builder implementation."""
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def csis_name(cls) -> str:
|
|
14
|
+
return ALPINE_TYPE
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.models.model_config import CSIS_MODEL_CONFIG
|
|
6
|
+
from pydantic.dataclasses import dataclass # stage 23: validation at construction
|
|
7
|
+
|
|
8
|
+
from cs_image_system.base.models.os_builder_model import OsBuilderModel
|
|
9
|
+
|
|
10
|
+
ALPINE_TYPE: str = "alpine"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
14
|
+
class AlpineOsBuilderModel(OsBuilderModel):
|
|
15
|
+
"""Alpine OS/Source configuration data object.
|
|
16
|
+
|
|
17
|
+
Alpine updates via apk against its default repositories. Note: official
|
|
18
|
+
Alpine cloud images ship doas rather than guaranteeing sudo; if a target
|
|
19
|
+
lacks sudo, this command list will need to become config-adjustable —
|
|
20
|
+
sudo is used here for consistency with every other OS type.
|
|
21
|
+
"""
|
|
22
|
+
type = ALPINE_TYPE
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def csis_name(cls) -> str:
|
|
26
|
+
return ALPINE_TYPE
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def get_command_to_update(cls) -> list[str]:
|
|
30
|
+
"""Full package-level update for Alpine (single packer shell script).
|
|
31
|
+
|
|
32
|
+
--available upgrades even when packages must be replaced/downgraded to
|
|
33
|
+
match the repositories — the right semantic for "bring fully current".
|
|
34
|
+
"""
|
|
35
|
+
return [
|
|
36
|
+
"sudo apk update",
|
|
37
|
+
"sudo apk upgrade --available",
|
|
38
|
+
]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.models.os_builder_model import OsBuilderModel
|
|
6
|
+
from cs_image_system.base.models.update_policy import (
|
|
7
|
+
POLICY_FULL,
|
|
8
|
+
POLICY_NONE,
|
|
9
|
+
POLICY_PACKAGES,
|
|
10
|
+
POLICY_SECURITY,
|
|
11
|
+
UpdatePolicy,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AptOsBuilderModel(OsBuilderModel):
|
|
16
|
+
"""Base model for apt-managed OS families (debian, ubuntu)."""
|
|
17
|
+
|
|
18
|
+
def commands_for_policy(self, policy: UpdatePolicy) -> list[str]:
|
|
19
|
+
if policy.policy == POLICY_NONE and not policy.pin:
|
|
20
|
+
return []
|
|
21
|
+
cmds = ["sudo apt-get -o DPkg::Lock::Timeout=600 update"]
|
|
22
|
+
for e in policy.exclude:
|
|
23
|
+
cmds.append(f"sudo apt-mark hold '{e}'")
|
|
24
|
+
if policy.policy == POLICY_SECURITY:
|
|
25
|
+
# only upgrades whose candidate comes from a *-security suite
|
|
26
|
+
cmds.append("sudo apt-get -o DPkg::Lock::Timeout=600 -s dist-upgrade | awk '/^Inst/ && /security/ {print $2}' | xargs -r sudo apt-get -o DPkg::Lock::Timeout=600 install -y --only-upgrade")
|
|
27
|
+
if policy.packages:
|
|
28
|
+
cmds.append("sudo apt-get -o DPkg::Lock::Timeout=600 install -y --only-upgrade " + " ".join(policy.packages))
|
|
29
|
+
elif policy.policy == POLICY_PACKAGES:
|
|
30
|
+
if policy.packages:
|
|
31
|
+
cmds.append("sudo apt-get -o DPkg::Lock::Timeout=600 install -y --only-upgrade " + " ".join(policy.packages))
|
|
32
|
+
elif policy.policy == POLICY_FULL:
|
|
33
|
+
cmds += ["sudo apt-get -o DPkg::Lock::Timeout=600 upgrade -y", "sudo apt-get -o DPkg::Lock::Timeout=600 full-upgrade -y",
|
|
34
|
+
"sudo apt-get -o DPkg::Lock::Timeout=600 autoremove -y", "sudo apt-get -o DPkg::Lock::Timeout=600 autoclean -y"]
|
|
35
|
+
for pkg, ver in policy.pin:
|
|
36
|
+
cmds.append(f"sudo apt-get -o DPkg::Lock::Timeout=600 install -y --allow-downgrades '{pkg}={ver}' && sudo apt-mark hold '{pkg}'")
|
|
37
|
+
for e in policy.exclude:
|
|
38
|
+
cmds.append(f"sudo apt-mark unhold '{e}'")
|
|
39
|
+
return cmds
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# AWS_EBS_SOURCE_TYPE: str = "amazon-ebs"
|
|
8
|
+
# @dataclass(kw_only=True)
|
|
9
|
+
# class AwsEbsSourceConfig(SourceModel):
|
|
10
|
+
# """AWS EBS Source configuration data object."""
|
|
11
|
+
|
|
12
|
+
# # type: str = "aws-ebs"
|
|
13
|
+
# # region: str. Region comes from the cloud config
|
|
14
|
+
# # root-device-type assumed to be "ebs" and virtualization-type
|
|
15
|
+
# # to be "hvm" for this type
|
|
16
|
+
# instance_type: str = DEFAULT
|
|
17
|
+
# owners: list[str] = field(default_factory=list)
|
|
18
|
+
# filters: dict[str, str] = field(default_factory=dict)
|
|
19
|
+
# most_recent: bool = True
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
log = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
from typing import TypeVar
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from .debian_type import DEBIAN_TYPE, DebianOsBuilderModel
|
|
13
|
+
from cs_image_system.base.basic.builder_base_os import OsBuilderBase
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
DEBSOS = TypeVar('DEBSOS', bound=DebianOsBuilderModel)
|
|
17
|
+
class DebianOsBuilder(OsBuilderBase[DEBSOS]):
|
|
18
|
+
"""Ansible-based modification provider implementation."""
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def csis_name(cls) -> str:
|
|
22
|
+
return DEBIAN_TYPE
|
|
23
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from cs_image_system.base.models.model_config import CSIS_MODEL_CONFIG
|
|
7
|
+
from pydantic.dataclasses import dataclass # stage 23: validation at construction
|
|
8
|
+
import logging
|
|
9
|
+
log = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from .apt_type import AptOsBuilderModel
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
DEBIAN_TYPE: str = "debian"
|
|
17
|
+
UBUNTU_TYPE: str = "ubuntu"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
21
|
+
class DebianOsBuilderModel(AptOsBuilderModel):
|
|
22
|
+
"""Some Debian OS/Source configuration data object."""
|
|
23
|
+
type = DEBIAN_TYPE
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def csis_name(cls) -> str:
|
|
27
|
+
return DEBIAN_TYPE
|
|
28
|
+
|
|
29
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.models.model_config import CSIS_MODEL_CONFIG
|
|
6
|
+
from pydantic.dataclasses import dataclass # stage 23: validation at construction
|
|
7
|
+
|
|
8
|
+
from cs_image_system.base.models.os_builder_model import OsBuilderModel
|
|
9
|
+
from cs_image_system.base.models.update_policy import (
|
|
10
|
+
POLICY_FULL,
|
|
11
|
+
POLICY_NONE,
|
|
12
|
+
POLICY_PACKAGES,
|
|
13
|
+
POLICY_SECURITY,
|
|
14
|
+
UpdatePolicy,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
19
|
+
class DnfOsBuilderModel(OsBuilderModel):
|
|
20
|
+
"""dnf-managed families. Subclasses supply ``repo_setup_commands`` (e.g.
|
|
21
|
+
subscription-manager on RHEL); the update policy is realized here
|
|
22
|
+
(EXPLORE "More Targeted Updates?")."""
|
|
23
|
+
|
|
24
|
+
def repo_setup_commands(self) -> list[str]:
|
|
25
|
+
return []
|
|
26
|
+
|
|
27
|
+
def commands_for_policy(self, policy: UpdatePolicy) -> list[str]:
|
|
28
|
+
if policy.policy == POLICY_NONE and not policy.pin:
|
|
29
|
+
return []
|
|
30
|
+
cmds = list(self.repo_setup_commands()) + ["sudo dnf clean all"]
|
|
31
|
+
excl = "".join(f" --exclude={e}" for e in policy.exclude)
|
|
32
|
+
|
|
33
|
+
def retried(cmd: str) -> str:
|
|
34
|
+
# RHUI repos flip their cache path mid-run when the point release
|
|
35
|
+
# moves (found live twice: Errno 2 on a downloaded rpm); a clean
|
|
36
|
+
# retry re-resolves against the new cache
|
|
37
|
+
return f"{cmd} || {{ sudo dnf clean all; {cmd}; }}"
|
|
38
|
+
|
|
39
|
+
def targeted(pkgs: str) -> str:
|
|
40
|
+
# dnf5 (EL10; found live on the first Alma 10 bake) exits 1 on
|
|
41
|
+
# `update <pkg>` when the named package has no pending update
|
|
42
|
+
# ("No packages marked for upgrade") where dnf4 exited 0.
|
|
43
|
+
# check-update keeps stable exit semantics on both (100 =
|
|
44
|
+
# updates exist, 0 = none), so the update runs only behind it;
|
|
45
|
+
# the rc dance keeps the line safe under packer's /bin/sh -e.
|
|
46
|
+
check = f"sudo dnf -q check-update{excl} {pkgs}"
|
|
47
|
+
update = retried(f"sudo dnf -y update{excl} {pkgs}")
|
|
48
|
+
return (f'rc=0; {check} || rc=$?; if [ "$rc" -eq 100 ]; then {update}; '
|
|
49
|
+
f'elif [ "$rc" -ne 0 ]; then exit "$rc"; fi')
|
|
50
|
+
|
|
51
|
+
if policy.policy == POLICY_SECURITY:
|
|
52
|
+
cmds.append(retried(f"sudo dnf -y update --security{excl}"))
|
|
53
|
+
if policy.packages:
|
|
54
|
+
cmds.append(targeted(" ".join(policy.packages)))
|
|
55
|
+
elif policy.policy == POLICY_PACKAGES:
|
|
56
|
+
if policy.packages:
|
|
57
|
+
cmds.append(targeted(" ".join(policy.packages)))
|
|
58
|
+
elif policy.policy == POLICY_FULL:
|
|
59
|
+
cmds += [retried(f"sudo dnf -y upgrade{excl}"),
|
|
60
|
+
"sudo dnf -y autoremove", "sudo dnf -y autoclean"]
|
|
61
|
+
if policy.pin:
|
|
62
|
+
cmds.append("sudo dnf -y install python3-dnf-plugin-versionlock || sudo dnf -y install dnf-plugins-core")
|
|
63
|
+
for pkg, ver in policy.pin:
|
|
64
|
+
cmds.append(f"sudo dnf -y install '{pkg}-{ver}' && sudo dnf versionlock add '{pkg}-{ver}'")
|
|
65
|
+
return cmds
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.models.model_config import CSIS_MODEL_CONFIG
|
|
6
|
+
from pydantic.dataclasses import dataclass # stage 23: validation at construction
|
|
7
|
+
|
|
8
|
+
from .os_sources import SourceModel
|
|
9
|
+
|
|
10
|
+
CONTAINER_SOURCE_TYPE: str = "container"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
14
|
+
class ContainerSourceConfig(SourceModel):
|
|
15
|
+
"""Container Source configuration data object."""
|
|
16
|
+
|
|
17
|
+
tag: str
|
|
18
|
+
version: str = "latest"
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def csis_name(cls) -> str:
|
|
22
|
+
return CONTAINER_SOURCE_TYPE
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
DOCKER_SOURCE_TYPE: str = "docker"
|
|
26
|
+
|
|
27
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
28
|
+
class DockerSourceModel(ContainerSourceConfig):
|
|
29
|
+
"""Docker Source configuration data object."""
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def csis_name(cls) -> str:
|
|
33
|
+
return DOCKER_SOURCE_TYPE
|
|
34
|
+
|
|
35
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.basic.builder_base_os import OsBuilderBase
|
|
6
|
+
from .fedora_type import FEDORA_TYPE
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FedoraOsBuilder(OsBuilderBase):
|
|
10
|
+
"""Fedora specific OS builder implementation."""
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def csis_name(cls) -> str:
|
|
14
|
+
return FEDORA_TYPE
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.models.model_config import CSIS_MODEL_CONFIG
|
|
6
|
+
from pydantic.dataclasses import dataclass # stage 23: validation at construction
|
|
7
|
+
|
|
8
|
+
from .dnf_type import DnfOsBuilderModel
|
|
9
|
+
|
|
10
|
+
FEDORA_TYPE: str = "fedora"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
14
|
+
class FedoraOsBuilderModel(DnfOsBuilderModel):
|
|
15
|
+
"""Fedora OS/Source configuration data object.
|
|
16
|
+
|
|
17
|
+
Unlike RHEL, Fedora needs no subscription-manager repository enablement —
|
|
18
|
+
a package-level update is a plain dnf upgrade against the default repos.
|
|
19
|
+
"""
|
|
20
|
+
type = FEDORA_TYPE
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def csis_name(cls) -> str:
|
|
24
|
+
return FEDORA_TYPE
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from cs_image_system.base.basic.abstract_plugin_metadata import AbstractPluginMetadata
|
|
7
|
+
from cs_image_system.base.models.os_builder_runtime_config import OSBuilderBaseImageBuilderSubconfig
|
|
8
|
+
from cs_image_system.base.protocols.plugin_metadata import PluginMetadataProtocol
|
|
9
|
+
from cs_image_system.default_os_plugin.os__image_bldr_config_builder import DefaultOSImageBuilderConfigBuilder
|
|
10
|
+
from .alpine_os_builder import AlpineOsBuilder
|
|
11
|
+
from .alpine_type import ALPINE_TYPE, AlpineOsBuilderModel
|
|
12
|
+
from .debian_os_builder import DebianOsBuilder
|
|
13
|
+
from .debian_type import DEBIAN_TYPE, DebianOsBuilderModel
|
|
14
|
+
from .fedora_os_builder import FedoraOsBuilder
|
|
15
|
+
from .fedora_type import FEDORA_TYPE, FedoraOsBuilderModel
|
|
16
|
+
from .rhel_type import RHEL_TYPE, RhelOsBuilderModel
|
|
17
|
+
from .rhel_os_builder import RhelOsBuilder
|
|
18
|
+
from .ubuntu_os_builder import UbuntuOsBuilder
|
|
19
|
+
from .ubuntu_os_type import UBUNTU_TYPE, UbuntuOsBuilderModel
|
|
20
|
+
|
|
21
|
+
log = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
class DefaultOsTypes(AbstractPluginMetadata, PluginMetadataProtocol):
|
|
24
|
+
def __init__(self) -> None:
|
|
25
|
+
super().__init__( "1", "3.13",
|
|
26
|
+
{RHEL_TYPE: [
|
|
27
|
+
RhelOsBuilderModel,
|
|
28
|
+
RhelOsBuilder
|
|
29
|
+
],
|
|
30
|
+
UBUNTU_TYPE: [
|
|
31
|
+
UbuntuOsBuilderModel,
|
|
32
|
+
UbuntuOsBuilder
|
|
33
|
+
],
|
|
34
|
+
DEBIAN_TYPE: [
|
|
35
|
+
DebianOsBuilderModel,
|
|
36
|
+
DebianOsBuilder
|
|
37
|
+
],
|
|
38
|
+
FEDORA_TYPE: [
|
|
39
|
+
FedoraOsBuilderModel,
|
|
40
|
+
FedoraOsBuilder
|
|
41
|
+
],
|
|
42
|
+
ALPINE_TYPE: [
|
|
43
|
+
AlpineOsBuilderModel,
|
|
44
|
+
AlpineOsBuilder
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
OSBuilderBaseImageBuilderSubconfig: DefaultOSImageBuilderConfigBuilder,
|
|
49
|
+
DebianOsBuilderModel: DebianOsBuilder,
|
|
50
|
+
RhelOsBuilderModel: RhelOsBuilder,
|
|
51
|
+
UbuntuOsBuilderModel: UbuntuOsBuilder,
|
|
52
|
+
FedoraOsBuilderModel: FedoraOsBuilder,
|
|
53
|
+
AlpineOsBuilderModel: AlpineOsBuilder
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def initialize():
|
|
59
|
+
log.debug("Initializing Default OS Provider")
|
|
60
|
+
return DefaultOsTypes()
|
|
61
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from typing import TypeVar
|
|
6
|
+
|
|
7
|
+
from cs_image_system.base.basic.builder_base_os import OsRuntimeConfigBuilderBase
|
|
8
|
+
from cs_image_system.base.models.os_builder_runtime_config import OSBuilderBaseImageBuilderSubconfig
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
DEFAULT_RTCB = TypeVar('DEFAULT_RTCB', bound=OSBuilderBaseImageBuilderSubconfig)
|
|
12
|
+
class DefaultOSImageBuilderConfigBuilder(OsRuntimeConfigBuilderBase[DEFAULT_RTCB]):
|
|
13
|
+
"""Default OS runtime config builder implementation."""
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def csis_name(cls) -> str:
|
|
17
|
+
return "default_os_runtime_config_builder"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from dataclasses import field
|
|
6
|
+
from cs_image_system.base.models.model_config import CSIS_MODEL_CONFIG
|
|
7
|
+
from pydantic.dataclasses import dataclass # stage 23: validation at construction
|
|
8
|
+
from typing import Any
|
|
9
|
+
from cs_image_system.base.constants import VCT
|
|
10
|
+
from cs_image_system.base.helpers.field_helpers import fk_field
|
|
11
|
+
from cs_image_system.base.models.builder_model import NameTyped
|
|
12
|
+
from cs_image_system.base.protocols.plugin_metadata import PluginArtifactProtocol
|
|
13
|
+
|
|
14
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
15
|
+
class SourceModel(NameTyped, PluginArtifactProtocol):
|
|
16
|
+
"""Source configuration data object."""
|
|
17
|
+
runtime: str = fk_field(target=VCT.RUNTIME_BUILDER_MODEL, metadata={
|
|
18
|
+
"description": "The runtime-builder this config uses",
|
|
19
|
+
"required": True,
|
|
20
|
+
})
|
|
21
|
+
config: dict[str, Any] = field(default_factory=dict)
|
|
22
|
+
# catchall: CatchAll
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def csis_classifier(cls) -> VCT:
|
|
26
|
+
return VCT.SOURCE_MODEL_MODEL
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.basic.builder_base_os import OsBuilderBase
|
|
6
|
+
from .rhel_type import RHEL_TYPE
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# @registry.register_class_to_type_and_key(type_=OS_BUILDER, key=RHEL_TYPE)
|
|
10
|
+
class RhelOsBuilder(OsBuilderBase):
|
|
11
|
+
"""RHEL 8 specific Ansible-based modification provider implementation."""
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def csis_name(cls) -> str:
|
|
15
|
+
return RHEL_TYPE
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.models.model_config import CSIS_MODEL_CONFIG
|
|
6
|
+
from pydantic.dataclasses import dataclass # stage 23: validation at construction
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from .dnf_type import DnfOsBuilderModel
|
|
13
|
+
|
|
14
|
+
RHEL_TYPE:str = "rhel"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
18
|
+
class RhelOsBuilderModel(DnfOsBuilderModel):
|
|
19
|
+
"""RHEL 8 OS/Source configuration data object."""
|
|
20
|
+
type = RHEL_TYPE
|
|
21
|
+
subscription_id: str | None = None
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def csis_name(cls) -> str:
|
|
25
|
+
return RHEL_TYPE
|
|
26
|
+
|
|
27
|
+
def __post_init__(self) -> None:
|
|
28
|
+
super().__post_init__()
|
|
29
|
+
# stage 63: checked at load, whatever the update policy (it ran only
|
|
30
|
+
# when update commands were generated, so `policy: none` with an
|
|
31
|
+
# unsupported major was never refused)
|
|
32
|
+
v = self.version()
|
|
33
|
+
if not v:
|
|
34
|
+
raise ValueError(f"Could not determine RHEL version from family_version '{self.family_version}' "
|
|
35
|
+
f"in OS builder {self.name}")
|
|
36
|
+
if v.major not in (8, 9, 10):
|
|
37
|
+
raise ValueError(f"Unsupported RHEL version '{v}' in OS builder {self.name} (supported: 8, 9, 10)")
|
|
38
|
+
|
|
39
|
+
def repo_setup_commands(self) -> list[str]:
|
|
40
|
+
"""Version-aware repository setup (RHEL 8/9/10 enable different repos).
|
|
41
|
+
|
|
42
|
+
Guarded on registration (found live, TODO stage 1: cloud vendor
|
|
43
|
+
RHEL AMIs are pay-as-you-go/RHUI, "This system is not yet
|
|
44
|
+
registered" -- their RHUI repos already serve baseos/appstream and
|
|
45
|
+
security metadata, so on an unregistered system this is a no-op)."""
|
|
46
|
+
v = self.version()
|
|
47
|
+
assert v is not None, "checked at load (__post_init__)"
|
|
48
|
+
repos = " ".join(f"--enable='rhel-{v.major}-for-x86_64-{r}-rpms'" for r in ("baseos", "appstream")) + f" --enable='codeready-builder-for-rhel-{v.major}-x86_64-rpms'"
|
|
49
|
+
return [
|
|
50
|
+
"# subscription-managed systems get their repos enabled; RHUI/PAYG images skip",
|
|
51
|
+
("if sudo subscription-manager identity >/dev/null 2>&1; then "
|
|
52
|
+
"sudo subscription-manager refresh; "
|
|
53
|
+
"sudo subscription-manager repos --disable='*'; "
|
|
54
|
+
f"sudo subscription-manager repos {repos}; "
|
|
55
|
+
"else echo 'not subscription-registered (RHUI image): using vendor repos as-is'; fi"),
|
|
56
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from typing import TypeVar
|
|
6
|
+
|
|
7
|
+
from cs_image_system.base.basic.builder_base_os import OsBuilderBase
|
|
8
|
+
from .ubuntu_os_type import UbuntuOsBuilderModel, UBUNTU_TYPE
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
UBUOS = TypeVar('UBUOS', bound=UbuntuOsBuilderModel)
|
|
13
|
+
# @registry.register_class_to_type_and_key(type_=OS_BUILDER, key=UBUNTU_TYPE)
|
|
14
|
+
class UbuntuOsBuilder(OsBuilderBase[UBUOS]):
|
|
15
|
+
"""Ansible-based modification provider implementation."""
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def csis_name(cls) -> str:
|
|
19
|
+
return UBUNTU_TYPE
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mykel Alvis <mykelalvis@infrastructurebuilder.org>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from cs_image_system.base.models.model_config import CSIS_MODEL_CONFIG
|
|
6
|
+
from pydantic.dataclasses import dataclass # stage 23: validation at construction
|
|
7
|
+
|
|
8
|
+
from cs_image_system.default_os_plugin.apt_type import AptOsBuilderModel
|
|
9
|
+
|
|
10
|
+
UBUNTU_TYPE: str = "ubuntu"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(kw_only=True, config=CSIS_MODEL_CONFIG)
|
|
14
|
+
# @registry.register_class_to_type_and_key(type_=OS_BUILDER_MODEL, key=UBUNTU_TYPE)
|
|
15
|
+
class UbuntuOsBuilderModel(AptOsBuilderModel):
|
|
16
|
+
"""Some Ubuntu OS/Source configuration data object."""
|
|
17
|
+
type = UBUNTU_TYPE
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def csis_name(cls) -> str:
|
|
21
|
+
return UBUNTU_TYPE
|
|
22
|
+
|