Skip to content

Commit b7fbb6f

Browse files
Add AMD driver image (jsc#PED-14049)
This image is required for adding support for the AMD GPU Operator on SLES.
1 parent 22a9af2 commit b7fbb6f

2 files changed

Lines changed: 292 additions & 0 deletions

File tree

src/bci_build/package/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,6 +1478,7 @@ def generate_disk_size_constraints(size_gb: int) -> str:
14781478
"""
14791479

14801480

1481+
from .amd import AMD_CONTAINERS # noqa: E402
14811482
from .apache_tomcat import TOMCAT_CONTAINERS # noqa: E402
14821483
from .appcontainers import ALERTMANAGER_CONTAINERS # noqa: E402
14831484
from .appcontainers import BLACKBOX_EXPORTER_CONTAINERS # noqa: E402
@@ -1549,6 +1550,7 @@ def generate_disk_size_constraints(size_gb: int) -> str:
15491550
*BCI_CI_CONTAINERS,
15501551
*THREE_EIGHT_NINE_DS_CONTAINERS,
15511552
*NGINX_CONTAINERS,
1553+
*AMD_CONTAINERS,
15521554
*DOTNET_CONTAINERS,
15531555
*PCP_CONTAINERS,
15541556
*REGISTRY_CONTAINERS,

src/bci_build/package/amd.py

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
from jinja2 import Template
2+
3+
from bci_build.container_attributes import Arch
4+
from bci_build.container_attributes import PackageType
5+
from bci_build.container_attributes import ReleaseStage
6+
from bci_build.container_attributes import SupportLevel
7+
from bci_build.containercrate import ContainerCrate
8+
from bci_build.os_version import OsVersion
9+
from bci_build.package import DOCKERFILE_RUN
10+
from bci_build.package import _RELEASE_PLACEHOLDER
11+
from bci_build.package import DevelopmentContainer
12+
from bci_build.package import Package
13+
from bci_build.package import generate_disk_size_constraints
14+
from bci_build.package.helpers import generate_from_image_tag
15+
from bci_build.package.thirdparty import ThirdPartyRepo
16+
from bci_build.package.thirdparty import ThirdPartyRepoMixin
17+
from bci_build.repomdparser import RpmPackage
18+
19+
AMD_REPOS = [
20+
ThirdPartyRepo(
21+
name="radeon-sles15sp7-x86_64",
22+
arch=Arch.X86_64,
23+
url="https://repo.radeon.com/amdgpu/7.0.3/sle/15.7/main/x86_64/",
24+
key_url="https://repo.radeon.com/rocm/rocm.gpg.key",
25+
),
26+
]
27+
28+
29+
CUSTOM_END_TEMPLATE = Template(
30+
"""
31+
{{ DOCKERFILE_RUN }} depmod {{ kernel_ga }}
32+
33+
# decompress modules for getKmodsToSign (kmmmodule.go) since it expects uncompressed files
34+
{{ DOCKERFILE_RUN }} find /lib/modules/{{ kernel_ga }} -name "*.ko.zst" -exec zstd -d --rm {} \\;
35+
{{ DOCKERFILE_RUN }} depmod {{ kernel_ga }}
36+
37+
# copy modules to /opt since getKmodsToSign (kmmmodule.go) expects it there
38+
# since we build only for GA, we need to copy modules for each kernel version
39+
# to match the container tags, and symlinks are not allowed
40+
{%- for kernel_version in kernel_versions %}
41+
{{ DOCKERFILE_RUN }} mkdir -p /target/opt/lib/modules/{{ kernel_version }}/updates/dkms
42+
{{ DOCKERFILE_RUN }} cp /lib/modules/{{ kernel_ga }}/updates/amd* /target/opt/lib/modules/{{ kernel_version }}/updates/dkms
43+
{{ DOCKERFILE_RUN }} cp /lib/modules/{{ kernel_ga }}/modules.* /target/opt/lib/modules/{{ kernel_version }}/
44+
{{ DOCKERFILE_RUN }} cp -r /lib/modules/{{ kernel_ga }}/kernel /target/opt/lib/modules/{{ kernel_version }}/kernel
45+
{%- endfor %}
46+
47+
# copy firmware to /firmwareDir
48+
{{ DOCKERFILE_RUN }} mkdir -p /target/firmwareDir/updates/amdgpu
49+
{{ DOCKERFILE_RUN }} cp -r /lib/firmware/updates/amdgpu /target/firmwareDir/updates/amdgpu
50+
"""
51+
)
52+
53+
54+
class AMDDriverBCI(ThirdPartyRepoMixin, DevelopmentContainer):
55+
def __init__(self, **kwargs):
56+
super().__init__(**kwargs)
57+
58+
self.extra_files.update(
59+
{
60+
"_constraints": generate_disk_size_constraints(4),
61+
}
62+
)
63+
64+
@property
65+
def labelprefix(self) -> str:
66+
labelprefix = "com.suse"
67+
if self.os_version.is_tumbleweed:
68+
labelprefix = "org.opensuse"
69+
return f"{labelprefix}.third-party.{(self.custom_labelprefix_end or self.name)}"
70+
71+
@property
72+
def release_stage(self) -> ReleaseStage:
73+
# TODO: Remove once the image is completed with all driver versions
74+
return ReleaseStage.BETA
75+
76+
@property
77+
def registry_prefix(self):
78+
return "third-party"
79+
80+
@property
81+
def build_tags(self) -> list[str]:
82+
# addition tags should match sles-15.7-6.4.0-150700.53.19-default-7.0.3
83+
return [
84+
f"{self.registry_prefix}/amd/amdgpu-driver:{self.image_ref_name}-{_RELEASE_PLACEHOLDER}",
85+
f"{self.registry_prefix}/amd/amdgpu-driver:{self.image_ref_name}",
86+
] + [
87+
f"{self.registry_prefix}/amd/amdgpu-driver:sles-{self.os_version.os_version}-{v}-default-{self.tag_version}"
88+
for v in self.additional_versions
89+
]
90+
91+
@property
92+
def image_ref_name(self) -> str:
93+
return f"sles-%OS_VERSION_ID_SP%-{self.tag_version}"
94+
95+
@property
96+
def build_name(self) -> str:
97+
return f"{self.name}-{self.tag_version}"
98+
99+
@property
100+
def build_version(self) -> str:
101+
return f"{self.os_version.os_version}.{self.version}"
102+
103+
@property
104+
def reference(self) -> str:
105+
return f"{self.registry}/{self.registry_prefix}/amd/amdgpu-driver:{self.image_ref_name}-{_RELEASE_PLACEHOLDER}"
106+
107+
@property
108+
def pretty_reference(self) -> str:
109+
return f"{self.registry}/{self.registry_prefix}/amd/amdgpu-driver:{self.image_ref_name}"
110+
111+
def fetch_rpm_packages(self) -> list[RpmPackage]:
112+
"""Fetches all the required packages from the repository.
113+
114+
Returns:
115+
list of :py:class:`RpmPackage` representing the downloaded rpms
116+
"""
117+
if self._rpms:
118+
return self._rpms
119+
120+
super().fetch_rpm_packages()
121+
122+
project = "SUSE:SLE-15-SP7:GA"
123+
repo = "pool"
124+
version = "6.4.0"
125+
release = "150700.51.1"
126+
arches = self.exclusive_arch
127+
subpackages = [
128+
{
129+
"name": "kernel-default",
130+
"package": "kernel-default",
131+
},
132+
{
133+
"name": "kernel-default-devel",
134+
"package": "kernel-default",
135+
},
136+
{
137+
"name": "kernel-syms",
138+
"package": "kernel-syms",
139+
},
140+
{
141+
"name": "kernel-devel",
142+
"package": "kernel-source",
143+
"no_arch": True,
144+
},
145+
{
146+
"name": "kernel-macros",
147+
"package": "kernel-source",
148+
"no_arch": True,
149+
},
150+
]
151+
152+
for subpkg in subpackages:
153+
name = subpkg["name"]
154+
package = subpkg["package"]
155+
no_arch = subpkg.get("no_arch", False)
156+
157+
for arch in arches:
158+
filename_in_image = f"{name}-{version}-{release}.{arch}.rpm"
159+
160+
if no_arch:
161+
filename_in_repo = f"{name}-{version}-{release}.noarch.rpm"
162+
else:
163+
filename_in_repo = f"{name}-{version}-{release}.{arch}.rpm"
164+
165+
self._rpms.append(
166+
RpmPackage(
167+
name=name,
168+
arch=str(arch),
169+
evr=("", version, release),
170+
filename=filename_in_image,
171+
url=f"https://api.opensuse.org/public/build/{project}/{repo}/{arch}/{package}/{filename_in_repo}",
172+
)
173+
)
174+
175+
return self._rpms
176+
177+
def prepare_template(self) -> None:
178+
super().prepare_template()
179+
180+
self.build_stage_custom_end += "\n" + CUSTOM_END_TEMPLATE.render(
181+
image=self,
182+
DOCKERFILE_RUN=DOCKERFILE_RUN,
183+
kernel_ga=_get_kernel_versions(self.os_version)[-1] + "-default",
184+
kernel_versions=[
185+
f"{v}-default" for v in _get_kernel_versions(self.os_version)
186+
],
187+
)
188+
189+
190+
def _get_kernel_versions(os_version: OsVersion):
191+
"""Return all kernel versions for a given OS version."""
192+
193+
# TODO: This should be moved to the package_versions.json
194+
# otherwise a new kernel version needs to be added here
195+
# for every release.
196+
if os_version == OsVersion.SL16_0:
197+
return [
198+
"6.12.0-160000.26",
199+
"6.12.0-160000.9",
200+
"6.12.0-160000.8",
201+
"6.12.0-160000.7",
202+
"6.12.0-160000.6",
203+
"6.12.0-160000.5", # GA
204+
]
205+
206+
if os_version == OsVersion.SP7:
207+
return [
208+
"6.4.0-150700.53.31",
209+
"6.4.0-150700.53.28",
210+
"6.4.0-150700.53.25",
211+
"6.4.0-150700.53.22",
212+
"6.4.0-150700.53.19",
213+
"6.4.0-150700.53.16",
214+
"6.4.0-150700.53.11",
215+
"6.4.0-150700.53.6",
216+
"6.4.0-150700.53.3",
217+
"6.4.0-150700.51", # GA
218+
]
219+
220+
raise ValueError(f"Unknown kernel versions for '{os_version}'")
221+
222+
223+
_AMD_DRIVER_VERSIONS: list[str] = ["7.0.3"]
224+
225+
AMD_CONTAINERS: list[AMDDriverBCI] = []
226+
227+
for os_version in (OsVersion.SP7,):
228+
for ver in _AMD_DRIVER_VERSIONS:
229+
AMD_CONTAINERS.append(
230+
AMDDriverBCI(
231+
os_version=os_version,
232+
version=ver,
233+
tag_version=ver,
234+
additional_versions=_get_kernel_versions(os_version),
235+
version_in_uid=True,
236+
use_build_flavor_in_tag=False,
237+
name="amd-driver",
238+
pretty_name="AMD GPU Driver",
239+
is_latest=False,
240+
from_image=generate_from_image_tag(os_version, "bci-base"),
241+
from_target_image=generate_from_image_tag(os_version, "bci-micro"),
242+
support_level=SupportLevel.TECHPREVIEW,
243+
supported_until="",
244+
exclusive_arch=[Arch.X86_64],
245+
package_list=[
246+
(
247+
Package("rpm-ndb", PackageType.IMAGE)
248+
if os_version.is_sle15
249+
else Package("rpm", PackageType.IMAGE)
250+
),
251+
# needed by kernel GA packages
252+
# since kernel GA packages are using RemoteAssetUrl a few dependencies
253+
# are not solved by zypper automatically
254+
Package("awk", PackageType.BOOTSTRAP),
255+
Package("dwarves", PackageType.BOOTSTRAP),
256+
Package("elfutils", PackageType.BOOTSTRAP),
257+
Package("gcc", PackageType.BOOTSTRAP),
258+
Package("libelf-devel", PackageType.BOOTSTRAP),
259+
Package("pesign-obs-integration", PackageType.BOOTSTRAP),
260+
Package("zstd", PackageType.BOOTSTRAP),
261+
# build requirements for amdgpu-dkms
262+
Package("autoconf", PackageType.BOOTSTRAP),
263+
Package("automake", PackageType.BOOTSTRAP),
264+
Package("bc", PackageType.BOOTSTRAP),
265+
Package("bison", PackageType.BOOTSTRAP),
266+
Package("dracut", PackageType.BOOTSTRAP),
267+
Package("flex", PackageType.BOOTSTRAP),
268+
Package("gawk", PackageType.BOOTSTRAP),
269+
Package("libzstd-devel", PackageType.BOOTSTRAP),
270+
Package("make", PackageType.BOOTSTRAP),
271+
Package("mokutil", PackageType.BOOTSTRAP),
272+
Package("perl", PackageType.BOOTSTRAP),
273+
Package("perl-Bootloader", PackageType.BOOTSTRAP),
274+
Package("python3", PackageType.BOOTSTRAP),
275+
Package("python3-setuptools", PackageType.BOOTSTRAP),
276+
Package("python3-wheel", PackageType.BOOTSTRAP),
277+
# runtime requirement to load amdgpu-dkms
278+
Package("kmod", PackageType.IMAGE),
279+
*os_version.release_package_names,
280+
],
281+
third_party_repos=AMD_REPOS,
282+
third_party_package_list=[
283+
"amdgpu-dkms",
284+
"amdgpu-dkms-firmware",
285+
"dkms",
286+
],
287+
)
288+
)
289+
290+
AMD_CRATE = ContainerCrate(AMD_CONTAINERS)

0 commit comments

Comments
 (0)