From 7cfb40700370423a812ef007bc79b21ae7fe09a5 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Wed, 23 Oct 2024 12:43:53 -0500 Subject: [PATCH 1/8] docs: add image-template link in DIY section (#205) --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index c38d536..642e178 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Please take a look at the included modifications, and help us improve uCore if t - [ZFS](#zfs) - [ZFS and immutable root filesystem](#zfs-and-immutable-root-filesystem) - [Sanoid/Syncoid](#sanoidsyncoid) +- [DIY](#diy) - [Metrics](#metrics) ## Features @@ -517,6 +518,12 @@ sanoid/syncoid is a great tool for manual and automated snapshot/transfer of ZFS `ucore` has pre-install all the (lightweight) required dependencies (perl-Config-IniFiles perl-Data-Dumper perl-Capture-Tiny perl-Getopt-Long lzop mbuffer mhash pv), such that a user wishing to use sanoid/syncoid only need install the "sbin" files and create configuration/systemd units for it. +## DIY + +Is all this too easy, leaving you with the desire to create a custom uCore image? + +Then [create an image `FROM ucore`](https://github.com/ublue-os/image-template) using our [image template](https://github.com/ublue-os/image-template)! + ## Metrics ![Alt](https://repobeats.axiom.co/api/embed/07d1ed133f5ed1a1048ea6a76bfe3a23227eedd5.svg "Repobeats analytics image") From c1db889854a69789a13746c6e6bac406060f3ee9 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Tue, 12 Nov 2024 11:17:46 -0600 Subject: [PATCH 2/8] chore: temporarily pause stable scheduled builds (#208) --- .github/workflows/build-stable.yml | 8 +++++--- .github/workflows/build-testing.yml | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-stable.yml b/.github/workflows/build-stable.yml index 8970aa0..9b1668e 100644 --- a/.github/workflows/build-stable.yml +++ b/.github/workflows/build-stable.yml @@ -1,9 +1,11 @@ name: stable on: - pull_request: merge_group: - schedule: - - cron: '50 2 * * *' # 2:50am-ish UTC everyday (approx 45 minutes after akmods images run) + pull_request: + branches: + - main + #schedule: + # - cron: '50 2 * * *' # 2:50am-ish UTC everyday (approx 45 minutes after akmods images run) workflow_dispatch: jobs: diff --git a/.github/workflows/build-testing.yml b/.github/workflows/build-testing.yml index e36766e..8d29d9d 100644 --- a/.github/workflows/build-testing.yml +++ b/.github/workflows/build-testing.yml @@ -1,7 +1,9 @@ name: testing on: - pull_request: merge_group: + pull_request: + branches: + - main schedule: - cron: '55 2 * * *' # 2:55am-ish UTC everyday (approx 50 minutes after akmods images run) workflow_dispatch: From be48008c8b08e1ef43d578c8f31ec3ff604ccbd6 Mon Sep 17 00:00:00 2001 From: m2 <69128853+m2Giles@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:26:10 -0500 Subject: [PATCH 3/8] chore(ci): Use kernel-cache for kernel-version (#209) Co-authored-by: Benjamin Sherman --- .github/workflows/build-stable.yml | 4 +- .github/workflows/reusable-build.yml | 59 ++++++++++++---------------- README.md | 15 +++++++ 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build-stable.yml b/.github/workflows/build-stable.yml index 9b1668e..4e58f6c 100644 --- a/.github/workflows/build-stable.yml +++ b/.github/workflows/build-stable.yml @@ -4,8 +4,8 @@ on: pull_request: branches: - main - #schedule: - # - cron: '50 2 * * *' # 2:50am-ish UTC everyday (approx 45 minutes after akmods images run) + schedule: + - cron: '50 2 * * *' # 2:50am-ish UTC everyday (approx 45 minutes after akmods images run) workflow_dispatch: jobs: diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index 02c7606..85aa0b3 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -53,12 +53,6 @@ jobs: skopeo inspect docker://quay.io/fedora/fedora-coreos:${{ inputs.coreos_version }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) - if [ -z "$kernel" ] || [ "null" = "$kernel" ]; then - echo "inspected linux (kernel) version must not be empty or null" - exit 1 - fi - image=$(jq -r '.["Labels"]["org.opencontainers.image.version"]' inspect.json) if [ -z "$image" ] || [ "null" = "$image" ]; then echo "inspected image version must not be empty or null" @@ -71,6 +65,13 @@ jobs: exit 1 fi + kernel=$(skopeo inspect docker://ghcr.io/ublue-os/coreos-${{ inputs.coreos_version }}-kernel:${fedora} | jq -r '.["Labels"]["ostree.linux"]') + if [ -z "$kernel" ] || [ "null" = "$kernel" ]; then + echo "inspected linux (kernel) version must not be empty or null" + exit 1 + fi + + echo "kernel=$kernel" >> $GITHUB_OUTPUT echo "image=$image" >> $GITHUB_OUTPUT echo "fedora=$fedora" >> $GITHUB_OUTPUT @@ -142,20 +143,16 @@ jobs: echo "env.KERNEL_VERSION must not be empty or null" exit 1 fi - skopeo inspect docker://quay.io/fedora/fedora-coreos:${{ inputs.coreos_version }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) - if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then - echo "pulled coreos image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" - exit 1 - fi - skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/${{ env.KERNEL_FLAVOR }}-kernel:${{ env.FEDORA_VERSION }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) + + #Use Podman Inspect instead of skopeo for local checks. + podman inspect ${{ env.IMAGE_REGISTRY }}/${{ env.KERNEL_FLAVOR }}-kernel:${{ env.FEDORA_VERSION }} > inspect.json + kernel=$(jq -r '.[]["Config"]["Labels"]["ostree.linux"]' inspect.json) if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then echo "pulled kernel-cache image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" exit 1 fi - skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/akmods:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) + podman inspect ${{ env.IMAGE_REGISTRY }}/akmods:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json + kernel=$(jq -r '.[]["Config"]["Labels"]["ostree.linux"]' inspect.json) if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then echo "pulled akmods image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" exit 1 @@ -166,8 +163,8 @@ jobs: shell: bash run: | set -x - skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/akmods-nvidia:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) + podman inspect ${{ env.IMAGE_REGISTRY }}/akmods-nvidia:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json + kernel=$(jq -r '.[]["Config"]["Labels"]["ostree.linux"]' inspect.json) if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then echo "pulled akmods-nvidia image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" exit 1 @@ -178,8 +175,8 @@ jobs: shell: bash run: | set -x - skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/akmods-zfs:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) + podman inspect ${{ env.IMAGE_REGISTRY }}/akmods-zfs:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json + kernel=$(jq -r '.[]["Config"]["Labels"]["ostree.linux"]' inspect.json) if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then echo "pulled akmods-zfs image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" exit 1 @@ -412,20 +409,14 @@ jobs: echo "env.KERNEL_VERSION must not be empty or null" exit 1 fi - skopeo inspect docker://quay.io/fedora/fedora-coreos:${{ inputs.coreos_version }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) - if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then - echo "pulled coreos image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" - exit 1 - fi - skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/${{ env.KERNEL_FLAVOR }}-kernel:${{ env.FEDORA_VERSION }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) + podman inspect ${{ env.IMAGE_REGISTRY }}/${{ env.KERNEL_FLAVOR }}-kernel:${{ env.FEDORA_VERSION }} > inspect.json + kernel=$(jq -r '.[]["Config"]["Labels"]["ostree.linux"]' inspect.json) if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then echo "pulled kernel-cache image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" exit 1 fi - skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/akmods:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) + podman inspect ${{ env.IMAGE_REGISTRY }}/akmods:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json + kernel=$(jq -r '.[]["Config"]["Labels"]["ostree.linux"]' inspect.json) if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then echo "pulled akmods image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" exit 1 @@ -436,8 +427,8 @@ jobs: shell: bash run: | set -x - skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/akmods-nvidia:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) + podman inspect ${{ env.IMAGE_REGISTRY }}/akmods-nvidia:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json + kernel=$(jq -r '.[]["Config"]["Labels"]["ostree.linux"]' inspect.json) if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then echo "pulled akmods-nvidia image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" exit 1 @@ -448,8 +439,8 @@ jobs: shell: bash run: | set -x - skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/akmods-zfs:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json - kernel=$(jq -r '.["Labels"]["ostree.linux"]' inspect.json) + podman inspect ${{ env.IMAGE_REGISTRY }}/akmods-zfs:${{ env.KERNEL_FLAVOR }}-${{ env.FEDORA_VERSION }} > inspect.json + kernel=$(jq -r '.[]["Config"]["Labels"]["ostree.linux"]' inspect.json) if [[ "${{ env.KERNEL_VERSION }}" != "$kernel"* ]]; then echo "pulled akmods-zfs image kernel ($kernel) does not match expected kernel (${{ env.KERNEL_VERSION }})" exit 1 diff --git a/README.md b/README.md index 642e178..bde1c3c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Please take a look at the included modifications, and help us improve uCore if t ## Table of Contents +- [Announcements](#announcements) - [Features](#features) - [Images](#images) - [`fedora-coreos`](#fedora-coreos) @@ -43,6 +44,20 @@ Please take a look at the included modifications, and help us improve uCore if t - [DIY](#diy) - [Metrics](#metrics) +## Announcements + +### 2024.11.12 - uCore has updated to Fedora 41 + +As of today our upstream Fedora CoreOS stable image updated to Fedora 41 under the hood, so expect a lot of package updates. + +### 2024.11.12 - uCore *stable* has pinned to kernel version *6.11.3* + +Kernel version `6.11.3` was the previous *stable* update's kernel, and despite the update to Fedora 41, we've stuck with `6.11.3` rather than updating to `6.11.5` from upstream. + +This is due to a kernel bug in versions `6.11.4`/`6.11.5` which [breaks tailscale status reporting](https://github.com/tailscale/tailscale/issues/13863). As many users of uCore do use tailscale, we've decided to be extra cautious and hold back the kernel, even though the rest of stable updated as usual. + +We expect the next update of Fedora CoreOS to be on `6.11.6` per the current state of the testing stream. So uCore will follow when that update occurs. + ## Features The uCore project builds four images, each with different tags for different features. From 71222dddd7816584b4d30d9670175a6bdb95a489 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:22:12 -0600 Subject: [PATCH 4/8] chore(deps): bump sigstore/cosign-installer from 3.6.0 to 3.7.0 (#203) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/reusable-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index 85aa0b3..bb2ed81 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -311,7 +311,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} # Sign container - - uses: sigstore/cosign-installer@v3.6.0 + - uses: sigstore/cosign-installer@v3.7.0 if: github.event_name != 'pull_request' - name: Sign container image @@ -581,7 +581,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} # Sign container - - uses: sigstore/cosign-installer@v3.6.0 + - uses: sigstore/cosign-installer@v3.7.0 if: github.event_name != 'pull_request' - name: Sign container image From 794f61d193e46baa5998fcfb9f799d6ad13d07d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:22:22 -0600 Subject: [PATCH 5/8] chore(deps): bump Wandalen/wretry.action from 3.5.0 to 3.7.2 (#207) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/reusable-build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index bb2ed81..b46aa32 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -44,7 +44,7 @@ jobs: steps: - name: Fetch CoreOS stream versions id: fetch - uses: Wandalen/wretry.action@v3.5.0 + uses: Wandalen/wretry.action@v3.7.2 with: attempt_limit: 3 attempt_delay: 15000 @@ -113,7 +113,7 @@ jobs: uses: actions/checkout@v4 - name: Pull base and kmod images - uses: Wandalen/wretry.action@v3.5.0 + uses: Wandalen/wretry.action@v3.7.2 with: attempt_limit: 3 attempt_delay: 15000 @@ -283,7 +283,7 @@ jobs: # Push the image to GHCR (Image Registry) - name: Push To GHCR - uses: Wandalen/wretry.action@v3.5.0 + uses: Wandalen/wretry.action@v3.7.2 id: push if: github.event_name != 'pull_request' env: @@ -379,7 +379,7 @@ jobs: echo "IMAGE_NAME=$IMAGE_NAME" >> $GITHUB_ENV - name: Pull base and kmod images - uses: Wandalen/wretry.action@v3.5.0 + uses: Wandalen/wretry.action@v3.7.2 with: attempt_limit: 3 attempt_delay: 15000 @@ -553,7 +553,7 @@ jobs: # Push the image to GHCR (Image Registry) - name: Push To GHCR - uses: Wandalen/wretry.action@v3.5.0 + uses: Wandalen/wretry.action@v3.7.2 id: push if: github.event_name != 'pull_request' env: From b7f87e8840f4ad5b9962b1dbc49ba170239d7cce Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Wed, 13 Nov 2024 19:54:49 -0600 Subject: [PATCH 6/8] fix: possible fix for apparent ZFS depmod fail (#211) --- fedora-coreos/install.sh | 2 +- ucore/install-ucore-minimal.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fedora-coreos/install.sh b/fedora-coreos/install.sh index 8849298..78b8dbc 100755 --- a/fedora-coreos/install.sh +++ b/fedora-coreos/install.sh @@ -53,7 +53,7 @@ fi if [[ "-zfs" == "${ZFS_TAG}" ]]; then rpm-ostree install pv /tmp/rpms/akmods-zfs/kmods/zfs/*.rpm /tmp/rpms/akmods-zfs/kmods/zfs/other/zfs-dracut-*.rpm # for some reason depmod ran automatically with zfs 2.1 but not with 2.2 - depmod -A ${KERNEL_VERSION} + depmod -a -v ${KERNEL_VERSION} fi ## CONDITIONAL: install NVIDIA diff --git a/ucore/install-ucore-minimal.sh b/ucore/install-ucore-minimal.sh index 5d080f4..0e01470 100755 --- a/ucore/install-ucore-minimal.sh +++ b/ucore/install-ucore-minimal.sh @@ -56,7 +56,7 @@ fi if [[ "-zfs" == "${ZFS_TAG}" ]]; then rpm-ostree install pv /tmp/rpms/akmods-zfs/kmods/zfs/*.rpm /tmp/rpms/akmods-zfs/kmods/zfs/other/zfs-dracut-*.rpm # for some reason depmod ran automatically with zfs 2.1 but not with 2.2 - depmod -A ${KERNEL_VERSION} + depmod -a -v ${KERNEL_VERSION} fi ## CONDITIONAL: install NVIDIA From d544752c48c968668661cb33407d85be59e4b498 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Thu, 14 Nov 2024 09:28:43 -0600 Subject: [PATCH 7/8] docs: add warning about rebase from non-FCOS systems (#212) --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bde1c3c..2f6c806 100644 --- a/README.md +++ b/README.md @@ -174,14 +174,15 @@ Hyper-Coverged Infrastructure(HCI) refers to storage and hypervisor in one place ## Installation -**Please read the [CoreOS installation guide](https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/)** before attempting installation. As uCore is an extension of CoreOS, it does not provide it's own custom or GUI installer. +> [!IMPORTANT] +> **Read the [CoreOS installation guide](https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/)** before attempting installation. uCore extends Fedora CoreOS; it does not provide it's own custom or GUI installer. There are varying methods of installation for bare metal, cloud providers, and virtualization platforms. **All CoreOS installation methods require the user to [produce an Ignition file](https://docs.fedoraproject.org/en-US/fedora-coreos/producing-ign/).** This Ignition file should, at mimimum, set a password and SSH key for the default user (default username is `core`). -> [!NOTE] -> It is highly recommended that for bare metal installs, first test your ignition configuration by installing in a VM (or other test hardware) using the same bare metal process. +> [!TIP] +> For bare metal installs, first test your ignition configuration by installing in a VM (or other test hardware) using the bare metal process. ### Image Verification @@ -203,7 +204,11 @@ One of the fastest paths to running uCore is using [examples/ucore-autorebase.bu Once a machine is running any Fedora CoreOS version, you can easily rebase to uCore. Installing CoreOS itself can be done through [a number of provisioning methods](https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/). -To rebase an existing machine to the latest uCore: +> [!WARNING] +> **Rebasing from Fedora IoT or Atomic Desktops is not supported!** +> If ignition doesn't provide a desired feature, then Fedora CoreOS doesn't support that feature. Rebasing from another system to gain a filesystem feature or GUI installation is very likely to cause problems later on. + +To rebase an existing CoreOS machine to the latest uCore: 1. Execute the `rpm-ostree rebase` command (below) with desired `IMAGE` and `TAG`. 1. Reboot, as instructed. From 27d8fcde3cc799eed4ac5bf4f7ffeecd41af5024 Mon Sep 17 00:00:00 2001 From: Benjamin Sherman Date: Thu, 14 Nov 2024 13:40:38 -0600 Subject: [PATCH 8/8] fix: restore mergerfs in f41 (#213) --- ucore/install-ucore.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ucore/install-ucore.sh b/ucore/install-ucore.sh index 4bcd4b7..cfe6a43 100755 --- a/ucore/install-ucore.sh +++ b/ucore/install-ucore.sh @@ -14,7 +14,15 @@ export IMAGE_NAME=ucore /ctx/packages.sh # install packages direct from github -/ctx/github-release-install.sh trapexit/mergerfs fc${RELEASE}.x86_64 +# Fedora 41 packages missing for mergerfs +#/ctx/github-release-install.sh trapexit/mergerfs fc${RELEASE}.x86_64 +curl --fail --retry 5 --retry-delay 5 --retry-all-errors -sSL -o /tmp/mfs-api.json \ + "https://api.github.com/repos/trapexit/mergerfs/releases/latest" +MFS_TGZ_URL=$(cat /tmp/mfs-api.json | \ + jq -r --arg arch_filter "linux_amd64" \ + '.assets | sort_by(.created_at) | reverse | .[] | select(.name|test($arch_filter)) | select (.name|test("tar.gz$")) | .browser_download_url') +curl -sSL -o /tmp/mergerfs.tar.gz "${MFS_TGZ_URL}" +tar -zxvf /tmp/mergerfs.tar.gz -C /usr --strip-components=2 # tweak os-release sed -i '/^PRETTY_NAME/s/(uCore.*$/(uCore)"/' /usr/lib/os-release