diff --git a/.github/workflows/build-38.yml b/.github/workflows/build-38.yml index 9fdb9aa..eb71ab9 100644 --- a/.github/workflows/build-38.yml +++ b/.github/workflows/build-38.yml @@ -1,4 +1,4 @@ -name: ublue nvidia 38 +name: ublue hwe 38 on: pull_request: merge_group: diff --git a/.github/workflows/build-39.yml b/.github/workflows/build-39.yml index 422f20a..a21655a 100644 --- a/.github/workflows/build-39.yml +++ b/.github/workflows/build-39.yml @@ -1,4 +1,4 @@ -name: ublue nvidia 39 +name: ublue hwe 39 on: pull_request: merge_group: diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index 324f6a9..94337aa 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -9,9 +9,13 @@ on: env: IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }}-${{ inputs.fedora_version }} + cancel-in-progress: true + jobs: build_ublue: - name: nvidia + name: hwe runs-on: ubuntu-22.04 permissions: contents: read @@ -22,6 +26,10 @@ jobs: matrix: fedora_version: - ${{ inputs.fedora_version }} + hwe_flavor: + - main + - asus + - surface image_name: - silverblue - kinoite @@ -32,9 +40,10 @@ jobs: - lazurite - mate - vauxite - driver_version: - - 470 - - 550 + nvidia_version: + - 0 # No Nvidia drivers (this indicates to only build "main" image target + - 470 # Older Nvidia driver + - 550 # Latest Nvidia driver (update IS_LATEST_DRIVER below if version changes) exclude: # There is no Fedora 38 version of onyx or lazurite - image_name: onyx @@ -49,6 +58,17 @@ jobs: # There is currently no Fedora 40 version of mate - image_name: mate fedora_version: 40 + # Don't build/push "main" since it would be a duplicate of the "base" `*-main` images + - nvidia_version: 0 + hwe_flavor: main + # Only build latest Fedora versions for "asus" and "surface" HWE flavors + - fedora_version: 38 + hwe_flavor: asus + - fedora_version: 38 + hwe_flavor: surface + # Only build latest nvidia version for "surface" HWE flavor + - nvidia_version: 470 + hwe_flavor: surface steps: # Checkout push-to-registry action GitHub repository - name: Checkout Push to Registry action @@ -61,15 +81,24 @@ jobs: - name: Matrix Variables run: | - REPO=${{ github.repository }} - echo "IMAGE_NAME=${{ matrix.image_name }}-${REPO##*/}" >> $GITHUB_ENV + if [[ "${{ matrix.hwe_flavor }}" == "main" ]]; then + if "${{ matrix.nvidia_version }}" == "0" ]]; then + echo "this workflow does not build main image without Nvidia drivers" + exit 1 + fi + echo "IMAGE_NAME=${{ matrix.image_name }}-nvidia" >> $GITHUB_ENV + else + echo "IMAGE_NAME=${{ matrix.image_name }}-${{ matrix.hwe_flavor }}${{ matrix.nvidia_version != '0' && '-nvidia' || ''}}" >> $GITHUB_ENV + fi + echo "SOURCE_IMAGE=${{ matrix.image_name }}-main" >> $GITHUB_ENV + - name: Generate tags id: generate-tags shell: bash run: | # Generate a timestamp for creating an image version history TIMESTAMP="$(date +%Y%m%d)" - VARIANT="${{ matrix.fedora_version }}-${{ matrix.driver_version }}" + VARIANT="${{ matrix.fedora_version }}${{ matrix.nvidia_version == '0' && '' || format('-{0}', matrix.driver_version) }}" if [[ "${{ matrix.fedora_version }}" -eq "38" ]]; then IS_LATEST_VERSION=false @@ -85,7 +114,7 @@ jobs: IS_GTS_VERSION=false fi - if [[ "${{ matrix.driver_version }}" -eq "550" ]]; then + if [[ "${{ matrix.nvidia_version }}" -eq "550" ]]; then IS_LATEST_DRIVER=true fi @@ -155,7 +184,7 @@ jobs: attempt_delay: 15000 command: | set -eo pipefail - ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ matrix.image_name }}-main:${{ matrix.fedora_version }} | jq -r '.Labels["org.opencontainers.image.version"]') + ver=$(skopeo inspect docker://ghcr.io/ublue-os/${{ env.SOURCE_IMAGE }}:${{ matrix.fedora_version }} | jq -r '.Labels["org.opencontainers.image.version"]') if [ -z "$ver" ] || [ "null" = "$ver" ]; then echo "inspected image version must not be empty or null" exit 1 @@ -171,7 +200,7 @@ jobs: ${{ env.IMAGE_NAME }} labels: | org.opencontainers.image.title=${{ env.IMAGE_NAME }} - org.opencontainers.image.description=ublue-os ${{ matrix.image_name }} with Nvidia drivers added + org.opencontainers.image.description=ublue-os ${{ matrix.image_name }}${{ matrix.hwe_flavor == 'asus' && ' for ASUS devices' || '' }}${{ matrix.hwe_flavor == 'surface' && ' for Surface laptops' || ''}}${{ matrix.nvidia_version != '0' && ' with Nvidia drivers' || ''}} org.opencontainers.image.version=${{ env.SOURCE_IMAGE_VERSION }} io.artifacthub.package.readme-url=https://raw.githubusercontent.com/${{ github.repository }}/main/README.md io.artifacthub.package.logo-url=https://avatars.githubusercontent.com/u/1728152?s=200&v=4 @@ -198,11 +227,15 @@ jobs: ${{ steps.generate-tags.outputs.alias_tags }} build-args: | IMAGE_NAME=${{ matrix.image_name }} + SOURCE_IMAGE=${{ env.SOURCE_IMAGE }} FEDORA_MAJOR_VERSION=${{ matrix.fedora_version }} - NVIDIA_MAJOR_VERSION=${{ matrix.driver_version }} + NVIDIA_MAJOR_VERSION=${{ matrix.nvidia_version }} + HWE_FLAVOR=${{ matrix.hwe_flavor }} RPMFUSION_MIRROR=${{ vars.RPMFUSION_MIRROR }} labels: ${{ steps.meta.outputs.labels }} oci: false + extra-args: | + --target=${{ matrix.nvidia_version == '0' && 'main' || 'nvidia' }} # Workaround bug where capital letters in your GitHub username make it impossible to push to GHCR. # https://github.com/macbre/push-to-ghcr/issues/12 diff --git a/Containerfile b/Containerfile index c88b753..9fd225f 100644 --- a/Containerfile +++ b/Containerfile @@ -1,26 +1,49 @@ ARG IMAGE_NAME="${IMAGE_NAME:-silverblue}" -ARG BASE_IMAGE="ghcr.io/ublue-os/${IMAGE_NAME}-main" +ARG SOURCE_IMAGE="${SOURCE_IMAGE:-silverblue-main}" +ARG SOURCE_ORG="${SOURCE_ORG:-ublue-os}" +ARG BASE_IMAGE="ghcr.io/${SOURCE_ORG}/${SOURCE_IMAGE}" ARG FEDORA_MAJOR_VERSION="${FEDORA_MAJOR_VERSION:-39}" -FROM ${BASE_IMAGE}:${FEDORA_MAJOR_VERSION} AS nvidia +FROM ${BASE_IMAGE}:${FEDORA_MAJOR_VERSION} AS main +ARG FEDORA_MAJOR_VERSION="${FEDORA_MAJOR_VERSION:-39}" +ARG HWE_FLAVOR="{HWE_FLAVOR:-main}" ARG IMAGE_NAME="${IMAGE_NAME:-silverblue}" -ARG IMAGE_VENDOR="ublue-os" -ARG IMAGE_FLAVOR="${IMAGE_FLAVOR:-nvidia}" +ARG IMAGE_VENDOR="${IMAGE_VENDOR:-ublue-os}" +ARG RPMFUSION_MIRROR="" + +COPY *.sh /tmp/ +COPY ${HWE_FLAVOR}/ /tmp/ + +RUN mkdir -p /var/lib/alternatives && \ + IMAGE_FLAVOR=main /tmp/image-info.sh && \ + /tmp/install.sh && \ + mv /var/lib/alternatives /staged-alternatives && \ + rm -rf /tmp/* /var/* && \ + ostree container commit && \ + mkdir -p /var/lib && mv /staged-alternatives /var/lib/alternatives && \ + mkdir -p /tmp /var/tmp && \ + chmod -R 1777 /tmp /var/tmp + +FROM main AS nvidia + ARG FEDORA_MAJOR_VERSION="${FEDORA_MAJOR_VERSION:-39}" +ARG HWE_FLAVOR="{HWE_FLAVOR:-main}" +ARG IMAGE_NAME="${IMAGE_NAME:-silverblue}" +ARG IMAGE_VENDOR="${IMAGE_VENDOR:-ublue-os}" ARG NVIDIA_MAJOR_VERSION="${NVIDIA_MAJOR_VERSION:-550}" ARG RPMFUSION_MIRROR="" -COPY image-info.sh /tmp/image-info.sh -COPY install.sh /tmp/install.sh -COPY post-install.sh /tmp/post-install.sh +COPY --from=ghcr.io/ublue-os/akmods-nvidia:${HWE_FLAVOR}-${FEDORA_MAJOR_VERSION}-${NVIDIA_MAJOR_VERSION} /rpms /tmp/akmods-rpms -COPY --from=ghcr.io/ublue-os/akmods-nvidia:main-${FEDORA_MAJOR_VERSION}-${NVIDIA_MAJOR_VERSION} /rpms /tmp/akmods-rpms - -RUN /tmp/image-info.sh && \ - /tmp/install.sh && \ - /tmp/post-install.sh && \ - rm -rf /tmp/* /var/* +COPY *.sh /tmp/ -RUN ostree container commit && \ - mkdir -p /var/tmp && chmod -R 1777 /tmp /var/tmp +RUN mkdir -p /var/lib/alternatives && \ + IMAGE_FLAVOR=nvidia /tmp/image-info.sh && \ + /tmp/nvidia-install.sh && \ + mv /var/lib/alternatives /staged-alternatives && \ + rm -rf /tmp/* /var/* && \ + ostree container commit && \ + mkdir -p /var/lib && mv /staged-alternatives /var/lib/alternatives && \ + mkdir -p /tmp /var/tmp && \ + chmod -R 1777 /tmp /var/tmp diff --git a/README.md b/README.md index be28347..ab5307e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# Nvidia +# HWE -[![build-38](https://github.com/ublue-os/nvidia/actions/workflows/build-38.yml/badge.svg)](https://github.com/ublue-os/nvidia/actions/workflows/build-38.yml) [![build-39](https://github.com/ublue-os/nvidia/actions/workflows/build-39.yml/badge.svg)](https://github.com/ublue-os/nvidia/actions/workflows/build-39.yml) +[![build-38](https://github.com/ublue-os/hwe/actions/workflows/build-38.yml/badge.svg)](https://github.com/ublue-os/hwe/actions/workflows/build-38.yml) [![build-39](https://github.com/ublue-os/hwe/actions/workflows/build-39.yml/badge.svg)](https://github.com/ublue-os/hwe/actions/workflows/build-39.yml) -The purpose of these images is to provide [community Fedora images](https://github.com/ublue-os/main) with Nvidia drivers built-in. This approach can lead to greater reliability as failures can be caught at the build level instead of the client machine. This also allows for individual sets of images for each series of Nvidia drivers, allowing users to remain current with their OS but on an older, known working driver. Performance regression with a recent driver update? Reboot into a known-working driver after one command. That's the goal! +The purpose of these images is to provide [community Fedora images](https://github.com/ublue-os/main) with hardware enablement (ASUS and Surface) and Nvidia. This approach can lead to greater reliability as failures can be caught at the build level instead of the client machine. This also allows for individual sets of images for each series of Nvidia drivers, allowing users to remain current with their OS but on an older, known working driver. Performance regression with a recent driver update? Reboot into a known-working driver after one command. That's the goal! # Documentation - [Main website and documentation](https://universal-blue.org) -- [Documentation for these images](https://universal-blue.org/images/nvidia) +- [Documentation for these images](https://universal-blue.org/images/) - [Installation](https://universal-blue.org/installation/) - follow this for clean installation - [Rebase instructions](https://universal-blue.org/images/) - follow this if you want to switch to another image. diff --git a/asus/packages.json b/asus/packages.json new file mode 100644 index 0000000..24d9703 --- /dev/null +++ b/asus/packages.json @@ -0,0 +1,14 @@ +{ + "all": { + "include": { + "all": [ + "asusctl", + "asusctl-rog-gui", + "fprintd" + ] + }, + "exclude": { + "all": [] + } + } +} diff --git a/asus/system_files/shared/usr/share/wireplumber/main.lua.d/50-alsa-config.lua b/asus/system_files/shared/usr/share/wireplumber/main.lua.d/50-alsa-config.lua new file mode 100644 index 0000000..4ebc988 --- /dev/null +++ b/asus/system_files/shared/usr/share/wireplumber/main.lua.d/50-alsa-config.lua @@ -0,0 +1,155 @@ +alsa_monitor.enabled = true + +alsa_monitor.properties = { + -- Create a JACK device. This is not enabled by default because + -- it requires that the PipeWire JACK replacement libraries are + -- not used by the session manager, in order to be able to + -- connect to the real JACK server. + --["alsa.jack-device"] = false, + + -- Reserve devices via org.freedesktop.ReserveDevice1 on D-Bus + -- Disable if you are running a system-wide instance, which + -- doesn't have access to the D-Bus user session + ["alsa.reserve"] = true, + --["alsa.reserve.priority"] = -20, + --["alsa.reserve.application-name"] = "WirePlumber", + + -- Enables MIDI functionality + ["alsa.midi"] = true, + + -- Enables monitoring of alsa MIDI devices + ["alsa.midi.monitoring"] = true, + + -- MIDI bridge node properties + ["alsa.midi.node-properties"] = { + -- Name set for the node with ALSA MIDI ports + ["node.name"] = "Midi-Bridge", + -- Removes longname/number from MIDI port names + --["api.alsa.disable-longname"] = true, + }, + + -- These properties override node defaults when running in a virtual machine. + -- The rules below still override those. + ["vm.node.defaults"] = { + ["api.alsa.period-size"] = 256, + ["api.alsa.headroom"] = 8192, + }, +} + +alsa_monitor.rules = { + -- An array of matches/actions to evaluate. + -- + -- If you want to disable some devices or nodes, you can apply properties per device as the following example. + -- The name can be found by running pw-cli ls Device, or pw-cli dump Device + --{ + -- matches = { + -- { + -- { "device.name", "matches", "name_of_some_disabled_card" }, + -- }, + -- }, + -- apply_properties = { + -- ["device.disabled"] = true, + -- }, + --} + { + -- Rules for matching a device or node. It is an array of + -- properties that all need to match the regexp. If any of the + -- matches work, the actions are executed for the object. + matches = { + { + -- This matches all cards. + { "device.name", "matches", "alsa_card.*" }, + }, + }, + -- Apply properties on the matched object. + apply_properties = { + -- Use ALSA-Card-Profile devices. They use UCM or the profile + -- configuration to configure the device and mixer settings. + ["api.alsa.use-acp"] = true, + + -- Use UCM instead of profile when available. Can be + -- disabled to skip trying to use the UCM profile. + --["api.alsa.use-ucm"] = true, + + -- Don't use the hardware mixer for volume control. It + -- will only use software volume. The mixer is still used + -- to mute unused paths based on the selected port. + --["api.alsa.soft-mixer"] = false, + + -- Ignore decibel settings of the driver. Can be used to + -- work around buggy drivers that report wrong values. + --["api.alsa.ignore-dB"] = false, + + -- The profile set to use for the device. Usually this is + -- "default.conf" but can be changed with a udev rule or here. + --["device.profile-set"] = "profileset-name", + + -- The default active profile. Is by default set to "Off". + --["device.profile"] = "default profile name", + + -- Automatically select the best profile. This is the + -- highest priority available profile. This is disabled + -- here and instead implemented in the session manager + -- where it can save and load previous preferences. + ["api.acp.auto-profile"] = false, + + -- Automatically switch to the highest priority available port. + -- This is disabled here and implemented in the session manager instead. + ["api.acp.auto-port"] = false, + + -- Other properties can be set here. + --["device.nick"] = "My Device", + }, + }, + { + matches = { + { + -- Matches all sources. + { "node.name", "matches", "alsa_input.*" }, + }, + { + -- Matches all sinks. + { "node.name", "matches", "alsa_output.*" }, + }, + }, + apply_properties = { + --["node.nick"] = "My Node", + --["node.description"] = "My Node Description", + --["priority.driver"] = 100, + --["priority.session"] = 100, + --["node.pause-on-idle"] = false, + --["monitor.channel-volumes"] = false + --["resample.quality"] = 4, + --["resample.disable"] = false, + --["channelmix.normalize"] = false, + --["channelmix.mix-lfe"] = false, + --["channelmix.upmix"] = true, + --["channelmix.upmix-method"] = "psd", -- "none" or "simple" + --["channelmix.lfe-cutoff"] = 150, + --["channelmix.fc-cutoff"] = 12000, + --["channelmix.rear-delay"] = 12.0, + --["channelmix.stereo-widen"] = 0.0, + --["channelmix.hilbert-taps"] = 0, + --["channelmix.disable"] = false, + --["dither.noise"] = 0, + --["dither.method"] = "none", -- "rectangular", "triangular" or "shaped5" + --["audio.channels"] = 2, + --["audio.format"] = "S16LE", + --["audio.rate"] = 44100, + --["audio.allowed-rates"] = "32000,96000", + --["audio.position"] = "FL,FR", + --["api.alsa.period-size"] = 1024, + --["api.alsa.period-num"] = 2, + --["api.alsa.headroom"] = 1024, + --["api.alsa.start-delay"] = 0, + --["api.alsa.disable-mmap"] = false, + --["api.alsa.disable-batch"] = false, + --["api.alsa.use-chmap"] = false, + --["api.alsa.multirate"] = true, + --["latency.internal.rate"] = 0 + --["latency.internal.ns"] = 0 + --["clock.name"] = "api.alsa.0" + --["session.suspend-timeout-seconds"] = 5, -- 0 disables suspend + }, + }, +} diff --git a/install.sh b/install.sh index 9cb0f4c..7d59d33 100755 --- a/install.sh +++ b/install.sh @@ -1,11 +1,19 @@ -#!/bin/sh +#!/bin/bash set -ouex pipefail -if [[ "${FEDORA_MAJOR_VERSION}" -le 38 ]]; then - sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/fedora-{cisco-openh264,modular,updates-modular}.repo -else - sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/fedora-cisco-openh264.repo +RELEASE="$(rpm -E %fedora)" + +if [ "${HWE_FLAVOR}" = "main" ]; then + # HWE_FLAVOR is main, no need to do anything + exit 0 +fi + +# after F40 launches, bump to 41 +if [[ "${FEDORA_MAJOR_VERSION}" -ge 40 ]]; then + # note: this is done before single mirror hack to ensure this persists in image and is not reset + # pre-release rpmfusion is in a different location + sed -i "s%free/fedora/releases%free/fedora/development%" /etc/yum.repos.d/rpmfusion-*.repo fi if [ -n "${RPMFUSION_MIRROR}" ]; then @@ -13,33 +21,77 @@ if [ -n "${RPMFUSION_MIRROR}" ]; then echo "Using single rpmfusion mirror: ${RPMFUSION_MIRROR}" sed -i.bak "s%^metalink=%#metalink=%" /etc/yum.repos.d/rpmfusion-*.repo sed -i "s%^#baseurl=http://download1.rpmfusion.org%baseurl=${RPMFUSION_MIRROR}%" /etc/yum.repos.d/rpmfusion-*.repo - # after F40 launches, bump to 41 - if [[ "${FEDORA_MAJOR_VERSION}" -ge 40 ]]; then - sed -i "s%free/fedora/releases%free/fedora/development%" /etc/yum.repos.d/rpmfusion-*.repo - fi fi -rpm-ostree install \ - /tmp/akmods-rpms/ublue-os/ublue-os-nvidia-addons-*.rpm +# do HWE specific things +if [ "${HWE_FLAVOR}" = "asus" ]; then + echo "install.sh: steps for HWE_FLAVOR: ${HWE_FLAVOR}" + # Install Asus kernel + wget https://copr.fedorainfracloud.org/coprs/lukenukem/asus-linux/repo/fedora-${RELEASE}/lukenukem-asus-linux-fedora-${RELEASE}.repo -O /etc/yum.repos.d/_copr_lukenukem-asus-linux.repo + wget https://copr.fedorainfracloud.org/coprs/lukenukem/asus-kernel/repo/fedora-${RELEASE}/lukenukem-asus-kernel-fedora-${RELEASE}repo -O /etc/yum.repos.d/_copr_lukenukem-asus-kernel.repo + rpm-ostree cliwrap install-to-root / + rpm-ostree override replace \ + --experimental \ + --from repo=copr:copr.fedorainfracloud.org:lukenukem:asus-kernel \ + kernel \ + kernel-core \ + kernel-modules \ + kernel-modules-core \ + kernel-modules-extra + git clone https://gitlab.com/asus-linux/firmware.git --depth 1 /tmp/asus-firmware + cp -rf /tmp/asus-firmware/* /usr/lib/firmware/ + rm -rf /tmp/asus-firmware +elif [ "${HWE_FLAVOR}" = "surface" ]; then + echo "install.sh: steps for HWE_FLAVOR: ${HWE_FLAVOR}" + # Install Surface kernel + wget https://pkg.surfacelinux.com/fedora/linux-surface.repo -P /etc/yum.repos.d + wget https://github.com/linux-surface/linux-surface/releases/download/silverblue-20201215-1/kernel-20201215-1.x86_64.rpm -O /tmp/surface-kernel.rpm + rpm-ostree cliwrap install-to-root / + rpm-ostree override replace /tmp/surface-kernel.rpm \ + --remove kernel-core \ + --remove kernel-modules \ + --remove kernel-modules-extra \ + --remove libwacom \ + --remove libwacom-data \ + --install kernel-surface \ + --install iptsd \ + --install libwacom-surface \ + --install libwacom-surface-data +else + echo "install.sh: steps for unexpected HWE_FLAVOR: ${HWE_FLAVOR}" +fi -source /tmp/akmods-rpms/kmods/nvidia-vars.${NVIDIA_MAJOR_VERSION} +# copy any shared sys files +if [ -d "/tmp/system_files/shared" ]; then + rsync -rvK /tmp/system_files/shared/ / +fi -if [[ "${IMAGE_NAME}" == "kinoite" ]]; then - VARIANT_PKGS="supergfxctl-plasmoid supergfxctl" -elif [[ "${IMAGE_NAME}" == "silverblue" ]]; then - VARIANT_PKGS="gnome-shell-extension-supergfxctl-gex supergfxctl" -else - VARIANT_PKGS="" +# copy any flavor specific files, eg silverblue +if [ -d "/tmp/system_files/${IMAGE_NAME}" ]; then + rsync -rvK /tmp/system_files/"${IMAGE_NAME}"/ / fi -rpm-ostree install \ - xorg-x11-drv-${NVIDIA_PACKAGE_NAME}-{,cuda-,devel-,kmodsrc-,power-}${NVIDIA_FULL_VERSION} \ - xorg-x11-drv-${NVIDIA_PACKAGE_NAME}-libs.i686 \ - nvidia-container-toolkit nvidia-vaapi-driver ${VARIANT_PKGS} \ - /tmp/akmods-rpms/kmods/kmod-${NVIDIA_PACKAGE_NAME}-${KERNEL_VERSION}-${NVIDIA_AKMOD_VERSION}.fc${RELEASE}.rpm +# install any packages from packages.json +if [ -f "/tmp/packages.json" ]; then + /tmp/packages.sh /tmp/packages.json +fi + +# do HWE specific post-install things +if [ "${HWE_FLAVOR}" = "asus" ]; then + echo "install.sh: post-install for: ${HWE_FLAVOR}" +elif [ "${HWE_FLAVOR}" = "surface" ]; then + echo "install.sh: post-install for: ${HWE_FLAVOR}" + if grep -q "silverblue" <<< "${IMAGE_NAME}"; then + systemctl enable dconf-update + fi + systemctl enable fprintd + systemctl enable surface-hardware-setup +else + echo "install.sh: post-install for unexpected HWE_FLAVOR: ${HWE_FLAVOR}" +fi if [ -n "${RPMFUSION_MIRROR}" ]; then # reset forced use of single rpmfusion mirror echo "Revert from single rpmfusion mirror: ${RPMFUSION_MIRROR}" rename -v .repo.bak .repo /etc/yum.repos.d/rpmfusion-*repo.bak -fi +fi \ No newline at end of file diff --git a/main/.gitkeep b/main/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/nvidia-install.sh b/nvidia-install.sh new file mode 100755 index 0000000..e26ff5e --- /dev/null +++ b/nvidia-install.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +set -ouex pipefail + +RELEASE="$(rpm -E %fedora)" + +if [[ "${FEDORA_MAJOR_VERSION}" -le 38 ]]; then + sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/fedora-{cisco-openh264,modular,updates-modular}.repo +else + sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/fedora-cisco-openh264.repo +fi + +# after F40 launches, bump to 41 +if [[ "${FEDORA_MAJOR_VERSION}" -ge 40 ]]; then + # note: this is done before single mirror hack to ensure this persists in image and is not reset + # pre-release rpmfusion is in a different location + sed -i "s%free/fedora/releases%free/fedora/development%" /etc/yum.repos.d/rpmfusion-*.repo +fi + +if [ -n "${RPMFUSION_MIRROR}" ]; then + # force use of single rpmfusion mirror + echo "Using single rpmfusion mirror: ${RPMFUSION_MIRROR}" + sed -i.bak "s%^metalink=%#metalink=%" /etc/yum.repos.d/rpmfusion-*.repo + sed -i "s%^#baseurl=http://download1.rpmfusion.org%baseurl=${RPMFUSION_MIRROR}%" /etc/yum.repos.d/rpmfusion-*.repo +fi + + +# nvidia install steps +rpm-ostree install /tmp/akmods-rpms/ublue-os/ublue-os-nvidia-addons-*.rpm + +source /tmp/akmods-rpms/kmods/nvidia-vars.${NVIDIA_MAJOR_VERSION} + +if [[ "${IMAGE_NAME}" == "kinoite" ]]; then + VARIANT_PKGS="supergfxctl-plasmoid supergfxctl" +elif [[ "${IMAGE_NAME}" == "silverblue" ]]; then + VARIANT_PKGS="gnome-shell-extension-supergfxctl-gex supergfxctl" +else + VARIANT_PKGS="" +fi + +rpm-ostree install \ + xorg-x11-drv-${NVIDIA_PACKAGE_NAME}-{,cuda-,devel-,kmodsrc-,power-}${NVIDIA_FULL_VERSION} \ + xorg-x11-drv-${NVIDIA_PACKAGE_NAME}-libs.i686 \ + nvidia-container-toolkit nvidia-vaapi-driver ${VARIANT_PKGS} \ + /tmp/akmods-rpms/kmods/kmod-${NVIDIA_PACKAGE_NAME}-${KERNEL_VERSION}-${NVIDIA_AKMOD_VERSION}.fc${RELEASE}.rpm + + +# nvidia post-install steps +sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/{eyecantcu-supergfxctl,nvidia-container-toolkit}.repo + +systemctl enable ublue-nvctk-cdi.service +semodule --verbose --install /usr/share/selinux/packages/nvidia-container.pp + +if [[ "${IMAGE_NAME}" == "sericea" ]]; then + mv /etc/sway/environment{,.orig} + install -Dm644 /usr/share/ublue-os/etc/sway/environment /etc/sway/environment +fi + + +if [ -n "${RPMFUSION_MIRROR}" ]; then + # reset forced use of single rpmfusion mirror + echo "Revert from single rpmfusion mirror: ${RPMFUSION_MIRROR}" + rename -v .repo.bak .repo /etc/yum.repos.d/rpmfusion-*repo.bak +fi diff --git a/packages.sh b/packages.sh new file mode 100755 index 0000000..c75e27f --- /dev/null +++ b/packages.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -ouex pipefail + +RELEASE="$(rpm -E %fedora)" + +# build list of all packages requested for inclusion +INCLUDED_PACKAGES=($(jq -r "[(.all.include | (.all, select(.\"$IMAGE_NAME\" != null).\"$IMAGE_NAME\")[]), \ + (select(.\"$FEDORA_MAJOR_VERSION\" != null).\"$FEDORA_MAJOR_VERSION\".include | (.all, select(.\"$IMAGE_NAME\" != null).\"$IMAGE_NAME\")[])] \ + | sort | unique[]" /tmp/packages.json)) + +# build list of all packages requested for exclusion +EXCLUDED_PACKAGES=($(jq -r "[(.all.exclude | (.all, select(.\"$IMAGE_NAME\" != null).\"$IMAGE_NAME\")[]), \ + (select(.\"$FEDORA_MAJOR_VERSION\" != null).\"$FEDORA_MAJOR_VERSION\".exclude | (.all, select(.\"$IMAGE_NAME\" != null).\"$IMAGE_NAME\")[])] \ + | sort | unique[]" /tmp/packages.json)) + + +# ensure exclusion list only contains packages already present on image +if [[ "${#EXCLUDED_PACKAGES[@]}" -gt 0 ]]; then + EXCLUDED_PACKAGES=($(rpm -qa --queryformat='%{NAME} ' ${EXCLUDED_PACKAGES[@]})) +fi + +# simple case to install where no packages need excluding +if [[ "${#INCLUDED_PACKAGES[@]}" -gt 0 && "${#EXCLUDED_PACKAGES[@]}" -eq 0 ]]; then + rpm-ostree install \ + ${INCLUDED_PACKAGES[@]} + +# install/excluded packages both at same time +elif [[ "${#INCLUDED_PACKAGES[@]}" -gt 0 && "${#EXCLUDED_PACKAGES[@]}" -gt 0 ]]; then + rpm-ostree override remove \ + ${EXCLUDED_PACKAGES[@]} \ + $(printf -- "--install=%s " ${INCLUDED_PACKAGES[@]}) + +else + echo "No packages to install." + +fi + +# check if any excluded packages are still present +# (this can happen if an included package pulls in a dependency) +EXCLUDED_PACKAGES=($(jq -r "[(.all.exclude | (.all, select(.\"$IMAGE_NAME\" != null).\"$IMAGE_NAME\")[]), \ + (select(.\"$FEDORA_MAJOR_VERSION\" != null).\"$FEDORA_MAJOR_VERSION\".exclude | (.all, select(.\"$IMAGE_NAME\" != null).\"$IMAGE_NAME\")[])] \ + | sort | unique[]" /tmp/packages.json)) + +if [[ "${#EXCLUDED_PACKAGES[@]}" -gt 0 ]]; then + EXCLUDED_PACKAGES=($(rpm -qa --queryformat='%{NAME} ' ${EXCLUDED_PACKAGES[@]})) +fi + +# remove any excluded packages which are still present on image +if [[ "${#EXCLUDED_PACKAGES[@]}" -gt 0 ]]; then + rpm-ostree override remove \ + ${EXCLUDED_PACKAGES[@]} +fi diff --git a/post-install.sh b/post-install.sh deleted file mode 100755 index 6b7d0d9..0000000 --- a/post-install.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -set -ouex pipefail - -sed -i 's@enabled=1@enabled=0@g' /etc/yum.repos.d/{eyecantcu-supergfxctl,nvidia-container-toolkit}.repo - -systemctl enable ublue-nvctk-cdi.service -semodule --verbose --install /usr/share/selinux/packages/nvidia-container.pp - -if [[ "${IMAGE_NAME}" == "sericea" ]]; then - mv /etc/sway/environment{,.orig} - install -Dm644 /usr/share/ublue-os/etc/sway/environment /etc/sway/environment -fi diff --git a/surface/packages.json b/surface/packages.json new file mode 100644 index 0000000..ba83fee --- /dev/null +++ b/surface/packages.json @@ -0,0 +1,12 @@ +{ + "all": { + "include": { + "all": [ + "fprintd" + ] + }, + "exclude": { + "all": [] + } + } +} diff --git a/surface/system_files/shared/usr/bin/surface-hardware-setup b/surface/system_files/shared/usr/bin/surface-hardware-setup new file mode 100755 index 0000000..82f1c99 --- /dev/null +++ b/surface/system_files/shared/usr/bin/surface-hardware-setup @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +INITRAMFS=$(rpm-ostree initramfs-etc) +SURFACE_INITRAMFS=("/etc/crypttab") +APPLY_INITRAMFS=false + +echo "Current initramfs: $INITRAMFS" + +SURFACE_INITRAMFS+=("/etc/modules-load.d/ublue-surface.conf") + +# Verify initramfs options are applied +for ARG in ${SURFACE_INITRAMFS[@]}; do + if [[ ! $INITRAMFS =~ "$ARG" ]]; then + APPLY_INITRAMFS=true + fi +done + +# Update initramfs +if $APPLY_INITRAMFS; then + echo "Found needed initramfs changes, applying the following: ${SURFACE_INITRAMFS[*]}" + plymouth display-message --text="Updating initramfs - System will reboot" || true + rpm-ostree initramfs-etc "${SURFACE_INITRAMFS[@]/#/--track=}" --reboot +else + echo "No initramfs changes needed" +fi diff --git a/surface/system_files/shared/usr/etc/modules-load.d/ublue-surface.conf b/surface/system_files/shared/usr/etc/modules-load.d/ublue-surface.conf new file mode 100644 index 0000000..c55aa21 --- /dev/null +++ b/surface/system_files/shared/usr/etc/modules-load.d/ublue-surface.conf @@ -0,0 +1,23 @@ +# Add modules necessary for Disk Encryption via keyboard +surface_aggregator +surface_aggregator_registry +surface_aggregator_hub +surface_hid_core +8250_dw + +# Surface Laptop 3/Surface Book 3 and later +surface_hid +surface_kbd + +# Only on AMD models +pinctrl_amd + +# Only on Intel models +intel_lpss +intel_lpss_pci + +# For Surface Laptop 3/Surface Book 3 +pinctrl_icelake + +# For Surface Laptop 4/Surface Laptop Studio +pinctrl_tigerlake diff --git a/surface/system_files/shared/usr/lib/systemd/system/surface-hardware-setup.service b/surface/system_files/shared/usr/lib/systemd/system/surface-hardware-setup.service new file mode 100644 index 0000000..ad4d7dd --- /dev/null +++ b/surface/system_files/shared/usr/lib/systemd/system/surface-hardware-setup.service @@ -0,0 +1,12 @@ +[Unit] +Description=Configure Surface hardware +After=rpm-ostreed.service +Before=systemd-user-sessions.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/surface-hardware-setup + +[Install] +WantedBy=multi-user.target diff --git a/surface/system_files/silverblue/usr/etc/dconf/db/local.d/01-ublue-surface b/surface/system_files/silverblue/usr/etc/dconf/db/local.d/01-ublue-surface new file mode 100644 index 0000000..07e9a55 --- /dev/null +++ b/surface/system_files/silverblue/usr/etc/dconf/db/local.d/01-ublue-surface @@ -0,0 +1,7 @@ + + +[org/gnome/desktop/peripherals/touchpad] +tap-to-click=true + +[org/gnome/mutter] +experimental-features=['scale-monitor-framebuffer'] diff --git a/surface/system_files/silverblue/usr/lib/systemd/system/dconf-update.service b/surface/system_files/silverblue/usr/lib/systemd/system/dconf-update.service new file mode 100644 index 0000000..8311c6f --- /dev/null +++ b/surface/system_files/silverblue/usr/lib/systemd/system/dconf-update.service @@ -0,0 +1,10 @@ +[Unit] +Description=Update the dconf database onboot +Documentation=https://github.com/coreos/rpm-ostree/issues/1944 + +[Service] +Type=oneshot +ExecStart=/usr/bin/dconf update + +[Install] +WantedBy=multi-user.target