diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ddeecabb..ee977562 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,6 +41,14 @@ jobs: base_image: "fedora:41" trusted_boot: "true" fips: false + - platform: "arm64" + base_image: "ubuntu:22.04" + model: "nvidia-jetson-agx-orin" + fips: false + - platform: "arm64" + base_image: "ubuntu:22.04" + model: "nvidia-jetson-orin-nx" + fips: false steps: - uses: actions/checkout@v5 with: @@ -67,4 +75,5 @@ jobs: PROVIDER_VERSION=${{ matrix.kubernetes_version || '' }} VERSION=${{ env.VERSION }} FIPS=${{ matrix.fips || false }} - TRUSTED_BOOT=${{ matrix.trusted_boot || 'false' }} \ No newline at end of file + TRUSTED_BOOT=${{ matrix.trusted_boot || 'false' }} + MODEL=${{ matrix.model || 'generic' }} \ No newline at end of file diff --git a/pkg/stages/steps_install.go b/pkg/stages/steps_install.go index b61343a6..aa28da7e 100644 --- a/pkg/stages/steps_install.go +++ b/pkg/stages/steps_install.go @@ -62,17 +62,37 @@ func GetInstallStage(sis values.System, logger types.KairosLogger) ([]schema.Sta // Read the NVIDIA env variables, use defaults if not set nvidiaRelease := os.Getenv("NVIDIA_RELEASE") - if nvidiaRelease == "" { - nvidiaRelease = "35" - } + if nvidiaRelease == "" { + // This was just introduced in PR #211, however if you check the + // Dockerfile.nvidia-orin-nx it says 36 :shrug:, do we actually need a + // default or should the user always set it? if we have a default, should it + // ever change? + nvidiaRelease = "35" + } + + nvidiaVersion := os.Getenv("NVIDIA_VERSION") + if nvidiaVersion == "" { + // This was just introduced in PR #211, however if you check the + // Dockerfile.nvidia-orin-nx it says 4.4 :shrug:, do we actually need a + // default or should the user always set it? if we have a default, should it + // ever change? + nvidiaVersion = "3.1" + } + + l4tVersion := os.Getenv("L4T_VERSION") + if l4tVersion == "" { + l4tVersion = "36.4" + } - nvidiaVersion := os.Getenv("NVIDIA_VERSION") - if nvidiaVersion == "" { - nvidiaVersion = "3.1" - } + // Get board model from environment or config + boardModel := os.Getenv("BOARD_MODEL") + if boardModel == "" { + // Does it make sense that both AGX Orin and Orin NX use the same board model? + boardModel = "t234" + } // Prepare NVIDIA L4T extraction script - l4tScript := fmt.Sprintf(`#!/bin/bash + l4tScript := fmt.Sprintf(`#!/bin/bash set -e NVIDIA_RELEASE="%s" @@ -149,6 +169,72 @@ func GetInstallStage(sis values.System, logger types.KairosLogger) ([]schema.Sta l4tScript, }, }, + { + Name: "Setup NVIDIA L4T repositories", + If: fmt.Sprintf(`[ "%s" = "nvidia-jetson-agx-orin" ] || [ "%s" = "nvidia-jetson-orin-nx" ]`, config.DefaultConfig.Model, config.DefaultConfig.Model), + Commands: []string{ + // Clean up existing NVIDIA repository files + "rm -rf /etc/apt/sources.list.d/nvidia-l4t-apt-source.list", + // Create NVIDIA L4T packages directory + "mkdir -p /opt/nvidia/l4t-packages", + "touch /opt/nvidia/l4t-packages/.nv-l4t-disable-boot-fw-update-in-preinstall", + // Add NVIDIA GPG keys + "curl -fSsL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub | gpg --dearmor | tee /usr/share/keyrings/nvidia-drivers-2004.gpg > /dev/null 2>&1", + "curl -fSsL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/3bf863cc.pub | gpg --dearmor | tee /usr/share/keyrings/nvidia-drivers-2204.gpg > /dev/null 2>&1", + "curl -fSsL https://repo.download.nvidia.com/jetson/jetson-ota-public.asc | gpg --dearmor | tee /usr/share/keyrings/jetson-ota.gpg > /dev/null 2>&1", + // Add NVIDIA repositories + "echo 'deb [signed-by=/usr/share/keyrings/nvidia-drivers-2204.gpg] https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/ /' | tee -a /etc/apt/sources.list.d/nvidia-drivers.list", + "echo 'deb [signed-by=/usr/share/keyrings/nvidia-drivers-2004.gpg] https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /' | tee -a /etc/apt/sources.list.d/nvidia-drivers.list", + fmt.Sprintf("echo 'deb [signed-by=/usr/share/keyrings/jetson-ota.gpg] https://repo.download.nvidia.com/jetson/common/ r%s main' | tee -a /etc/apt/sources.list.d/nvidia-drivers.list", l4tVersion), + fmt.Sprintf("echo 'deb [signed-by=/usr/share/keyrings/jetson-ota.gpg] https://repo.download.nvidia.com/jetson/%s/ r%s main' | tee -a /etc/apt/sources.list.d/nvidia-drivers.list", boardModel, l4tVersion), + }, + }, + { + Name: "Setup OpenCV symlink for NVIDIA devices", + If: fmt.Sprintf(`[ "%s" = "nvidia-jetson-agx-orin" ] || [ "%s" = "nvidia-jetson-orin-nx" ]`, config.DefaultConfig.Model, config.DefaultConfig.Model), + Commands: []string{ + "ln -s /usr/include/opencv4/opencv2 /usr/include/opencv2", + }, + }, + { + Name: "Configure CUDA paths for NVIDIA devices", + If: fmt.Sprintf(`[ "%s" = "nvidia-jetson-agx-orin" ] || [ "%s" = "nvidia-jetson-orin-nx" ]`, config.DefaultConfig.Model, config.DefaultConfig.Model), + Commands: []string{ + // Move CUDA out of the way to /opt so kairos can occupy /usr/local without workarounds + "update-alternatives --remove-all cuda || true", + "update-alternatives --remove-all cuda-12 || true", + "mv /usr/local/cuda-12.6 /opt/cuda-12.6 || true", + "update-alternatives --install /opt/cuda cuda /opt/cuda-12.6 1 || true", + "update-alternatives --install /opt/cuda-12 cuda-12 /opt/cuda-12.6 1 || true", + }, + }, + { + Name: "Configure NVIDIA L4T USB device mode for NVIDIA devices", + If: fmt.Sprintf(`[ "%s" = "nvidia-jetson-agx-orin" ] || [ "%s" = "nvidia-jetson-orin-nx" ]`, config.DefaultConfig.Model, config.DefaultConfig.Model), + Commands: []string{ + // Change mountpoint for l4t usb device mode, as rootfs is mounted ro + // /srv/data is made through cloud-config + "sed -i -e 's|mntpoint=\"/mnt|mntpoint=\"/srv/data|' /opt/nvidia/l4t-usb-device-mode/nv-l4t-usb-device-mode-start.sh || true", + }, + }, + { + Name: "Disable ISCSI for NVIDIA devices", + If: fmt.Sprintf(`[ "%s" = "nvidia-jetson-agx-orin" ] || [ "%s" = "nvidia-jetson-orin-nx" ]`, config.DefaultConfig.Model, config.DefaultConfig.Model), + Files: []schema.File{ + { + Path: "/etc/dracut.conf.d/iscsi.conf", + Content: "omit_dracutmodules+=\" iscsi \"", + }, + }, + }, + { + Name: "Disable ISCSI services for NVIDIA devices", + If: fmt.Sprintf(`[ "%s" = "nvidia-jetson-agx-orin" ] || [ "%s" = "nvidia-jetson-orin-nx" ]`, config.DefaultConfig.Model, config.DefaultConfig.Model), + Commands: []string{ + // iscsid causes delays on the login shell, and we don't need it, so we'll disable it + "systemctl disable iscsi open-iscsi iscsid.socket || true", + }, + }, } return stage, nil } diff --git a/pkg/values/packagemaps.go b/pkg/values/packagemaps.go index 21bb3946..e6ad988a 100644 --- a/pkg/values/packagemaps.go +++ b/pkg/values/packagemaps.go @@ -58,6 +58,148 @@ type ModelPackageMap map[DistroFamilyInterface]map[Architecture]map[Model]Versio // VersionMap is a map of a constraint to a list of packages type VersionMap map[string][]string +// BasePackagesModels allows model-specific base packages per distro/arch/model +var BasePackagesModels = ModelPackageMap{ + Ubuntu: { + ArchARM64: { + AgxOrin: { + Common: { + "bridge-utils", + "efibootmgr", + "fuse", + "git", + "grub2-common", + "libssl-dev", + "policykit-1", + "vim", + }, + }, + OrinNX: { + Common: { + "bc", + "binutils", + "bluez", + "bridge-utils", + "bzip2", + "ca-certificates", + "can-utils", + "cloud-guest-utils", + "conntrack", + "console-data", + "console-setup", + "coreutils", + "cron", + "cryptsetup", + "curl", + "debianutils", + "default-jdk", + "dirmngr", + "dmsetup", + "dosfstools", + "dracut", + "dracut-live", + "dracut-network", + "e2fsprogs", + "efibootmgr", + "ethtool", + "fail2ban", + "fdisk", + "file", + "fuse3", + "gawk", + "gdisk", + "gettext", + "gnupg", + "gnupg1-l10n", + "gpg-agent", + "grub2-common", + "grub-efi-arm64", + "grub-efi-arm64-bin", + "grub-efi-arm64-signed", + "haveged", + "iproute2", + "iptables", + "iputils-ping", + "isc-dhcp-client", + "isc-dhcp-common", + "isc-dhcp-server", + "jq", + "kbd", + "kmod", + "lbzip2", + "less", + "libatm1", + "libglib2.0-data", + "libgpm2", + "libldap-common", + "libnss-systemd", + "libopencv-dev", + "libpam-cap", + "libqt5core5a", + "libsasl2-modules", + "libssl-dev", + "lldpd", + "logrotate", + "lvm2", + "mdadm", + "modemmanager", + "mtd-utils", + "nano", + "nbd-client", + "ncurses-term", + "netplan.io", + "net-tools", + "networkd-dispatcher", + "network-manager", + "nfs-client", + "nfs-common", + "nftables", + "open-iscsi", + "openssh-server", + "open-vm-tools", + "os-prober", + "packagekit-tools", + "parted", + "passwd", + "patch", + "pigz", + "pkg-config", + "policykit-1", + "psmisc", + "publicsuffix", + "qemu-user-static", + "rsync", + "shared-mime-info", + "shim-signed", + "snmpd", + "software-properties-common", + "squashfs-tools", + "ssh", + "sudo", + "systemd", + "systemd-container", + "systemd-sysv", + "systemd-timesyncd", + "tar", + "tpm2-tools", + "ubuntu-advantage-tools", + "udev", + "unzip", + "vim", + "wget", + "wireless-tools", + "wpasupplicant", + "xxd", + "xz-utils", + "zerofree", + "zfsutils-linux", + "zstd", + }, + }, + }, + }, +} + // ImmucorePackages are the minimum set of packages that immucore needs. // Otherwise, you won't be able to build the initrd with immucore on it. // These packages are removed afterward, so we can keep the image as small as possible @@ -702,6 +844,126 @@ var KernelPackagesModels = ModelPackageMap{ // 24.10 uses the 24.04 hwe kernel as it is the same hwe track https://ubuntu.com/kernel/lifecycle ">=24.10": {"linux-image-generic-hwe-24.04"}, }, + AgxOrin: { + Common: { + // NVIDIA L4T packages for AGX Orin + "nvidia-l4t-3d-core", + "nvidia-l4t-apt-source", + "nvidia-l4t-bootloader", + "nvidia-l4t-camera", + "nvidia-l4t-configs", + "nvidia-l4t-core", + "nvidia-l4t-cuda", + "nvidia-l4t-display-kernel", + "nvidia-l4t-firmware", + "nvidia-l4t-gbm", + "nvidia-l4t-graphics-demos", + "nvidia-l4t-gstreamer", + "nvidia-l4t-init", + "nvidia-l4t-initrd", + "nvidia-l4t-jetson-io", + "nvidia-l4t-jetsonpower-gui-tools", + "nvidia-l4t-kernel", + "nvidia-l4t-kernel-dtbs", + "nvidia-l4t-kernel-headers", + "nvidia-l4t-kernel-oot-modules", + "nvidia-l4t-multimedia-utils", + "nvidia-l4t-multimedia", + "nvidia-l4t-nvfancontrol", + "nvidia-l4t-nvpmodel-gui-tools", + "nvidia-l4t-nvpmodel", + "nvidia-l4t-nvsci", + "nvidia-l4t-oem-config", + "nvidia-l4t-openwfd", + "nvidia-l4t-optee", + "nvidia-l4t-pva", + "nvidia-l4t-tools", + "nvidia-l4t-vulkan-sc-dev", + "nvidia-l4t-vulkan-sc-samples", + "nvidia-l4t-vulkan-sc-sdk", + "nvidia-l4t-vulkan-sc", + "nvidia-l4t-wayland", + "nvidia-l4t-weston", + "nvidia-l4t-x11", + "nvidia-l4t-xusb-firmware", + // CUDA packages + "cuda-cudart-12-6", + "cuda-cudart-dev-12-6", + "cuda-nvcc-12-6", + "cuda-nvdisasm-12-6", + "cuda-nvml-dev-12-6", + "cuda-nvprune-12-6", + "cuda-nvrtc-12-6", + "cuda-nvrtc-dev-12-6", + "cuda-nvtx-12-6", + "libcublas-12-6", + "libcublas-dev-12-6", + // Jetson GPIO + "jetson-gpio-common", + "python3-jetson-gpio", + // OpenCV + "libopencv-dev", + }, + }, + OrinNX: { + Common: { + // NVIDIA L4T packages for Orin NX + "nvidia-l4t-3d-core", + "nvidia-l4t-apt-source", + "nvidia-l4t-bootloader", + "nvidia-l4t-camera", + "nvidia-l4t-configs", + "nvidia-l4t-core", + "nvidia-l4t-cuda-utils", + "nvidia-l4t-cuda", + "nvidia-l4t-display-kernel", + "nvidia-l4t-firmware", + "nvidia-l4t-gbm", + "nvidia-l4t-init", + "nvidia-l4t-initrd", + "nvidia-l4t-jetson-io", + "nvidia-l4t-kernel", + "nvidia-l4t-kernel-dtbs", + "nvidia-l4t-kernel-headers", + "nvidia-l4t-kernel-oot-headers", + "nvidia-l4t-kernel-oot-modules", + "nvidia-l4t-nvfancontrol", + "nvidia-l4t-nvml", + "nvidia-l4t-nvpmodel-gui-tools", + "nvidia-l4t-nvpmodel", + "nvidia-l4t-nvsci", + "nvidia-l4t-oem-config", + "nvidia-l4t-openwfd", + "nvidia-l4t-optee", + "nvidia-l4t-pva", + "nvidia-l4t-tools", + "nvidia-l4t-vulkan-sc-dev", + "nvidia-l4t-vulkan-sc-sdk", + "nvidia-l4t-vulkan-sc", + "nvidia-l4t-xusb-firmware", + // CUDA packages + "cuda-cudart-12-6", + "cuda-cudart-dev-12-6", + "cuda-nvcc-12-6", + "cuda-nvdisasm-12-6", + "cuda-nvml-dev-12-6", + "cuda-nvprune-12-6", + "cuda-nvrtc-12-6", + "cuda-nvrtc-dev-12-6", + "cuda-nvtx-12-6", + "libcublas-12-6", + "libcublas-dev-12-6", + // Jetson GPIO + "jetson-gpio-common", + "python-jetson-gpio", + "python3-jetson-gpio", + // NVIDIA Container Toolkit + "nvidia-container-toolkit-base", + "nvidia-container-toolkit", + // OpenCV + "libopencv-dev", + }, + }, }, }, SUSEFamily: { @@ -777,6 +1039,13 @@ func GetPackages(s System, l sdkTypes.KairosLogger) ([]string, error) { BasePackages[s.Distro][s.Arch], // Specific packages for the arch BasePackages[s.Family][s.Arch], // Specific packages for the arch by family } + // Include model-specific base packages when model is not generic + if config.DefaultConfig.Model != Generic.String() { + filteredPackages = append(filteredPackages, BasePackagesModels[s.Distro][ArchCommon][Model(config.DefaultConfig.Model)]) + filteredPackages = append(filteredPackages, BasePackagesModels[s.Family][ArchCommon][Model(config.DefaultConfig.Model)]) + filteredPackages = append(filteredPackages, BasePackagesModels[s.Distro][s.Arch][Model(config.DefaultConfig.Model)]) + filteredPackages = append(filteredPackages, BasePackagesModels[s.Family][s.Arch][Model(config.DefaultConfig.Model)]) + } // If trusted boot is enabled, we need to install the trusted boot packages if config.DefaultConfig.TrustedBoot { // Install only systemd-boot packages diff --git a/pkg/values/values.go b/pkg/values/values.go index 55e90ac9..2f64e42f 100644 --- a/pkg/values/values.go +++ b/pkg/values/values.go @@ -39,7 +39,7 @@ const ( OpenSUSELeap Distro = "opensuse-leap" OpenSUSETumbleweed Distro = "opensuse-tumbleweed" SLES Distro = "sles" - Hadron Distro = "hadron" + Hadron Distro = "hadron" ) type Family string @@ -56,7 +56,7 @@ const ( ArchFamily Family = "arch" AlpineFamily Family = "alpine" SUSEFamily Family = "suse" - HadronFamily Family = "hadron" + HadronFamily Family = "hadron" ) type Model string // Model is the type of the system @@ -66,8 +66,8 @@ const ( Generic Model = "generic" Rpi3 Model = "rpi3" Rpi4 Model = "rpi4" - AgxOrin Model = "agx-orin" - OrinNX Model = "orin-nx" + AgxOrin Model = "nvidia-jetson-agx-orin" + OrinNX Model = "nvidia-jetson-orin-nx" ) type System struct {