Refactor profile flake installer

Add support for exporting to archive.nar
Add support for importing from an archive.nar
Add simple support for adding a flake.lock
This commit is contained in:
Andrew R. M. 2025-03-10 22:18:42 -04:00
parent edf8584f2a
commit 0a7f1e193a

View File

@ -2,7 +2,11 @@
# Installs packages to the nix profile using nix profile
# Reference: https://nixos.org/manual/nixpkgs/stable/#sec-declarative-package-management
set -ex
set -e
FLAKE_PATH="${HOME}/.config/nix/flakes/my-package-collection"
FLAKE_NAME="flake.nix"
ARCHIVE_PATH="${FLAKE_PATH}/archive.nar"
if ! which nix &>/dev/null; then
if [ -r "$HOME/.nix-profile/etc/profile.d/nix.sh" ]; then
@ -63,24 +67,24 @@ nix_packages=(
)
unstable_packages=(
# CVE in NixOS stable version of vault
"vault"
# "vault"
# Need unstable latest up to date terraform/terragrunt
"terraform"
"terragrunt"
# "terraform"
# "terragrunt"
# Language servers
"gitlab-ci-ls"
)
mkdir -p ~/.config/nixpkgs/
templated_insert="$(for nix_package in ${nix_packages[@]}; do echo " $nix_package"; echo; done)"
templated_insert=${templated_insert}$(for unstable_package in ${unstable_packages[@]}; do echo; echo " unstablePkgs.$unstable_package"; done)
generate_flake() {
mkdir -p "${FLAKE_PATH}"
templated_insert="$(for nix_package in ${nix_packages[@]}; do echo " $nix_package"; echo; done)"
templated_insert=${templated_insert}$(for unstable_package in ${unstable_packages[@]}; do echo; echo " unstablePkgs.$unstable_package"; done)
# Reference: https://discourse.nixos.org/t/nix-profile-in-combination-with-declarative-package-management/21228/9
cat << EOF > ~/.config/nixpkgs/flake.nix
# Reference: https://discourse.nixos.org/t/nix-profile-in-combination-with-declarative-package-management/21228/9
cat <<EOF > "${FLAKE_PATH}/${FLAKE_NAME}"
{
description = "A declarative system installation";
@ -112,7 +116,7 @@ cat << EOF > ~/.config/nixpkgs/flake.nix
pkgs = nixpkgs.legacyPackages.\${system}; # here we need just legacy packages
unstablePkgs = import unstable { inherit system; config.allowUnfree = true; };
in pkgs.buildEnv {
name = "myPackages";
name = "myPackageCollection";
paths = with pkgs; [
${templated_insert}
];
@ -123,6 +127,19 @@ ${templated_insert}
}; # outputs
}
EOF
}
lock_flake() {
nix flake lock "${FLAKE_PATH}"
}
flake_lock_exists() {
if [ -r "${FLAKE_PATH}/flake.lock" ]; then
return 0
else
return 1
fi
}
install_nix_packages()
{
@ -131,13 +148,48 @@ install_nix_packages()
if [ "${nix_packages[*]}" ]; then
# Updated to process new nix profile format, proper processing probably needs JQ
# But JQ would be another dependency and this is good enough for now
if nix profile list --json | grep -i "\"attrPath\":\"${package_name}\""; then
# Okay we are installing jq to do stuff now but I don't feel like reworking this
if nix profile list --json | grep -qi "\"attrPath\":\"${package_name}\""; then
echo "Removing previous version of profile"
nix profile remove "${package_name}"
store_path=$(nix profile list --json | nix-shell --quiet -p jq --run 'jq -r .elements.myPackageCollection.storePaths[0]')
nix profile remove "${store_path}"
fi
echo "Installing profile"
nix profile install "${HOME}/.config/nixpkgs/flake.nix#myPackageCollection"
nix profile install "${FLAKE_PATH}/#myPackageCollection"
fi
}
get_store_path() {
# This is only called post successful installation so jq is available
nix profile list --json | jq -r .elements.myPackageCollection.storePaths[0]
}
export_archive() {
store_path="${1}"
mkdir -p "$(dirname ${ARCHIVE_PATH})"
nix-store --export $(nix-store --query --requisites ${store_path}) > "${ARCHIVE_PATH}"
}
import_archive() {
nix-store --import < "${ARCHIVE_PATH}" > /dev/null
}
archive_exists() {
if [ -r "${ARCHIVE_PATH}" ]; then
return 0
else
return 1
fi
}
if archive_exists; then
import_archive
fi
generate_flake
if ! flake_lock_exists; then
lock_flake
fi
install_nix_packages
if ! archive_exists; then
export_archive "$(get_store_path)"
fi