mirror of
https://github.com/nix-community/nix-on-droid.git
synced 2025-11-08 19:46:07 +01:00
Add modules
This commit is contained in:
parent
5cc656fffc
commit
f40362898a
19 changed files with 1045 additions and 0 deletions
112
modules/build/activation.nix
Normal file
112
modules/build/activation.nix
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.build;
|
||||||
|
|
||||||
|
# Programs that always should be available on the activation
|
||||||
|
# script's PATH.
|
||||||
|
activationBinPaths = lib.makeBinPath [
|
||||||
|
pkgs.bash
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.findutils
|
||||||
|
pkgs.gnused
|
||||||
|
pkgs.ncurses # For `tput`.
|
||||||
|
pkgs.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
activationCmds = concatStringsSep "\n" (
|
||||||
|
mapAttrsToList (name: value: ''
|
||||||
|
noteEcho "Activating ${name}"
|
||||||
|
${value}
|
||||||
|
'') cfg.activation
|
||||||
|
);
|
||||||
|
|
||||||
|
activationScript = pkgs.writeScript "activation-script" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
cd $HOME
|
||||||
|
|
||||||
|
export PATH="${activationBinPaths}"
|
||||||
|
|
||||||
|
${builtins.readFile ../lib-bash/color-echo.sh}
|
||||||
|
${builtins.readFile ../lib-bash/activation-init.sh}
|
||||||
|
|
||||||
|
${activationCmds}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
build = {
|
||||||
|
activation = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrs;
|
||||||
|
description = ''
|
||||||
|
Activation scripts for the nix-on-droid environment.
|
||||||
|
</para><para>
|
||||||
|
Any script should respect the <varname>DRY_RUN</varname>
|
||||||
|
variable, if it is set then no actual action should be taken.
|
||||||
|
The variable <varname>DRY_RUN_CMD</varname> is set to
|
||||||
|
<code>echo</code> if dry run is enabled. Thus, many cases you
|
||||||
|
can use the idiom <code>$DRY_RUN_CMD rm -rf /</code>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
activationPackage = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = "Derivation with activation script.";
|
||||||
|
};
|
||||||
|
|
||||||
|
etc = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
internal = true;
|
||||||
|
description = "Package containing /etc files.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
build.activationPackage =
|
||||||
|
pkgs.runCommand
|
||||||
|
"nix-on-droid-generation"
|
||||||
|
{
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
}
|
||||||
|
''
|
||||||
|
mkdir --parents $out/filesystem/{bin,usr/{bin,lib}}
|
||||||
|
|
||||||
|
cp ${activationScript} $out/activate
|
||||||
|
|
||||||
|
ln --symbolic ${config.build.etc}/etc $out/etc
|
||||||
|
ln --symbolic ${config.environment.path} $out/nix-on-droid-path
|
||||||
|
|
||||||
|
ln --symbolic ${config.environment.files.login} $out/filesystem/bin/login
|
||||||
|
ln --symbolic ${config.environment.files.loginInner} $out/filesystem/usr/lib/login-inner
|
||||||
|
|
||||||
|
ln --symbolic ${config.environment.binSh} $out/filesystem/bin/sh
|
||||||
|
ln --symbolic ${config.environment.usrBinEnv} $out/filesystem/usr/bin/env
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
45
modules/build/config.nix
Normal file
45
modules/build/config.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
build = {
|
||||||
|
initialBuild = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Whether this is the initial build for the bootstrap zip ball.
|
||||||
|
Should not be enabled manually, see
|
||||||
|
<filename>initial-build.nix</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
installationDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
internal = true;
|
||||||
|
readOnly = true;
|
||||||
|
description = "Path to installation directory.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
build.installationDir = "/data/data/com.termux.nix/files/usr";
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
54
modules/build/initial-build/default.nix
Normal file
54
modules/build/initial-build/default.nix
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
build = {
|
||||||
|
arch = mkOption {
|
||||||
|
type = types.enum [ "aarch64" "i686" ];
|
||||||
|
description = "Destination arch.";
|
||||||
|
};
|
||||||
|
|
||||||
|
channel = {
|
||||||
|
nixpkgs = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "https://nixos.org/channels/nixos-19.09";
|
||||||
|
description = "Channel URL for nixpkgs.";
|
||||||
|
};
|
||||||
|
|
||||||
|
nix-on-droid = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "https://github.com/t184256/nix-on-droid-bootstrap/archive/master.tar.gz";
|
||||||
|
description = "Channel URL for nix-on-droid.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
build.initialBuild = true;
|
||||||
|
|
||||||
|
# /etc/group and /etc/passwd need to be build on target machine because
|
||||||
|
# uid and gid need to be determined.
|
||||||
|
environment.etc = {
|
||||||
|
"group".enable = false;
|
||||||
|
"nix-on-droid.nix.default".text = builtins.readFile ./nix-on-droid.nix.default;
|
||||||
|
"passwd".enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
39
modules/build/initial-build/nix-on-droid.nix.default
Normal file
39
modules/build/initial-build/nix-on-droid.nix.default
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Simply install just the packages
|
||||||
|
environment.packages = with pkgs; [
|
||||||
|
# User-facing stuff that you really really want to have
|
||||||
|
vim # or some other editor, e.g. nano or neovim
|
||||||
|
|
||||||
|
# Some common stuff that people expect to have
|
||||||
|
#diffutils
|
||||||
|
#findutils
|
||||||
|
#utillinux
|
||||||
|
#tzdata
|
||||||
|
#hostname
|
||||||
|
#man
|
||||||
|
#less
|
||||||
|
#gnugrep
|
||||||
|
#gnupg
|
||||||
|
#gnused
|
||||||
|
#gnutar
|
||||||
|
#bzip2
|
||||||
|
#gzip
|
||||||
|
#xz
|
||||||
|
#zip
|
||||||
|
#unzip
|
||||||
|
];
|
||||||
|
|
||||||
|
# After installing home-manager channel like
|
||||||
|
# nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager
|
||||||
|
# nix-channel --update
|
||||||
|
# you can configure home-manager in here like
|
||||||
|
#home-manager.config =
|
||||||
|
# { pkgs, ... }:
|
||||||
|
# {
|
||||||
|
# # insert home-manager config
|
||||||
|
# };
|
||||||
|
}
|
||||||
|
|
||||||
|
# vim: ft=nix
|
||||||
39
modules/default.nix
Normal file
39
modules/default.nix
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ pkgs ? import <nixpkgs> { }, initialBuild ? false, config ? { } }:
|
||||||
|
|
||||||
|
with pkgs.lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
homeDir = builtins.getEnv "HOME";
|
||||||
|
configFile = homeDir + "/.config/nixpkgs/nix-on-droid.nix";
|
||||||
|
|
||||||
|
hasConfigFile = builtins.pathExists configFile;
|
||||||
|
|
||||||
|
rawModule = evalModules {
|
||||||
|
modules = [
|
||||||
|
{
|
||||||
|
_module.args = { inherit pkgs; };
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ optional (!initialBuild && hasConfigFile) configFile
|
||||||
|
++ optional (!initialBuild && !hasConfigFile && pkgs.config ? nix-on-droid) pkgs.config.nix-on-droid
|
||||||
|
++ optional initialBuild config
|
||||||
|
++ import ./module-list.nix;
|
||||||
|
};
|
||||||
|
|
||||||
|
failedAssertions = map (x: x.message) (filter (x: !x.assertion) rawModule.config.assertions);
|
||||||
|
|
||||||
|
module =
|
||||||
|
if failedAssertions != []
|
||||||
|
then throw "\nFailed assertions:\n${concatMapStringsSep "\n" (x: "- ${x}") failedAssertions}"
|
||||||
|
else showWarnings rawModule.config.warnings rawModule;
|
||||||
|
in
|
||||||
|
|
||||||
|
if initialBuild
|
||||||
|
then module.config
|
||||||
|
else {
|
||||||
|
inherit (module.config.build) activationPackage;
|
||||||
|
inherit (module.config.environment) path;
|
||||||
|
}
|
||||||
108
modules/environment/etc/default.nix
Normal file
108
modules/environment/etc/default.nix
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
etc' = filter (f: f.enable) (attrValues config.environment.etc);
|
||||||
|
|
||||||
|
etc = pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
name = "etc";
|
||||||
|
|
||||||
|
builder = ./make-etc.sh;
|
||||||
|
|
||||||
|
preferLocalBuild = true;
|
||||||
|
allowSubstitutes = false;
|
||||||
|
|
||||||
|
sources = map (x: x.source) etc';
|
||||||
|
targets = map (x: x.target) etc';
|
||||||
|
};
|
||||||
|
|
||||||
|
fileType = types.submodule (
|
||||||
|
{ name, config, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether this /etc file should be generated. This
|
||||||
|
option allows specific /etc files to be disabled.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
target = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Name of symlink (relative to <filename>/etc</filename>).
|
||||||
|
Defaults to the attribute name.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
text = mkOption {
|
||||||
|
type = types.nullOr types.lines;
|
||||||
|
default = null;
|
||||||
|
description = "Text of the file.";
|
||||||
|
};
|
||||||
|
|
||||||
|
source = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "Path of the source file.";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
target = mkDefault name;
|
||||||
|
source = mkIf (config.text != null) (
|
||||||
|
let name' = "etc-" + baseNameOf name;
|
||||||
|
in mkDefault (pkgs.writeText name' config.text));
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
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 <filename>/etc</filename>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
build = {
|
||||||
|
inherit etc;
|
||||||
|
|
||||||
|
activation.setUpEtc = ''
|
||||||
|
$DRY_RUN_CMD bash ${./setup-etc.sh} /etc ${etc}/etc
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
41
modules/environment/etc/make-etc.sh
Normal file
41
modules/environment/etc/make-etc.sh
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
# inspired by https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/make-etc.sh
|
||||||
|
|
||||||
|
source $stdenv/setup
|
||||||
|
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
set -f
|
||||||
|
sources_=($sources)
|
||||||
|
targets_=($targets)
|
||||||
|
set +f
|
||||||
|
|
||||||
|
for ((i = 0; i < ${#targets_[@]}; i++)); do
|
||||||
|
source="${sources_[$i]}"
|
||||||
|
target="${targets_[$i]}"
|
||||||
|
|
||||||
|
if [[ "$source" =~ '*' ]]; then
|
||||||
|
|
||||||
|
# If the source name contains '*', perform globbing.
|
||||||
|
mkdir -p $out/etc/$target
|
||||||
|
for fn in $source; do
|
||||||
|
ln -s "$fn" $out/etc/$target/
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
mkdir -p $out/etc/$(dirname $target)
|
||||||
|
if ! [ -e $out/etc/$target ]; then
|
||||||
|
ln -s $source $out/etc/$target
|
||||||
|
else
|
||||||
|
echo "duplicate entry $target -> $source"
|
||||||
|
if test "$(readlink $out/etc/$target)" != "$source"; then
|
||||||
|
echo "mismatched duplicate entry $(readlink $out/etc/$target) <-> $source"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
done
|
||||||
85
modules/environment/etc/setup-etc.sh
Normal file
85
modules/environment/etc/setup-etc.sh
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
# inspired by https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/setup-etc.pl
|
||||||
|
|
||||||
|
etc="${1}"
|
||||||
|
static="/etc/static"
|
||||||
|
new_etc="${2}"
|
||||||
|
|
||||||
|
function atomic_symlink() {
|
||||||
|
local source="${1}"
|
||||||
|
local target="${2}"
|
||||||
|
local target_tmp="${target}.tmp"
|
||||||
|
|
||||||
|
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 -p "$(dirname "${target}")"
|
||||||
|
|
||||||
|
if [[ -e "${target}" ]] && ! is_static "${target}"; then
|
||||||
|
echo "Linking of ${target} failed. Please remove this file."
|
||||||
|
else
|
||||||
|
atomic_symlink "${static}/${name}" "${target}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# On initial build /etc/static is a directory instead of a symlink
|
||||||
|
if [[ -d "${etc}/static" ]]; then
|
||||||
|
rm --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
|
||||||
36
modules/environment/files.nix
Normal file
36
modules/environment/files.nix
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
"nix/nix.conf".text = ''
|
||||||
|
sandbox = false
|
||||||
|
substituters = https://cache.nixos.org https://nix-on-droid.cachix.org
|
||||||
|
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-on-droid.cachix.org-1:56snoMJTXmDRC1Ei24CmKoUqvHJ9XCp+nidK7qkMQrU=
|
||||||
|
'';
|
||||||
|
|
||||||
|
"resolv.conf".text = ''
|
||||||
|
nameserver 1.1.1.1
|
||||||
|
nameserver 8.8.8.8
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
60
modules/environment/links.nix
Normal file
60
modules/environment/links.nix
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.environment;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
binSh = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
readOnly = true;
|
||||||
|
description = "Path to /bin/sh executable.";
|
||||||
|
};
|
||||||
|
|
||||||
|
usrBinEnv = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
readOnly = true;
|
||||||
|
description = "Path to /usr/bin/env executable.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
build.activation = {
|
||||||
|
linkBinSh = ''
|
||||||
|
$DRY_RUN_CMD mkdir $VERBOSE_ARG --parents /bin
|
||||||
|
$DRY_RUN_CMD ln $VERBOSE_ARG --symbolic --force ${cfg.binSh} /bin/.sh.tmp
|
||||||
|
$DRY_RUN_CMD mv $VERBOSE_ARG /bin/.sh.tmp /bin/sh
|
||||||
|
'';
|
||||||
|
|
||||||
|
linkUsrBinEnv = ''
|
||||||
|
$DRY_RUN_CMD mkdir $VERBOSE_ARG --parents /usr/bin
|
||||||
|
$DRY_RUN_CMD ln $VERBOSE_ARG --symbolic --force ${cfg.usrBinEnv} /usr/bin/.env.tmp
|
||||||
|
$DRY_RUN_CMD mv $VERBOSE_ARG /usr/bin/.env.tmp /usr/bin/env
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
binSh = "${pkgs.bashInteractive}/bin/sh";
|
||||||
|
usrBinEnv = "${pkgs.coreutils}/bin/env";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
55
modules/environment/login/default.nix
Normal file
55
modules/environment/login/default.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, customPkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
login = pkgs.callPackage ./login.nix { inherit config; };
|
||||||
|
|
||||||
|
loginInner = pkgs.callPackage ./login-inner.nix { inherit config customPkgs; };
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
environment.files = {
|
||||||
|
|
||||||
|
login = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
readOnly = true;
|
||||||
|
description = "Login script.";
|
||||||
|
};
|
||||||
|
|
||||||
|
loginInner = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
readOnly = true;
|
||||||
|
description = "Login-inner script.";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
build.activation.installLoginScripts = ''
|
||||||
|
$DRY_RUN_CMD mkdir $VERBOSE_ARG --parents /bin /usr/lib
|
||||||
|
$DRY_RUN_CMD cp $VERBOSE_ARG ${login} /bin/login
|
||||||
|
$DRY_RUN_CMD cp $VERBOSE_ARG ${loginInner} /usr/lib/login-inner
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.files = {
|
||||||
|
inherit login loginInner;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
70
modules/environment/login/login-inner.nix
Normal file
70
modules/environment/login/login-inner.nix
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, customPkgs, writeText }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (customPkgs.packageInfo) cacert coreutils nix;
|
||||||
|
in
|
||||||
|
|
||||||
|
writeText "login-inner" ''
|
||||||
|
set -e
|
||||||
|
|
||||||
|
[ "$#" -gt 0 ] || echo "Welcome to Nix-on-Droid!"
|
||||||
|
|
||||||
|
[ "$#" -gt 0 ] || echo "If nothing works, use the rescue shell and read ${config.build.installationDir}/usr/lib/login-inner"
|
||||||
|
[ "$#" -gt 0 ] || echo "If it does not help, report bugs at https://github.com/t184256/nix-on-droid-bootstrap/issues"
|
||||||
|
|
||||||
|
export USER="${config.user.userName}"
|
||||||
|
export HOME="${config.user.home}"
|
||||||
|
|
||||||
|
${lib.optionalString config.build.initialBuild ''
|
||||||
|
[ "$#" -gt 0 ] || echo "Sourcing Nix environment..."
|
||||||
|
. ${nix}/etc/profile.d/nix.sh
|
||||||
|
|
||||||
|
export NIX_SSL_CERT_FILE=${cacert}
|
||||||
|
|
||||||
|
echo "Installing and updating nix-channels..."
|
||||||
|
${nix}/bin/nix-channel --add ${config.build.channel.nixpkgs} nixpkgs
|
||||||
|
${nix}/bin/nix-channel --update nixpkgs
|
||||||
|
${nix}/bin/nix-channel --add ${config.build.channel.nix-on-droid} nix-on-droid
|
||||||
|
${nix}/bin/nix-channel --update nix-on-droid
|
||||||
|
|
||||||
|
echo "Copy default nix-on-droid config..."
|
||||||
|
${coreutils}/bin/mkdir --parents $HOME/.config/nixpkgs
|
||||||
|
${coreutils}/bin/cp /etc/nix-on-droid.nix.default $HOME/.config/nixpkgs/nix-on-droid.nix
|
||||||
|
|
||||||
|
echo "Installing first nix-on-droid generation..."
|
||||||
|
${nix}/bin/nix build --no-link --file "<nix-on-droid>" nix-on-droid
|
||||||
|
$(${nix}/bin/nix path-info --file "<nix-on-droid>" nix-on-droid)/bin/nix-on-droid switch
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Congratulations! Now you have Nix installed with some default packages like bashInteractive, \
|
||||||
|
coreutils, cacert and most important nix-on-droid itself to manage local configuration, see"
|
||||||
|
echo " nix-on-droid help"
|
||||||
|
echo "or in the config file"
|
||||||
|
echo " ~/.config/nixpkgs/nix-on-droid.nix"
|
||||||
|
echo
|
||||||
|
echo "You can go for the bare nix-on-droid setup or you can configure your phone via home-manager. See \
|
||||||
|
config file for further information."
|
||||||
|
echo
|
||||||
|
''}
|
||||||
|
|
||||||
|
[ "$#" -gt 0 ] || echo "Sourcing Nix environment..."
|
||||||
|
. $HOME/.nix-profile/etc/profile.d/nix.sh
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# Workaround for https://github.com/NixOS/nix/issues/1865
|
||||||
|
export NIX_PATH=nixpkgs=$HOME/.nix-defexpr/channels/nixpkgs/:$NIX_PATH
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ]; then
|
||||||
|
exec /usr/bin/env bash
|
||||||
|
else
|
||||||
|
exec /usr/bin/env "$@"
|
||||||
|
fi
|
||||||
|
''
|
||||||
23
modules/environment/login/login.nix
Normal file
23
modules/environment/login/login.nix
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, writeScript }:
|
||||||
|
|
||||||
|
writeScript "login" ''
|
||||||
|
#!/system/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export USER="${config.user.userName}"
|
||||||
|
export PROOT_TMP_DIR=${config.build.installationDir}/tmp
|
||||||
|
export PROOT_L2S_DIR=${config.build.installationDir}/.l2s
|
||||||
|
|
||||||
|
exec "${config.build.installationDir}/bin/proot-static" \
|
||||||
|
-b ${config.build.installationDir}/nix:/nix \
|
||||||
|
-b ${config.build.installationDir}/bin:/bin \
|
||||||
|
-b ${config.build.installationDir}/etc:/etc \
|
||||||
|
-b ${config.build.installationDir}/tmp:/tmp \
|
||||||
|
-b ${config.build.installationDir}/usr:/usr \
|
||||||
|
-b /:/android \
|
||||||
|
--link2symlink \
|
||||||
|
${config.build.installationDir}/bin/sh ${config.build.installationDir}/usr/lib/login-inner "$@"
|
||||||
|
''
|
||||||
67
modules/environment/path.nix
Normal file
67
modules/environment/path.nix
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.environment;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
packages = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [];
|
||||||
|
description = "List of packages to be installed as user packages.";
|
||||||
|
};
|
||||||
|
|
||||||
|
path = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = "Derivation for installing user packages.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
build.activation.installPackages = ''
|
||||||
|
$DRY_RUN_CMD nix-env --install ${cfg.path}
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
packages = [
|
||||||
|
(pkgs.callPackage ../../nix-on-droid { })
|
||||||
|
pkgs.bashInteractive
|
||||||
|
pkgs.cacert
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.less # since nix tools really want a pager available, #27
|
||||||
|
pkgs.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
path = pkgs.buildEnv {
|
||||||
|
name = "nix-on-droid-path";
|
||||||
|
|
||||||
|
paths = cfg.packages;
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Environment of packages installed through nix-on-droid.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
59
modules/home-manager.nix
Normal file
59
modules/home-manager.nix
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.home-manager;
|
||||||
|
|
||||||
|
hmModule = types.submodule ({ name, ... }: {
|
||||||
|
imports = import <home-manager/modules/modules.nix> { inherit lib pkgs; };
|
||||||
|
|
||||||
|
config = {
|
||||||
|
submoduleSupport.enable = true;
|
||||||
|
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
|
||||||
|
|
||||||
|
home.username = config.user.userName;
|
||||||
|
home.homeDirectory = config.user.home;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
home-manager = {
|
||||||
|
config = mkOption {
|
||||||
|
type = types.nullOr hmModule;
|
||||||
|
default = null;
|
||||||
|
description = "Home Manager configuration.";
|
||||||
|
};
|
||||||
|
|
||||||
|
useUserPackages = mkEnableOption ''
|
||||||
|
installation of user packages through the
|
||||||
|
<option>environment.packages</option> option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf (cfg.config != null) {
|
||||||
|
|
||||||
|
inherit (config) assertions warnings;
|
||||||
|
|
||||||
|
build.activation.homeManager = ''
|
||||||
|
${cfg.config.home.activationPackage}/activate
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.packages = mkIf cfg.useUserPackages cfg.config.home.packages;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
20
modules/lib-bash/activation-init.sh
Normal file
20
modules/lib-bash/activation-init.sh
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
export VERBOSE_ECHO=echo
|
||||||
|
export VERBOSE_ARG="--verbose"
|
||||||
|
else
|
||||||
|
export VERBOSE_ECHO=true
|
||||||
|
export VERBOSE_ARG=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v DRY_RUN ]] ; then
|
||||||
|
echo "This is a dry run"
|
||||||
|
export DRY_RUN_CMD=echo
|
||||||
|
else
|
||||||
|
$VERBOSE_ECHO "This is a live run"
|
||||||
|
export DRY_RUN_CMD=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v VERBOSE ]]; then
|
||||||
|
echo -n "Using Nix version: "
|
||||||
|
nix --version
|
||||||
|
fi
|
||||||
37
modules/lib-bash/color-echo.sh
Normal file
37
modules/lib-bash/color-echo.sh
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
# The check for terminal output and color support is heavily inspired
|
||||||
|
# by https://unix.stackexchange.com/a/10065.
|
||||||
|
|
||||||
|
function setupColors() {
|
||||||
|
normalColor=""
|
||||||
|
errorColor=""
|
||||||
|
warnColor=""
|
||||||
|
noteColor=""
|
||||||
|
|
||||||
|
# Check if stdout is a terminal.
|
||||||
|
if [[ -t 1 ]]; then
|
||||||
|
# See if it supports colors.
|
||||||
|
local ncolors
|
||||||
|
ncolors=$(tput colors)
|
||||||
|
|
||||||
|
if [[ -n "$ncolors" && "$ncolors" -ge 8 ]]; then
|
||||||
|
normalColor="$(tput sgr0)"
|
||||||
|
errorColor="$(tput bold)$(tput setaf 1)"
|
||||||
|
warnColor="$(tput setaf 3)"
|
||||||
|
noteColor="$(tput bold)$(tput setaf 6)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
setupColors
|
||||||
|
|
||||||
|
function errorEcho() {
|
||||||
|
echo "${errorColor}$*${normalColor}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function warnEcho() {
|
||||||
|
echo "${warnColor}$*${normalColor}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function noteEcho() {
|
||||||
|
echo "${noteColor}$*${normalColor}"
|
||||||
|
}
|
||||||
14
modules/module-list.nix
Normal file
14
modules/module-list.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
[
|
||||||
|
./build/activation.nix
|
||||||
|
./build/config.nix
|
||||||
|
./environment/etc
|
||||||
|
./environment/files.nix
|
||||||
|
./environment/login
|
||||||
|
./environment/links.nix
|
||||||
|
./environment/path.nix
|
||||||
|
./user.nix
|
||||||
|
<nixpkgs/nixos/modules/misc/assertions.nix>
|
||||||
|
]
|
||||||
81
modules/user.nix
Normal file
81
modules/user.nix
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
# Licensed under GNU Lesser General Public License v3 or later, see COPYING.
|
||||||
|
# Copyright (c) 2019 Alexander Sosedkin and other contributors, see AUTHORS.
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.user;
|
||||||
|
|
||||||
|
idsDerivation = pkgs.runCommand "ids.nix" {} ''
|
||||||
|
cat > $out <<EOF
|
||||||
|
{
|
||||||
|
gid = "$(${pkgs.coreutils}/bin/id -g)";
|
||||||
|
uid = "$(${pkgs.coreutils}/bin/id -u)";
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
'';
|
||||||
|
|
||||||
|
ids = import idsDerivation;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
user = {
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "nix-on-droid";
|
||||||
|
description = "Group name.";
|
||||||
|
};
|
||||||
|
|
||||||
|
home = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
readOnly = true;
|
||||||
|
description = "Path to home directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
shell = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
readOnly = true;
|
||||||
|
description = "Path to login shell.";
|
||||||
|
};
|
||||||
|
|
||||||
|
userName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "nix-on-droid";
|
||||||
|
description = "User name.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
"group".text = ''
|
||||||
|
root:x:0:
|
||||||
|
${cfg.group}:x:${ids.gid}:${cfg.userName}
|
||||||
|
'';
|
||||||
|
|
||||||
|
"passwd".text = ''
|
||||||
|
root:x:0:0:System administrator:${config.build.installationDir}/root:/bin/sh
|
||||||
|
${cfg.userName}:x:${ids.uid}:${ids.gid}:${cfg.userName}:${cfg.home}:${cfg.shell}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
user = {
|
||||||
|
home = "/data/data/com.termux.nix/files/home";
|
||||||
|
shell = "/bin/sh";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue