Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion documentation/Installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ For cluster machines, ensure the following requirements are met:
* CentOS Stream 9
* RHEL 8.4, 8.6, 8.7, 8.8, 8.9, 8.10, 9.2, 9.3, 9.4
* Oracle Linux 8.4, 9.2
* RockyLinux 8.6, 8.7, 8.8, 9.2, 9.3, 9.4, 9.5, 9.6
* RockyLinux 8.6, 8.7, 8.8, 9.2, 9.3, 9.4, 9.5, 9.6, 10.1
* Ubuntu 20.04, 22.04.1, 24.04.1

**Note**: Ubuntu 24.04 is supported only with kubernetes versions starting from v1.29.7 and above.
Expand Down
4 changes: 2 additions & 2 deletions kubemarine/core/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ def get_os_family_for_nodes(self, hosts: Iterable[str]) -> str:
The method skips inaccessible nodes unless all nodes are inaccessible.
:return: Detected OS family, possible values: "debian", "rhel8", "rhel9",
"multiple", "unknown", "unsupported", "<undefined>".
"rhel10","multiple", "unknown", "unsupported", "<undefined>".
"""
os_families = {self.get_os_family_for_node(host) for host in hosts}
if os_families == {'<undefined>'}:
Expand All @@ -609,7 +609,7 @@ def get_os_family(self) -> str:
The method skips inaccessible nodes unless all nodes are inaccessible.
:return: Detected OS family, possible values: "debian", "rhel8", "rhel9",
"multiple", "unknown", "unsupported", "<undefined>".
"rhel10","multiple", "unknown", "unsupported", "<undefined>".
"""
return self.nodes['all'].get_nodes_os()

Expand Down
4 changes: 2 additions & 2 deletions kubemarine/core/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ def get_nodes_os(self) -> str:
Returns the detected operating system family for group.
:return: Detected OS family, possible values: "debian", "rhel8", "rhel9",
"multiple", "unknown", "unsupported", "<undefined>".
"rhel10","multiple", "unknown", "unsupported", "<undefined>".
"""
return self.cluster.get_os_family_for_nodes(self.nodes)

Expand All @@ -655,7 +655,7 @@ def get_subgroup_with_os(self: GROUP_SELF, os_families: Union[str, List[str]]) -
os_families = [os_families]

for os_family in os_families:
if os_family not in ['debian', 'rhel8', 'rhel9']:
if os_family not in ['debian', 'rhel8', 'rhel9', 'rhel10']:
raise Exception('Unsupported OS family provided')
hosts = []
for host in self.nodes:
Expand Down
2 changes: 1 addition & 1 deletion kubemarine/modprobe.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def enrich_kernel_modules(cluster: KubernetesCluster) -> None:
The method enrich the list of kernel modules ('services.modprobe') according to OS family
"""

for os_family in ('debian', 'rhel8', 'rhel9'):
for os_family in ('debian', 'rhel8', 'rhel9', 'rhel10'):
# Remove the section for OS families if no node has these OS families.
modprobe_config = cluster.inventory["services"]["modprobe"]
if cluster.nodes['all'].get_subgroup_with_os(os_family).is_empty():
Expand Down
10 changes: 5 additions & 5 deletions kubemarine/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,8 @@ def disable_unattended_upgrade(group: NodeGroup) -> None:


def get_associations_os_family_keys() -> List[str]:
# Generic 'rhel' is removed; use rhel8/rhel9.
return ['debian', 'rhel8', 'rhel9']
# Generic 'rhel' is removed; use rhel8/rhel9/rhel10.
return ['debian', 'rhel8', 'rhel9', 'rhel10']


def get_compatibility_version_key(os_family: str) -> str:
Expand Down Expand Up @@ -536,7 +536,7 @@ def search(self, group: DeferredGroup, package: str, callback: Callback = None)
def get_package_manager(group: AbstractGroup[GROUP_RUN_TYPE]) -> PackageManager:
os_family = group.get_nodes_os()

if os_family in ['rhel8', 'rhel9']:
if os_family in ['rhel8', 'rhel9', 'rhel10']:
return yum
elif os_family == 'debian':
return apt
Expand Down Expand Up @@ -596,7 +596,7 @@ def search_package(group: DeferredGroup, package: str, callback: Callback = None


def get_detect_package_version_cmd(os_family: str, package_name: str) -> str:
if os_family in ["rhel8", "rhel9"]:
if os_family in ["rhel8", "rhel9", "rhel10"]:
cmd = r"rpm -q %s" % package_name
else:
cmd = r"dpkg-query -f '${Package}=${Version}\n' -W %s" % package_name
Expand Down Expand Up @@ -682,7 +682,7 @@ def get_package_name(os_family: str, package: str) -> str:
package_name = ""

if package:
if os_family in ["rhel8", "rhel9"]:
if os_family in ["rhel8", "rhel9", "rhel10"]:
# regexp is needed to split package and its version, the pattern start with '-' then should be number or '*'
package_name = re.split(r'-[\d,\*]', package)[0]
else:
Expand Down
3 changes: 3 additions & 0 deletions kubemarine/patches/software_upgrade.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ packages:
containerdio:
version_rhel8: []
version_rhel9: []
version_rhel10: []
haproxy:
version_rhel8: false
version_rhel9: false
version_rhel10: false
version_debian: false
keepalived:
version_rhel8: false
version_rhel9: false
version_rhel10: false
version_debian: false
plugins:
calico: []
Expand Down
2 changes: 1 addition & 1 deletion kubemarine/procedures/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def export_ansible_inventory(cluster: KubernetesCluster) -> None:

def export_packages_list(cluster: KubernetesCluster) -> None:
cluster.context['backup_descriptor']['nodes']['packages'] = {}
if cluster.get_os_family() in ['rhel8', 'rhel9']:
if cluster.get_os_family() in ['rhel8', 'rhel9', 'rhel10']:
cmd = r"rpm -qa"
else:
cmd = r"dpkg-query -f '${Package}=${Version}\n' -W"
Expand Down
2 changes: 1 addition & 1 deletion kubemarine/procedures/check_iaas.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ def check_access_to_package_repositories(cluster: KubernetesCluster) -> None:
# TODO: think about better parsing
repository_urls: List[str] = []
repositories = cluster.inventory['services']['packages']['package_manager'].get("repositories")
if cluster.get_os_family() not in ['debian', 'rhel8', 'rhel9']:
if cluster.get_os_family() not in ['debian', 'rhel8', 'rhel9', 'rhel10']:
# Skip check in case of multiply or unknown OS
raise TestWarn("Can't check package repositories on multiple or unknown OS")
if isinstance(repositories, list):
Expand Down
4 changes: 2 additions & 2 deletions kubemarine/procedures/check_paas.py
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ def verify_selinux_status(cluster: KubernetesCluster) -> None:
:return: None
"""
with TestCase(cluster, '213', "Security", "Selinux security policy") as tc:
group = cluster.nodes['all'].get_subgroup_with_os(['rhel8', 'rhel9'])
group = cluster.nodes['all'].get_subgroup_with_os(['rhel8', 'rhel9', 'rhel10'])
if group.is_empty():
return tc.success("No RHEL nodes found")
_, selinux_result, selinux_parsed_result = \
Expand Down Expand Up @@ -931,7 +931,7 @@ def verify_selinux_config(cluster: KubernetesCluster) -> None:
:return: None
"""
with TestCase(cluster, '214', "Security", "Selinux configuration") as tc:
group = cluster.nodes['all'].get_subgroup_with_os(['rhel8', 'rhel9'])
group = cluster.nodes['all'].get_subgroup_with_os(['rhel8', 'rhel9', 'rhel10'])
if group.is_empty():
return tc.success("No RHEL nodes found")
selinux_configured, selinux_result, _ = \
Expand Down
8 changes: 7 additions & 1 deletion kubemarine/procedures/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,16 @@ def system_prepare_package_manager_disable_unattended_upgrades(group: NodeGroup)

@_applicable_for_new_nodes_with_roles('all')
def system_prepare_package_manager_manage_packages(group: NodeGroup) -> None:
cluster = group.cluster
group.call_batch([
manage_mandatory_packages,
manage_custom_packages
])

affected_hosts = system.detect_kernel_upgrade(group) #detecting if kernel is upgraded on any node.
#scheduling reboot if kernel upgrade detected, as it is required to apply new kernel version.
if affected_hosts:
cluster.log.debug(f"Scheduling reboot to apply updated kernel version.")
cluster.schedule_cumulative_point(system.reboot_nodes)

def manage_mandatory_packages(group: NodeGroup) -> RunnersGroupResult:
cluster: KubernetesCluster = group.cluster
Expand Down Expand Up @@ -566,6 +571,7 @@ def overview(cluster: KubernetesCluster) -> None:
# Reboot and verify that the most crucial system settings are applied on boot.
# This is done before `prepare.system.audit`.
system.reboot_nodes: [
"prepare.system.modprobe",
"prepare.system.audit"
],
system.verify_system: [
Expand Down
4 changes: 2 additions & 2 deletions kubemarine/procedures/migrate_kubemarine.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,15 @@ def resolve_upgrade_patches() -> List[_SoftwareUpgradePatch]:

k8s_versions = [version
for pkg in ('containerd', 'containerdio')
for v_key in ('version_rhel8', 'version_rhel9', 'version_debian')
for v_key in ('version_rhel8', 'version_rhel9', 'version_rhel10', 'version_debian')
for version in upgrade_config['packages'][pkg].get(v_key, [])]
if k8s_versions:
verify_allowed_kubernetes_versions(k8s_versions)
upgrade_patches.append(CriUpgradePatch(upgrade_config))

for package_name in ['haproxy', 'keepalived']:
if any(upgrade_config['packages'][package_name].get(v_key)
for v_key in ('version_rhel8', 'version_rhel9', 'version_debian')):
for v_key in ('version_rhel8', 'version_rhel9', 'version_rhel10', 'version_debian')):
upgrade_patches.append(BalancerUpgradePatch(upgrade_config, package_name))

default_plugins = static.DEFAULTS['plugins']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,42 @@ containerdio:
v1.32.0:
version_rhel8: 1.6*
version_rhel9: 1.7*
version_rhel10: 1.7*
v1.32.2:
version_rhel8: 1.6*
version_rhel9: 1.7*
version_rhel10: 1.7*
v1.32.10:
version_rhel8: 1.6*
version_rhel9: 1.7*
version_rhel10: 1.7*
v1.33.0:
version_rhel8: 1.6*
version_rhel9: 1.6*
version_rhel10: 1.7*
v1.33.6:
version_rhel8: 1.6*
version_rhel9: 1.6*
version_rhel10: 1.7*
v1.34.1:
version_rhel8: 1.6*
version_rhel9: 1.7*
version_rhel10: 1.7*
v1.34.2:
version_rhel8: 1.6*
version_rhel9: 1.7*
version_rhel10: 1.7*
v1.35.0:
version_rhel8: 1.6*
version_rhel9: 1.7*
version_rhel10: 1.7*
haproxy:
version_rhel8: 1.8*
version_rhel9: 2.4*
version_rhel10: 3.2*
version_debian: 2.*
keepalived:
version_rhel8: 2.1*
version_rhel9: 2.2*
version_rhel10: 2.3*
version_debian: 1:2.*
15 changes: 15 additions & 0 deletions kubemarine/resources/configurations/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ services:
- modulename: nf_defrag_ipv6
install: '{{ nodes[0]["internal_address"] | isipv6 }}'
rhel9: *modprobe-default-modules
rhel10: *modprobe-default-modules
debian: *modprobe-default-modules

sysctl:
Expand Down Expand Up @@ -502,6 +503,20 @@ services:
package_name: 'policycoreutils-python-utils'
iptables:
package_name: 'iptables-nft'
rhel10:
containerd: {}
haproxy:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check HAProxy/keepalived versions on rhel10

executable_name: '/usr/sbin/haproxy'
service_name: 'haproxy'
keepalived: {}
audit:
package_name: 'audit'
conntrack:
package_name: 'conntrack-tools'
semanage:
package_name: 'policycoreutils-python-utils'
iptables:
package_name: 'iptables-nft'

plugin_defaults:
installation: {}
Expand Down
13 changes: 13 additions & 0 deletions kubemarine/resources/configurations/globals.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,16 @@ packages:
keepalived:
package_name:
- keepalived: keepalived
rhel10:
containerd:
package_name:
- containerd.io: containerdio
haproxy:
package_name:
- haproxy: haproxy
keepalived:
package_name:
- keepalived: keepalived
common_associations:
containerd:
executable_name: 'containerd'
Expand Down Expand Up @@ -324,6 +334,9 @@ compatibility_map:
- '9.4'
- '9.5'
- '9.6'
- os_family: 'rhel10'
versions:
- '10.1'
ubuntu:
- os_family: 'debian'
versions:
Expand Down
3 changes: 3 additions & 0 deletions kubemarine/resources/etalons/patches/software_upgrade.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ packages:
containerdio:
version_rhel8: []
version_rhel9: []
version_rhel10: []
haproxy:
version_rhel8: false
version_rhel9: false
version_rhel10: false
version_debian: false
keepalived:
version_rhel8: false
version_rhel9: false
version_rhel10: false
version_debian: false
plugins:
calico: []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
"properties": {
"debian": {"$ref": "#/definitions/OSFamilyModules"},
"rhel8": {"$ref": "#/definitions/OSFamilyModules"},
"rhel9": {"$ref": "#/definitions/OSFamilyModules"}
"rhel9": {"$ref": "#/definitions/OSFamilyModules"},
"rhel10": {"$ref": "#/definitions/OSFamilyModules"}
},
"propertyNames": {
"anyOf": [
{"enum": ["debian", "rhel8", "rhel9"]}
{"enum": ["debian", "rhel8", "rhel9", "rhel10"]}
]
},
"definitions": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
"properties": {
"debian": {"$ref": "#/definitions/OSFamilyAssociations"},
"rhel8": {"$ref": "#/definitions/OSFamilyAssociations"},
"rhel9": {"$ref": "#/definitions/OSFamilyAssociations"}
"rhel9": {"$ref": "#/definitions/OSFamilyAssociations"},
"rhel10": {"$ref": "#/definitions/OSFamilyAssociations"}
},
"propertyNames": {
"anyOf": [
{"$ref": "#/definitions/AssociationsNames"},
{"enum": ["debian", "rhel8", "rhel9"]}
{"enum": ["debian", "rhel8", "rhel9", "rhel10"]}
]
},
"definitions": {
Expand Down
2 changes: 1 addition & 1 deletion kubemarine/selinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def setup_selinux(group: NodeGroup) -> bool:
log = group.cluster.log

# this method handles cluster with multiple os, suppressing should be enabled
if group.get_nodes_os() not in ['rhel8', 'rhel9']:
if group.get_nodes_os() not in ['rhel8', 'rhel9', 'rhel10']:
log.debug("Skipped - selinux is not supported on Ubuntu/Debian os family")
return False

Expand Down
23 changes: 22 additions & 1 deletion kubemarine/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,27 @@ def disable_swap(group: NodeGroup) -> Optional[RunnersGroupResult]:
def reboot_nodes(cluster: KubernetesCluster) -> None:
cluster.get_new_nodes_or_self().call(reboot_group)

def detect_kernel_upgrade(group: NodeGroup) -> List[str]:
cluster = group.cluster
affected_hosts = []

os_family = group.get_nodes_os()

if os_family in ["rhel8", "rhel9", "rhel10"]:
try:
result = group.sudo("needs-restarting -r", hide=True, warn=True)
for host, res in result.items():
if res.exited == 1:
affected_hosts.append(host)
cluster.log.debug(
f"{host}: Reboot required (detected via needs-restarting -r)"
)
except GroupResultException:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we mock this in tests? I am not sure about always ignoring GroupResultException

cluster.log.debug(
"Skipping reboot detection (needs-restarting not available in test environment)"
)
return []
return affected_hosts #list of nodes with detected kernel upgrade

def reboot_group(group: NodeGroup, try_graceful: bool = None) -> RunnersGroupResult:
from kubemarine import kubernetes # pylint: disable=cyclic-import
Expand Down Expand Up @@ -497,7 +518,7 @@ def verify_system(cluster: KubernetesCluster) -> None:
# this method handles clusters with multiple OS
os_family = group.get_nodes_os()

if os_family in ['rhel8', 'rhel9'] and cluster.is_task_completed('prepare.system.setup_selinux'):
if os_family in ['rhel8', 'rhel9', 'rhel10'] and cluster.is_task_completed('prepare.system.setup_selinux'):
log.debug("Verifying Selinux...")
selinux_configured, selinux_result, _ = \
selinux.is_config_valid(group,
Expand Down
2 changes: 2 additions & 0 deletions scripts/thirdparties/src/software/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,13 @@ def get_compatibility_version_keys(package_name: str) -> List[str]:
keys = [
'version_rhel8',
'version_rhel9',
'version_rhel10',
'version_debian',
]
if package_name == 'containerd':
keys.remove('version_rhel8')
keys.remove('version_rhel9')
keys.remove('version_rhel10')
elif package_name == 'containerdio':
keys.remove('version_debian')

Expand Down
Loading
Loading