mirror of
https://github.com/nix-community/nix-on-droid.git
synced 2025-11-08 11:36:07 +01:00
103 lines
2.7 KiB
Bash
103 lines
2.7 KiB
Bash
# Copyright (c) 2019-2020, see AUTHORS. Licensed under MIT License, see LICENSE.
|
|
|
|
# Inspired by
|
|
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/setup-etc.pl
|
|
# (Copyright (c) 2003-2019 Eelco Dolstra and the Nixpkgs/NixOS contributors,
|
|
# licensed under MIT License as well)
|
|
|
|
|
|
set -eu -o pipefail
|
|
|
|
: "${VERBOSE_ARG:=}"
|
|
: "${VERBOSE_ECHO:=true}"
|
|
|
|
etc="${1}"
|
|
static="/etc/static"
|
|
new_etc="${2}"
|
|
backup_extension="${3:-}"
|
|
|
|
function atomic_symlink() {
|
|
local source="${1}"
|
|
local target="${2}"
|
|
local target_tmp="${target}.tmp"
|
|
|
|
$VERBOSE_ECHO "Atomic symlink ${source} to ${target}..."
|
|
|
|
mkdir -p "$(dirname "${target_tmp}")"
|
|
ln -sf "${source}" "${target_tmp}"
|
|
mv -T "${target_tmp}" "${target}"
|
|
}
|
|
|
|
# Remove dangling symlinks that point to /etc/static. These are
|
|
# configuration files that existed in a previous configuration but not
|
|
# in the current one.
|
|
function cleanup() {
|
|
local file
|
|
for file in $(find "${etc}/" -xtype l); do
|
|
local target="$(readlink "${file}")"
|
|
if [[ ! -L "${target}" ]]; then
|
|
echo "Removing obsolete symlink '${file}'..."
|
|
rm "${file}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Returns 0 if the argument points to the files in /etc/static. That
|
|
# means either argument is a symlink to a file in /etc/static or a
|
|
# directory with all children being static.
|
|
function is_static() {
|
|
local path="${1}"
|
|
|
|
if [[ -L "${path}" ]]; then
|
|
[[ "$(readlink "${path}")" == ${static}/* ]]
|
|
return
|
|
fi
|
|
|
|
if [[ -d "${path}" ]]; then
|
|
local file
|
|
for file in "${path}"/*; do
|
|
is_static "${file}" || return
|
|
done
|
|
fi
|
|
|
|
false
|
|
}
|
|
|
|
function link() {
|
|
if [[ ! -d "${new_etc}" ]]; then
|
|
return
|
|
fi
|
|
|
|
local name
|
|
for name in $(find "${new_etc}/" -type l | sed -e "s,^${new_etc}/,,"); do
|
|
local target="${etc}/${name}"
|
|
|
|
mkdir $VERBOSE_ARG -p "$(dirname "${target}")"
|
|
|
|
if [[ -e "${target}" ]] && ! is_static "${target}"; then
|
|
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
|
|
done
|
|
}
|
|
|
|
# On initial build /etc/static is a directory instead of a symlink
|
|
if [[ -e "${etc}/static" && ! -L "${etc}/static" ]]; then
|
|
rm $VERBOSE_ARG --recursive "${etc}/static"
|
|
fi
|
|
|
|
# Atomically update /etc/static to point at the etc files of the
|
|
# current configuration.
|
|
atomic_symlink "${new_etc}" "${etc}/static"
|
|
|
|
cleanup
|
|
|
|
link
|