nix-on-droid/script
2019-03-12 21:19:06 +07:00

280 lines
8.7 KiB
Bash
Executable file

#!/usr/bin/env bash
# This script builds the initial bootstrap zipball for Nix on Android.
# Copyright (c) 2019 Alexander Sosedkin <monk@unboiled.info>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set -ue
ARCHIVE=nix-2.2.1-aarch64-linux.tar.bz2
BASEURL=https://nixos.org/releases/nix/nix-2.2.1
URL="$BASEURL/$ARCHIVE"
INST="/data/data/com.termux.nix/files/usr"
export PROOT_NO_SECCOMP=1 # see https://github.com/proot-me/PRoot/issues/106
rm -rf ./bootstrap
mkdir -p bootstrap
wget https://github.com/proot-me/proot-static-build/blob/master/static/proot-x86_64?raw=true -O proot-host
chmod +x proot-host
wget https://github.com/multiarch/qemu-user-static/releases/download/v3.1.0-2/qemu-aarch64-static -O qemu-aarch64
chmod +x qemu-aarch64
echo "downloading nix archive"
wget $URL -O $ARCHIVE
echo -n "extracting $ARCHIVE "
tar -xf "$ARCHIVE" -C bootstrap --checkpoint=200 --checkpoint-action=dot
echo " done"
mv bootstrap/nix* bootstrap/nix-installer
echo -n "copying store... "
mkdir bootstrap/nix
cp -r bootstrap/nix-installer/store bootstrap/nix/
echo "done"
mkdir -p bootstrap/bin
TGT_SHELL=$(find bootstrap/nix/store -path '*/bin/bash' | sed s/^bootstrap//)
echo "shell found at $TGT_SHELL"
ln -s "$TGT_SHELL" bootstrap/bin/sh
mkdir -p bootstrap/usr/bin
TGT_ENV=$(find bootstrap/nix/store -path '*/bin/env' | sed s/^bootstrap//)
echo "env found at $TGT_ENV"
ln -s "$TGT_ENV" bootstrap/usr/bin/env
TGT_NIX=$(find bootstrap/nix/store -path '*/bin/nix' | sed s/^bootstrap//)
TGT_NIX=${TGT_NIX%/bin/nix}
echo "nix derivation found at $TGT_NIX"
TGT_CACERT=$(find bootstrap/nix/store -path *-nss-cacert-*/ca-bundle.crt | sed s/^bootstrap//)
echo "cacert found at $TGT_CACERT"
PROOT_CMD="./proot-host -q ./qemu-aarch64 -r bootstrap -w /"
echo "initialising Nix database..."
$PROOT_CMD "$TGT_NIX/bin/nix-store" --init
echo "registering paths..."
$PROOT_CMD "$TGT_NIX/bin/nix-store" --load-db < bootstrap/nix-installer/.reginfo
echo "injecting proot..."
mkdir -p bootstrap/bin
cp proot-tgt bootstrap/bin/proot
echo "making up some resolv.conf..."
mkdir -p bootstrap/etc
echo -e "nameserver 1.1.1.1\nnameserver 8.8.8.8" > bootstrap/etc/resolv.conf
echo "disabling sandboxing..." # we can't rely on USER_NS support
mkdir -p bootstrap/etc/nix
echo "sandbox = false " > bootstrap/etc/nix/nix.conf
echo "composing login scripts..."
mkdir -p bootstrap/bin
mkdir -p bootstrap/root
mkdir -p bootstrap/tmp
cat > bootstrap/bin/login <<EOF
#!/system/bin/sh
set -e
export USER=\$(/system/bin/whoami)
export PROOT_TMP_DIR=$INST/tmp
if [ ! -e $INST/etc/passwd ]; then
[ -n "$@" ] || echo "Creating /etc/passwd..."
echo "root:x:0:0:System administrator:$INST/root:/bin/sh" > $INST/etc/passwd
echo "nix-on-droid:x:\$(/system/bin/stat -c '%u:%g' $INST):nix-on-droid:/bin/sh" >> $INST/etc/passwd
fi
exec $INST/bin/proot \
-b $INST/nix:/nix \
-b $INST/bin:/bin \
-b $INST/etc:/etc \
-b $INST/tmp:/tmp \
-b $INST/usr:/usr \
-b /:/android \
--link2symlink \
$INST/bin/sh $INST/bin/.login-inner \$USER "\$@"
EOF
chmod +x bootstrap/bin/login
cat > bootstrap/bin/.login-inner <<EOF
set -e
[ "\$#" -gt 1 ] || echo "Welcome to Nix-on-Droid!"
[ "\$#" -gt 1 ] || echo "If nothing works, use the rescue shell and read $INST/bin/.login-inner"
export USER="\$1"
export HOME="/data/data/com.termux.nix/files/home"
shift
[ "\$#" -gt 0 ] || echo "Sourcing Nix environment..."
. $INST/$TGT_NIX/etc/profile.d/nix.sh
if [ ! -e \$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crt ]; then
if [ -e $TGT_CACERT ]; then
export NIX_SSL_CERT_FILE=$TGT_CACERT
fi
fi
if [ -e "\$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" ]; then
[ "\$#" -gt 0 ] || echo "Sourcing home-manager environment..."
export NIX_PATH=\$HOME/.nix-defexpr/channels\${NIX_PATH:+:}\$NIX_PATH
. "\$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
fi
if [ "\$#" -eq 0 ]; then
if [ ! -e "\$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" ]; then
echo "Congratulations. Now you have Nix installed, but that's kinda it."
echo "Hope you're a seasoned Nix user, because stuff is not pretty yet."
echo "If you wonder what to do next, and want to do it the hard way, start with running"
echo " nix-channel --add https://nixos.org/channels/nixos-18.09 nixpkgs"
echo " nix-channel --update"
echo "After that you can summon software from nixpkgs (e.g. gitMinimal):"
echo "* by asking for a shell that has it:"
echo " nix run nixpkgs.bashInteractive nixpkgs.gitMinimal"
echo "* or installing it into the user environment (not recommended):"
echo " nix-env -iA nixpkgs.gitMinimal"
echo "* or, the best way, declaratively with home-manager:"
echo " 0. nix-on-droid-install"
echo " 1. [get an editor and edit ~/.config/nixpkgs/home.nix]"
echo " 2. home-manager switch"
echo "or a myriad other ways."
echo "You should really consider installing at least: nix, cacert and coreutils."
echo "bashInteractive and a text editor should be high on the list too."
echo
echo "If you want the easy way, nix-on-droid-install should get all this covered."
echo
echo "TL;DR: run nix-on-droid-install and things will get better."
echo
echo "Dropping you into an extremely limited shell (that has Nix though). Happy hacking!"
export PATH="$TGT_NIX/bin:\$PATH"
exec /bin/sh
fi
echo "Dropping you into a shell. Happy hacking!"
exec /usr/bin/env bash
else
exec /usr/bin/env "\$@"
fi
EOF
chmod +x bootstrap/bin/.login-inner
cat > bootstrap/bin/nix-on-droid-install <<EOF
#!/bin/sh
set -e
if [ -e \$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh ]; then
echo "You already have home-manager installed."
fi
echo "Installing home-manager and other good stuff..."
echo "Subscribing to the stable (nixos-18.09) channel of home-manager and nixpkgs..."
echo "If you want unstable instead, you probably also know what to do."
$TGT_NIX/bin/nix-channel --add https://nixos.org/channels/nixos-18.09 nixpkgs
$TGT_NIX/bin/nix-channel --add https://github.com/rycee/home-manager/archive/release-18.09.tar.gz home-manager
echo "Updating channels..."
$TGT_NIX/bin/nix-channel --update
echo "Whew."
export NIX_PATH=\$HOME/.nix-defexpr/channels\${NIX_PATH:+:}\$NIX_PATH
if [ ! -e \$HOME/.config/nixpkgs/home.nix ]; then
echo "Creating an initial home-manager configuration in ~/.config/nixpkgs/home.nix ..."
$TGT_NIX/bin/nix run nixpkgs.coreutils -c mkdir -p \$HOME/.config/nixpkgs/
$TGT_NIX/bin/nix run nixpkgs.coreutils -c cp -n $INST/etc/home.nix.default \$HOME/.config/nixpkgs/home.nix
fi
echo "Installing home-manager..."
$TGT_NIX/bin/nix run nixpkgs.nix -c $TGT_NIX/bin/nix-shell '<home-manager>' -A install
echo "Edit ~/.config/nixpkgs/home.nix and home-manager rebuild to control what is going on."
echo "Run bash or restart your session to enjoy a much nicer environment."
EOF
chmod +x bootstrap/bin/nix-on-droid-install
echo "providing a default home-manager config..."
cat > bootstrap/etc/home.nix.default <<EOF
{ pkgs, ... }:
{
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
# Install and configure software declaratively
#programs.git = {
# enable = true;
# userName = "Jane Doe";
# userEmail = "jane.doe@example.org";
#};
# Simply install just the packages
home.packages = with pkgs; [
# Stuff that you really really want to have
nix cacert coreutils # think twice before removing these
# User-facing stuff that you really really want to have
bashInteractive # think twice before removing thes
vim # or some other editor, e.g. nano or neovim
# Some common stuff that people expect to have
#diffutils
#findutils
#utillinux
#tzdata
#hostname
#man
#gnugrep
#gnupg
#gnused
#gnutar
#bzip2
#gzip
#xz
#zip
#unzip
];
}
EOF
echo "removing nix-installer..."
rm -rf bootstrap/nix-installer
echo "finding executables..."
find bootstrap -executable -type f | \
sed s@^bootstrap/@@ \
> bootstrap/EXECUTABLES.txt
echo "finding symlinks..."
for LINK in $(find bootstrap -type l); do
LNK=$(echo "$LINK" | sed s@^bootstrap/@@)
TGT=$(readlink $LINK)
echo "$TGT$LNK" >> bootstrap/SYMLINKS.txt
rm "$LINK"
done
echo "packing..."
rm -f bootstrap-aarch64.zip
(cd bootstrap; zip -q -9 -r ../bootstrap-aarch64 ./*)
echo "done"