From 15f5d97457e4aa59838c5018f3f964045e97ecdf Mon Sep 17 00:00:00 2001 From: Tobias Happ Date: Sat, 30 Nov 2019 01:30:33 +0100 Subject: [PATCH] Add environment.etcBackupExtension option --- .../initial-build/nix-on-droid.nix.default | 3 ++ modules/environment/etc/default.nix | 47 +++++++++++++------ modules/environment/etc/setup-etc.sh | 12 ++++- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/modules/build/initial-build/nix-on-droid.nix.default b/modules/build/initial-build/nix-on-droid.nix.default index 85756c6..d6f6d76 100644 --- a/modules/build/initial-build/nix-on-droid.nix.default +++ b/modules/build/initial-build/nix-on-droid.nix.default @@ -24,6 +24,9 @@ #unzip ]; + # Backup etc files instead of failing to activate generation if a file already exists in /etc + environment.etcBackupExtension = ".bak"; + # Read the changelog before changing this value system.stateVersion = "19.09"; diff --git a/modules/environment/etc/default.nix b/modules/environment/etc/default.nix index 7e460a2..6a120d7 100644 --- a/modules/environment/etc/default.nix +++ b/modules/environment/etc/default.nix @@ -72,20 +72,37 @@ in options = { - environment.etc = mkOption { - type = types.loaOf fileType; - default = {}; - example = literalExample '' - { - example-configuration-file = { - source = "/nix/store/.../etc/dir/file.conf.example"; - }; - "default/useradd".text = "GROUP=100 ..."; - } - ''; - description = '' - Set of files that have to be linked in /etc. - ''; + environment = { + etc = mkOption { + type = types.loaOf fileType; + default = {}; + example = literalExample '' + { + example-configuration-file = { + source = "/nix/store/.../etc/dir/file.conf.example"; + }; + "default/useradd".text = "GROUP=100 ..."; + } + ''; + description = '' + Set of files that have to be linked in /etc. + ''; + }; + + etcBackupExtension = mkOption { + type = types.nullOr types.str; + default = null; + example = ".bak"; + description = '' + Backup file extension. + + If a file in /etc already exists and is not managed + by nix-on-droid, the activation fails because we do not overwrite unknown + files. When an extension is provided through this option, the original + file will be moved in respect of the backup extension and the activation + executes successfully. + ''; + }; }; }; @@ -99,7 +116,7 @@ in inherit etc; activation.setUpEtc = '' - $DRY_RUN_CMD bash ${./setup-etc.sh} /etc ${etc}/etc + $DRY_RUN_CMD bash ${./setup-etc.sh} /etc ${etc}/etc ${config.environment.etcBackupExtension} ''; }; diff --git a/modules/environment/etc/setup-etc.sh b/modules/environment/etc/setup-etc.sh index c9cfa7c..bafdfaf 100644 --- a/modules/environment/etc/setup-etc.sh +++ b/modules/environment/etc/setup-etc.sh @@ -6,6 +6,7 @@ etc="${1}" static="/etc/static" new_etc="${2}" +backup_extension="${3:-}" function atomic_symlink() { local source="${1}" @@ -25,7 +26,7 @@ function cleanup() { for file in $(find "${etc}" -xtype l); do local target="$(readlink "${file}")" if [[ ! -L "${target}" ]]; then - echo "removing obsolete symlink '${file}'..." + echo "Removing obsolete symlink '${file}'..." rm "${file}" fi done @@ -64,7 +65,14 @@ function link() { mkdir -p "$(dirname "${target}")" if [[ -e "${target}" ]] && ! is_static "${target}"; then - echo "Linking of ${target} failed. Please remove this file." + if [[ -n "${backup_extension}" ]]; then + echo "Backing up '${target}' to '${target}${backup_extension}'..." + cp "${target}" "${target}${backup_extension}" + + atomic_symlink "${static}/${name}" "${target}" + else + echo "Linking of ${target} failed. Please remove this file." + fi else atomic_symlink "${static}/${name}" "${target}" fi