cc1ae918bd
Pointed out by Mathnerd626 on irc Signed-off-by: Shea Levy <shea@shealevy.com>
379 lines
9.2 KiB
Bash
379 lines
9.2 KiB
Bash
#! @shell@ -e
|
|
|
|
# Allow the location of NixOS sources and the system configuration
|
|
# file to be overridden.
|
|
|
|
: ${mountPoint=/mnt}
|
|
: ${NIXOS_CONFIG=/etc/nixos/configuration.nix}
|
|
export NIXOS_CONFIG
|
|
|
|
usage () {
|
|
echo 1>&2 "
|
|
Usage: $0 [-v] [-d] [-l] [--xml] OPTION_NAME
|
|
$0 --install
|
|
|
|
This program allows you to inspect the current value of NixOS
|
|
configuration options. It can also generate a basic NixOS
|
|
configuration file.
|
|
|
|
Options:
|
|
|
|
-i | --install Write a template NixOS configuration file to
|
|
${mountPoint:+$mountPoint/}$NIXOS_CONFIG.
|
|
-v | --value Display the current value, based on your
|
|
configuration.
|
|
-d | --description Display the default value, the example and the
|
|
description.
|
|
-l | --lookup Display where the option is defined and where it
|
|
is declared.
|
|
--xml Print an XML representation of the result.
|
|
Implies -vdl options.
|
|
--help Show this message.
|
|
|
|
Environment variables affecting $0:
|
|
|
|
\$mountPoint Path to the target file system.
|
|
\$NIXOS_CONFIG Path to your configuration file.
|
|
|
|
"
|
|
|
|
exit 1;
|
|
}
|
|
|
|
#####################
|
|
# Process Arguments #
|
|
#####################
|
|
|
|
desc=false
|
|
defs=false
|
|
value=false
|
|
xml=false
|
|
install=false
|
|
verbose=false
|
|
|
|
option=""
|
|
|
|
argfun=""
|
|
for arg; do
|
|
if test -z "$argfun"; then
|
|
case $arg in
|
|
-*)
|
|
longarg=""
|
|
sarg="$arg"
|
|
while test "$sarg" != "-"; do
|
|
case $sarg in
|
|
--*) longarg=$arg; sarg="--";;
|
|
-d*) longarg="$longarg --description";;
|
|
-v*) longarg="$longarg --value";;
|
|
-l*) longarg="$longarg --lookup";;
|
|
-i*) longarg="$longarg --install";;
|
|
-*) usage;;
|
|
esac
|
|
# remove the first letter option
|
|
sarg="-${sarg#??}"
|
|
done
|
|
;;
|
|
*) longarg=$arg;;
|
|
esac
|
|
for larg in $longarg; do
|
|
case $larg in
|
|
--description) desc=true;;
|
|
--value) value=true;;
|
|
--lookup) defs=true;;
|
|
--xml) xml=true;;
|
|
--install) install=true;;
|
|
--verbose) verbose=true;;
|
|
--help) usage;;
|
|
-*) usage;;
|
|
*) if test -z "$option"; then
|
|
option="$larg"
|
|
else
|
|
usage
|
|
fi;;
|
|
esac
|
|
done
|
|
else
|
|
case $argfun in
|
|
set_*)
|
|
var=$(echo $argfun | sed 's,^set_,,')
|
|
eval $var=$arg
|
|
;;
|
|
esac
|
|
argfun=""
|
|
fi
|
|
done
|
|
|
|
if $xml; then
|
|
value=true
|
|
desc=true
|
|
defs=true
|
|
fi
|
|
|
|
# --install cannot be used with -d -v -l without option name.
|
|
if $value || $desc || $defs && $install && test -z "$option"; then
|
|
usage
|
|
fi
|
|
|
|
generate=false
|
|
if ! $defs && ! $desc && ! $value && $install && test -z "$option"; then
|
|
generate=true
|
|
fi
|
|
|
|
if ! $defs && ! $desc; then
|
|
value=true
|
|
fi
|
|
|
|
if $verbose; then
|
|
set -x
|
|
else
|
|
set +x
|
|
fi
|
|
|
|
#############################
|
|
# Process the configuration #
|
|
#############################
|
|
|
|
evalNix(){
|
|
nix-instantiate - --eval-only "$@"
|
|
}
|
|
|
|
evalAttr(){
|
|
local prefix=$1
|
|
local suffix=$2
|
|
local strict=$3
|
|
echo "(import <nixos> {}).$prefix${option:+.$option}${suffix:+.$suffix}" |
|
|
evalNix ${strict:+--strict}
|
|
}
|
|
|
|
evalOpt(){
|
|
evalAttr "eval.options" "$@"
|
|
}
|
|
|
|
evalCfg(){
|
|
evalAttr "config" "$@"
|
|
}
|
|
|
|
findSources(){
|
|
local suffix=$1
|
|
echo "builtins.map (f: f.source) (import <nixos> {}).eval.options${option:+.$option}.$suffix" |
|
|
evalNix --strict
|
|
}
|
|
|
|
# Given a result from nix-instantiate, recover the list of attributes it
|
|
# contains.
|
|
attrNames() {
|
|
local attributeset=$1
|
|
# sed is used to replace un-printable subset by 0s, and to remove most of
|
|
# the inner-attribute set, which reduce the likelyhood to encounter badly
|
|
# pre-processed input.
|
|
echo "builtins.attrNames $attributeset" | \
|
|
sed 's,<[A-Z]*>,0,g; :inner; s/{[^\{\}]*};/0;/g; t inner;' | \
|
|
evalNix --strict
|
|
}
|
|
|
|
# map a simple list which contains strings or paths.
|
|
nixMap() {
|
|
local fun="$1"
|
|
local list="$2"
|
|
local elem
|
|
for elem in $list; do
|
|
test $elem = '[' -o $elem = ']' && continue;
|
|
$fun $elem
|
|
done
|
|
}
|
|
|
|
if $install; then
|
|
NIXOS_CONFIG="$mountPoint$NIXOS_CONFIG"
|
|
fi
|
|
|
|
if $generate; then
|
|
mkdir -p $(dirname "$NIXOS_CONFIG")
|
|
|
|
# Scan the hardware and add the result to /etc/nixos/hardware-scan.nix.
|
|
hardware_config="${NIXOS_CONFIG%/configuration.nix}/hardware-configuration.nix"
|
|
if test -e "$hardware_config"; then
|
|
echo "A hardware configuration file exists, generation skipped."
|
|
else
|
|
echo "Generating a hardware configuration file in $hardware_config..."
|
|
nixos-hardware-scan > "$hardware_config"
|
|
fi
|
|
|
|
if test -e "$NIXOS_CONFIG"; then
|
|
echo 1>&2 "error: Cannot generate a template configuration because a configuration file exists."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Generating a basic configuration file in $NIXOS_CONFIG..."
|
|
|
|
# Generate a template configuration file where the user has to
|
|
# fill the gaps.
|
|
cat <<EOF > "$NIXOS_CONFIG"
|
|
# Edit this configuration file to define what should be installed on
|
|
# the system. Help is available in the configuration.nix(5) man page
|
|
# or the NixOS manual available on virtual console 8 (Alt+F8).
|
|
|
|
{ config, pkgs, ... }:
|
|
|
|
{
|
|
require =
|
|
[ # Include the results of the hardware scan.
|
|
./hardware-configuration.nix
|
|
];
|
|
|
|
boot.initrd.kernelModules =
|
|
[ # Specify all kernel modules that are necessary for mounting the root
|
|
# filesystem.
|
|
# "xfs" "ata_piix"
|
|
];
|
|
|
|
# Use the GRUB 2 boot loader.
|
|
boot.loader.grub.enable = true;
|
|
boot.loader.grub.version = 2;
|
|
|
|
# Define on which hard drive you want to install Grub.
|
|
# boot.loader.grub.device = "/dev/sda";
|
|
|
|
# networking.hostName = "nixos"; # Define your hostname.
|
|
# networking.wireless.enable = true; # Enables Wireless.
|
|
|
|
# Add filesystem entries for each partition that you want to see
|
|
# mounted at boot time. This should include at least the root
|
|
# filesystem.
|
|
|
|
# fileSystems."/".device = "/dev/disk/by-label/nixos";
|
|
|
|
# fileSystems."/data" = # where you want to mount the device
|
|
# { device = "/dev/sdb"; # the device
|
|
# fsType = "ext3"; # the type of the partition
|
|
# options = "data=journal";
|
|
# };
|
|
|
|
# List swap partitions activated at boot time.
|
|
swapDevices =
|
|
[ # { device = "/dev/disk/by-label/swap"; }
|
|
];
|
|
|
|
# Select internationalisation properties.
|
|
# i18n = {
|
|
# consoleFont = "lat9w-16";
|
|
# consoleKeyMap = "us";
|
|
# defaultLocale = "en_US.UTF-8";
|
|
# };
|
|
|
|
# List services that you want to enable:
|
|
|
|
# Enable the OpenSSH daemon.
|
|
# services.openssh.enable = true;
|
|
|
|
# Enable CUPS to print documents.
|
|
# services.printing.enable = true;
|
|
|
|
# Enable the X11 windowing system.
|
|
# services.xserver.enable = true;
|
|
# services.xserver.layout = "us";
|
|
# services.xserver.xkbOptions = "eurosign:e";
|
|
|
|
# Enable the KDE Desktop Environment.
|
|
# services.xserver.displayManager.kdm.enable = true;
|
|
# services.xserver.desktopManager.kde4.enable = true;
|
|
}
|
|
EOF
|
|
|
|
exit 0
|
|
fi;
|
|
|
|
# This duplicates the work made below, but it is useful for processing
|
|
# the output of nixos-option with other tools such as nixos-gui.
|
|
if $xml; then
|
|
evalNix --xml --no-location <<EOF
|
|
let
|
|
reach = attrs: attrs${option:+.$option};
|
|
nixos = import <nixos> {};
|
|
nixpkgs = import <nixpkgs> {};
|
|
sources = builtins.map (f: f.source);
|
|
opt = reach nixos.eval.options;
|
|
cfg = reach nixos.config;
|
|
in
|
|
|
|
with nixpkgs.lib;
|
|
|
|
let
|
|
optStrict = v:
|
|
let
|
|
traverse = x :
|
|
if isAttrs x then
|
|
if x ? outPath then true
|
|
else all id (mapAttrsFlatten (n: traverseNoAttrs) x)
|
|
else traverseNoAttrs x;
|
|
traverseNoAttrs = x:
|
|
# do not continue in attribute sets
|
|
if isAttrs x then true
|
|
else if isList x then all id (map traverse x)
|
|
else true;
|
|
in assert traverse v; v;
|
|
in
|
|
|
|
if isOption opt then
|
|
optStrict ({}
|
|
// optionalAttrs (opt ? default) { inherit (opt) default; }
|
|
// optionalAttrs (opt ? example) { inherit (opt) example; }
|
|
// optionalAttrs (opt ? description) { inherit (opt) description; }
|
|
// optionalAttrs (opt ? type) { typename = opt.type.name; }
|
|
// optionalAttrs (opt ? options) { inherit (opt) options; }
|
|
// {
|
|
# to disambiguate the xml output.
|
|
_isOption = true;
|
|
declarations = sources opt.declarations;
|
|
definitions = sources opt.definitions;
|
|
value = cfg;
|
|
})
|
|
else
|
|
opt
|
|
EOF
|
|
exit $?
|
|
fi
|
|
|
|
if test "$(evalOpt "_type" 2> /dev/null)" = '"option"'; then
|
|
$value && evalCfg;
|
|
|
|
if $desc; then
|
|
$value && echo;
|
|
|
|
if default=$(evalOpt "default" - 2> /dev/null); then
|
|
echo "Default: $default"
|
|
else
|
|
echo "Default: <None>"
|
|
fi
|
|
if example=$(evalOpt "example" - 2> /dev/null); then
|
|
echo "Example: $example"
|
|
fi
|
|
echo "Description:"
|
|
eval printf $(evalOpt "description")
|
|
fi
|
|
|
|
if $defs; then
|
|
$desc || $value && echo;
|
|
|
|
printPath () { echo " $1"; }
|
|
|
|
echo "Declared by:"
|
|
nixMap printPath "$(findSources "declarations")"
|
|
echo ""
|
|
echo "Defined by:"
|
|
nixMap printPath "$(findSources "definitions")"
|
|
echo ""
|
|
fi
|
|
|
|
else
|
|
# echo 1>&2 "Warning: This value is not an option."
|
|
|
|
result=$(evalCfg)
|
|
if names=$(attrNames "$result" 2> /dev/null); then
|
|
echo 1>&2 "This attribute set contains:"
|
|
escapeQuotes () { eval echo "$1"; }
|
|
nixMap escapeQuotes "$names"
|
|
else
|
|
echo 1>&2 "An error occured while looking for attribute names."
|
|
echo $result
|
|
fi
|
|
fi
|