|
| 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