Last active
October 4, 2023 20:08
-
-
Save swick/968453815a1e918f0f0f56faff310a80 to your computer and use it in GitHub Desktop.
silverblue-devel-utils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -euo pipefail | |
#set -x | |
MICRODNF_PACKAGES_F38="https://kojipkgs.fedoraproject.org//packages/microdnf/3.9.0/2.fc38/x86_64/microdnf-3.9.0-2.fc38.x86_64.rpm \ | |
https://kojipkgs.fedoraproject.org//packages/libpeas/1.34.0/3.fc38/x86_64/libpeas-1.34.0-3.fc38.x86_64.rpm \ | |
https://kojipkgs.fedoraproject.org//packages/dnf/4.14.0/2.fc38/noarch/dnf-data-4.14.0-2.fc38.noarch.rpm \ | |
https://kojipkgs.fedoraproject.org//packages/libdnf/0.68.0/2.fc38/x86_64/libdnf-0.68.0-2.fc38.x86_64.rpm" | |
MICRODNF_PACKAGES_F39="https://kojipkgs.fedoraproject.org/packages/microdnf/3.9.0/3.fc39/x86_64/microdnf-3.9.0-3.fc39.x86_64.rpm \ | |
https://kojipkgs.fedoraproject.org/packages/dnf/4.17.0/6.fc39/noarch/dnf-data-4.17.0-6.fc39.noarch.rpm \ | |
https://kojipkgs.fedoraproject.org/packages/libdnf/0.71.0/2.fc39/x86_64/libdnf-0.71.0-2.fc39.x86_64.rpm" | |
MICRODNF_PACKAGES_VAR="MICRODNF_PACKAGES_F$(source /etc/os-release && echo $VERSION_ID)" | |
MICRODNF_PACKAGES=${!MICRODNF_PACKAGES_VAR} | |
OCI_ARCHIVE_STORAGE="/var/lib/development-images/" | |
SELF="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" | |
tmpdir=$(mktemp -d) | |
function cleanup () { | |
rm -rf -- "$tmpdir" | |
} | |
trap cleanup EXIT | |
function fail() { | |
printf '%s\n' "$1" >&2 | |
exit "${2-1}" | |
} | |
function usage () | |
{ | |
echo "Utils for developing on a Silverblue system" | |
echo | |
echo "Syntax:" | |
echo "$SELF make_mutable [--temporary]" | |
echo "$SELF unmake_mutable" | |
echo "$SELF cleanup_mutable" | |
echo "$SELF rebase_image <IMAGE>" | |
echo | |
} | |
function install_dnf () | |
{ | |
install="" | |
command -v dnf &> /dev/null && return | |
for url in $MICRODNF_PACKAGES; do | |
package="$tmpdir/$(basename $url)" | |
curl --silent --show-error --remote-name-all --output-dir $tmpdir "$url" || fail "Failed to download package $url" | |
package_name=$(rpm -q --qf '%{name}' "$package") | |
rpm --quiet -q "$package_name" || install="$install $package" | |
done | |
if [ "$install" != "" ] ; then | |
sudo rpm -i --oldpackage $install | |
fi | |
if ! sudo microdnf --assumeyes install dnf python3-dnf-plugins* ; then | |
fail "Failed installing dnf and dnf-plugins!" | |
fi | |
} | |
function make_mutable () | |
{ | |
persistent="${1-persistent}" | |
ostree_flags="" | |
unlocked=$(rpm-ostree status --json | jq -r '.deployments[] | select (.booted==true) | .unlocked') | |
if [ "$persistent" == "persistent" ] ; then | |
[ "$unlocked" == "hotfix" ] && return | |
[ "$unlocked" != "none" ] && fail "The system is in another mutable state!" | |
sudo ostree admin unlock --hotfix | |
else | |
[ "$unlocked" == "development" ] && return | |
[ "$unlocked" != "none" ] && fail "The system is in another mutable state!" | |
sudo ostree admin unlock | |
fi | |
} | |
function unmake_mutable () | |
{ | |
unlocked=$(rpm-ostree status --json | jq -r '.deployments[] | select (.booted==true) | .unlocked') | |
if [ "$unlocked" == "hotfix" ] ; then | |
needs_rollback=$(rpm-ostree status --json | jq -r '.deployments[0].unlocked=="hotfix"') | |
[ $needs_rollback == "true" ] && sudo rpm-ostree rollback | |
echo "Reboot now to return to the previous state and then run '$SELF cleanup'" | |
return | |
fi | |
if [ "$unlocked" == "development" ] ; then | |
echo "The system is only in a temporary mutable state. Reboot to return to the previous state." | |
return | |
fi | |
fail "The system is not in a mutable state!" | |
} | |
function cleanup_mutable () | |
{ | |
should_cleanup=$(rpm-ostree status --json | jq -r '.deployments[1].unlocked == "hotfix" and .deployments[0].unlocked != "hotfix"') | |
if [ "$should_cleanup" == "true" ]; then | |
sudo rpm-ostree cleanup -r | |
else | |
echo "Not cleaning up" | |
fi | |
} | |
function rebase_image () | |
{ | |
image=$1 | |
id=$(podman image inspect --format '{{ .Id }}' "$image") || fail "Inspecting image failed!" | |
image_name="${image#*/}" | |
image_name="${image_name%:*}-${id:0:10}" | |
oci_archive="${OCI_ARCHIVE_STORAGE}/${image_name}" | |
sudo rm -rf "${oci_archive}" | |
sudo mkdir -p "${oci_archive}" | |
podman save --format=oci-archive "${image}" | sudo tar -x -C "${oci_archive}" | |
sudo rpm-ostree rebase "ostree-unverified-image:oci:${oci_archive}" | |
current_origin=$(rpm-ostree status --json | jq -r '.deployments[] | select (.booted==true) | .origin') | |
echo "You can now reboot into your image!" | |
echo "Return to the current system by running 'rpm-ostree rebase $current_origin'." | |
} | |
if [ "$#" -lt 1 ] || [ "$1" == "--help" ] ; then | |
usage | |
exit | |
fi | |
mode=$1 | |
shift | |
if [ "$mode" == "make_mutable" ] ; then | |
if [ "$#" -eq 1 ] && [ "$1" == "--temporary" ] ; then | |
make_mutable temporary | |
install_dnf | |
elif [ "$#" -ge 1 ] ; then | |
usage | |
fail "Unknown parameters!" | |
else | |
make_mutable | |
install_dnf | |
fi | |
elif [ "$mode" == "unmake_mutable" ] ; then | |
unmake_mutable | |
elif [ "$mode" == "cleanup_mutable" ] ; then | |
cleanup_mutable | |
elif [ "$mode" == "rebase_image" ] ; then | |
if [ "$#" -lt 1 ] ; then | |
usage | |
fail "Image parameter missing!" | |
fi | |
rebase_image "$1" | |
else | |
usage | |
fail "Unknown operation '$mode'!" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment