2009-12-15 07:37:32 +01:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
# prepare installation by putting in place unless present:
|
|
|
|
# /etc/nixos/nixpkgs
|
|
|
|
# /etc/nixos/nixos
|
|
|
|
# /etc/nixos/configuration.nix
|
|
|
|
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
usage(){
|
|
|
|
cat << EOF
|
|
|
|
script options [list of actions]
|
|
|
|
|
|
|
|
actions:
|
|
|
|
|
|
|
|
guess-config: run nixos-hardware-scan > T/configuration.nix
|
|
|
|
copy-nix: copy minimal nix system which can bootstrap the whole system
|
|
|
|
This creates the $mountPoint/bin/sh symlink
|
|
|
|
If you're bootstrapping from an archive store paths are registered valid only
|
|
|
|
copy-nixos-bootstrap:
|
|
|
|
copy the nixos-bootstrap script to /nix/store where it will be
|
|
|
|
garbage collected later
|
|
|
|
copy-sources: copy repos into T/
|
|
|
|
checkout-sources: svn checkout official repos into T/
|
|
|
|
|
|
|
|
|
|
|
|
where T=$T
|
|
|
|
and repos = $ALL_REPOS
|
|
|
|
|
|
|
|
options:
|
|
|
|
--force: If targets exist no action will taken unless you use --force
|
|
|
|
in which case target is renamed before action is run
|
|
|
|
--dir-ok: allow installing into directory (omits is mount point check)
|
|
|
|
|
|
|
|
--debug: set -x
|
|
|
|
|
|
|
|
|
|
|
|
default list of actions: $DEFAULTS
|
|
|
|
EOF
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
INFO(){ echo "INFO: " $@; }
|
|
|
|
|
|
|
|
# = configuration =
|
|
|
|
|
|
|
|
FORCE_ACTIONS=${FORCE_ACTIONS:-}
|
|
|
|
ALL_REPOS="nixpkgs nixos"
|
|
|
|
mountPoint=${mountPoint:-/mnt}
|
|
|
|
|
|
|
|
if [ -e $mountPoint/README-BOOTSTRAP-NIXOS ]; then
|
|
|
|
INFO "$mountPoint/README-BOOTSTRAP-NIXOS found, assuming your're bootstrapping from an archive. Nix files should be in place"
|
|
|
|
FROM_ARCHIVE=1
|
|
|
|
DEFAULTS="guess-config copy-nix"
|
|
|
|
else
|
|
|
|
FROM_ARCHIVE=0
|
|
|
|
DEFAULTS="guess-config copy-nixos-bootstrap copy-nix copy-sources"
|
|
|
|
fi
|
|
|
|
|
|
|
|
backupTimestamp=$(date "+%Y%m%d%H%M%S")
|
|
|
|
SRC_BASE=${SRC_BASE:-"/etc/nixos"}
|
|
|
|
SVN_BASE="https://svn.nixos.org/repos/nix"
|
|
|
|
MUST_BE_MOUNTPOINT=${MUST_BE_MOUNTPOINT:-1}
|
|
|
|
T="$mountPoint/etc/nixos"
|
|
|
|
|
|
|
|
NIX_CLOSURE=${NIX_CLOSURE:-@nixClosure@}
|
|
|
|
|
|
|
|
die(){ echo "!>> " $@; exit 1; }
|
|
|
|
|
|
|
|
## = read options =
|
|
|
|
# actions is used by main loop at the end
|
|
|
|
ACTIONS=""
|
|
|
|
# check and handle options:
|
|
|
|
for a in $@; do
|
|
|
|
case "$a" in
|
|
|
|
copy-nix|copy-nixos-bootstrap|guess-config|copy-sources|checkout-sources)
|
|
|
|
ACTIONS="$ACTIONS $a"
|
|
|
|
;;
|
|
|
|
--dir-ok)
|
|
|
|
MUST_BE_MOUNTPOINT=false
|
|
|
|
;;
|
|
|
|
--force)
|
|
|
|
FORCE_ACTIONS=1
|
|
|
|
;;
|
|
|
|
--debug)
|
|
|
|
set -x
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "unkown option: $a"
|
|
|
|
usage
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
[ -n "$ACTIONS" ] || ACTIONS="$DEFAULTS"
|
|
|
|
|
|
|
|
|
|
|
|
if ! grep -F -q " $mountPoint " /proc/mounts && [ "$MUST_BE_MOUNTPOINT" = 1 ]; then
|
|
|
|
die "$mountPoint doesn't appear to be a mount point"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# = utils =
|
|
|
|
|
|
|
|
backup(){
|
|
|
|
local dst="$(dirname "$1")/$(basename "$1")-$backupTimestamp"
|
|
|
|
INFO "backing up: $1 -> $dst"
|
|
|
|
mv "$1" "$dst"
|
|
|
|
}
|
|
|
|
|
|
|
|
# = implementation =
|
|
|
|
|
|
|
|
# exit status = 0: target exists
|
|
|
|
# exti status != 0: target must be rebuild either because --force was given or
|
|
|
|
# because it didn't exist yet
|
|
|
|
target_realised(){
|
|
|
|
if [ -e "$1" ] && [ "$FORCE_ACTIONS" = 1 ]; then
|
|
|
|
backup "$1"
|
|
|
|
fi
|
|
|
|
|
|
|
|
[ -e "$1" ] && {
|
|
|
|
INFO "not realsing $1. Target already exists. Use --force to force."
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
createDirs(){
|
|
|
|
mkdir -m 0755 -p $mountPoint/etc/nixos
|
|
|
|
mkdir -m 1777 -p $mountPoint/nix/store
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
realise_repo(){
|
|
|
|
local action=$1
|
|
|
|
local repo=$2
|
|
|
|
|
|
|
|
createDirs
|
|
|
|
|
|
|
|
if [ "$action" == "copy-sources" ]; then
|
|
|
|
|
|
|
|
local repo_sources="${repo}_SOURCES"
|
|
|
|
rsync -a -r "${SRC_BASE}/$repo" "$T"
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
INFO "checking out $repo"
|
|
|
|
svn co "$SVN_BASE/$repo/trunk" "$T/$repo"
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-12-16 00:26:52 +01:00
|
|
|
# only keep /nix/store/* lines
|
|
|
|
# print them only once
|
|
|
|
pathsFromGraph(){
|
|
|
|
declare -A a
|
|
|
|
local prefix=/nix/store/
|
|
|
|
while read l; do
|
|
|
|
if [ "${l/#$prefix/}" != "$l" ] && [ -z "${a["$l"]}" ]; then
|
|
|
|
echo "$l";
|
|
|
|
a["$l"]=1;
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2009-12-15 07:37:32 +01:00
|
|
|
# = run actions: =
|
|
|
|
for a in $ACTIONS; do
|
|
|
|
case "$a" in
|
|
|
|
|
|
|
|
guess_config)
|
|
|
|
local config="$T/configuration.nix"
|
|
|
|
target_realised "$config" || {
|
|
|
|
INFO "creating simple configuration file"
|
|
|
|
nixos-hardware-scan > "$config"
|
|
|
|
echo
|
|
|
|
INFO "Note: you can start customizing $config while remaining actions will are being executed"
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
;;
|
|
|
|
|
|
|
|
copy-nixos-bootstrap)
|
|
|
|
createDirs
|
|
|
|
# this script will be garbage collected somewhen:
|
|
|
|
cp @nixosBootstrap@/bin/nixos-bootstrap $mountPoint/nix/store/
|
|
|
|
;;
|
|
|
|
|
|
|
|
copy-nix)
|
2009-12-16 00:26:52 +01:00
|
|
|
if [ "$FROM_ARCHIVE" = 1 ]; then
|
2009-12-15 07:37:32 +01:00
|
|
|
NIX_CLOSURE=${mountPoint}@nixClosure@
|
|
|
|
else
|
|
|
|
INFO "Copy Nix to the Nix store on the target device."
|
|
|
|
createDirs
|
|
|
|
echo "copying Nix to $mountPoint...."
|
2009-12-16 00:26:52 +01:00
|
|
|
|
|
|
|
for i in `cat $NIX_CLOSURE | pathsFromGraph`; do
|
2009-12-15 07:37:32 +01:00
|
|
|
echo " $i"
|
|
|
|
rsync -a $i $mountPoint/nix/store/
|
|
|
|
done
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
[ -e "$NIX_CLOSURE" ] || die "Couldn't find nixClosure $NIX_CLOSURE anywhere. Can't register inital store paths valid. Exiting"
|
|
|
|
|
|
|
|
# Create the required /bin/sh symlink; otherwise lots of things
|
|
|
|
# (notably the system() function) won't work.
|
|
|
|
mkdir -m 0755 -p $mountPoint/bin
|
|
|
|
ln -sf @shell@ $mountPoint/bin/sh
|
|
|
|
|
|
|
|
INFO "registering bootstrapping store paths as valid so that they won't be rebuild"
|
|
|
|
# Register the paths in the Nix closure as valid. This is necessary
|
|
|
|
# to prevent them from being deleted the first time we install
|
|
|
|
# something. (I.e., Nix will see that, e.g., the glibc path is not
|
|
|
|
# valid, delete it to get it out of the way, but as a result nothing
|
|
|
|
# will work anymore.)
|
|
|
|
# TODO: check permissions so that paths can't be changed later?
|
|
|
|
chroot "$mountPoint" @nix@/bin/nix-store --register-validity < $NIX_CLOSURE
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
copy-sources|checkout-sources)
|
|
|
|
|
|
|
|
for repo in $ALL_REPOS; do
|
|
|
|
target_realised "$T/$repo" || realise_repo $a $repo
|
|
|
|
done
|
|
|
|
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ -e "$T/nixos" ] && [ -e "$T/nixpkgs" ] && [ -e "$T/configuration.nix" ]; then
|
|
|
|
cat << EOF
|
|
|
|
To realise your NixOS installtion execute:
|
|
|
|
|
2009-12-16 00:26:52 +01:00
|
|
|
run-in-chroot "/nix/store/nixos-bootstrap --install -j2 --keep-going"
|
2009-12-15 07:37:32 +01:00
|
|
|
EOF
|
|
|
|
else
|
|
|
|
for t in "$T/configuration.nix" "$T/nixpkgs" "$T/configuration.nix"; do
|
|
|
|
INFO "you can't start because $t is missing"
|
|
|
|
done
|
|
|
|
fi
|