Add a "nixos-enter" command

This factors out the functionality in nixos-install for running a
command inside a NixOS installation (nixos-install --chroot).
This commit is contained in:
Eelco Dolstra 2018-02-05 19:41:54 +01:00
parent 294a4e6ea5
commit 60cb23001a
No known key found for this signature in database
GPG Key ID: 8170B4726D7198DE
4 changed files with 189 additions and 3 deletions

View File

@ -0,0 +1,119 @@
<refentry xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refmeta>
<refentrytitle><command>nixos-enter</command></refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo class="source">NixOS</refmiscinfo>
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
</refmeta>
<refnamediv>
<refname><command>nixos-enter</command></refname>
<refpurpose>run a command in a NixOS chroot environment</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>nixos-enter</command>
<arg>
<arg choice='plain'><option>--root</option></arg>
<replaceable>root</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--system</option></arg>
<replaceable>system</replaceable>
</arg>
<arg>
<arg choice='plain'><option>-c</option></arg>
<replaceable>shell-command</replaceable>
</arg>
<arg>
<arg choice='plain'><option>--help</option></arg>
</arg>
<arg>
<arg choice='plain'><option>--</option></arg>
<replaceable>arguments</replaceable>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsection><title>Description</title>
<para>This command runs a command in a NixOS chroot environment, that
is, in a filesystem hierarchy previously prepared using
<command>nixos-install</command>.</para>
</refsection>
<refsection><title>Options</title>
<para>This command accepts the following options:</para>
<variablelist>
<varlistentry>
<term><option>--root</option></term>
<listitem>
<para>The path to the NixOS system you want to enter. It defaults to <filename>/mnt</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--system</option></term>
<listitem>
<para>The NixOS system configuration to use. It defaults to
<filename>/nix/var/nix/profiles/system</filename>. You can enter
a previous NixOS configuration by specifying a path such as
<filename>/nix/var/nix/profiles/system-106-link</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--command</option></term>
<term><option>-c</option></term>
<listitem>
<para>The bash command to execute.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--</option></term>
<listitem><para>Interpret the remaining arguments as the program
name and arguments to be invoked. The program is not executed in a
shell.</para></listitem>
</varlistentry>
</variablelist>
</refsection>
<refsection><title>Examples</title>
<para>Start an interactive shell in the NixOS installation in
<filename>/mnt</filename>:</para>
<screen>
# nixos-enter /mnt
</screen>
<para>Run a shell command:</para>
<screen>
# nixos-enter -c 'ls -l /; cat /proc/mounts'
</screen>
<para>Run a non-shell command:</para>
<screen>
# nixos-enter -- cat /proc/mounts
</screen>
</refsection>
</refentry>

View File

@ -15,7 +15,7 @@
</author>
<copyright>
<year>2007-2015</year>
<year>2007-2018</year>
<holder>Eelco Dolstra</holder>
</copyright>
@ -25,6 +25,7 @@
<xi:include href="man-nixos-build-vms.xml" />
<xi:include href="man-nixos-generate-config.xml" />
<xi:include href="man-nixos-install.xml" />
<xi:include href="man-nixos-enter.xml" />
<xi:include href="man-nixos-option.xml" />
<xi:include href="man-nixos-rebuild.xml" />
<xi:include href="man-nixos-version.xml" />

View File

@ -0,0 +1,58 @@
#! @shell@
set -e
# Re-exec ourselves in a private mount namespace so that our bind
# mounts get cleaned up automatically.
if [ "$(id -u)" = 0 ]; then
if [ -z "$NIXOS_ENTER_REEXEC" ]; then
export NIXOS_ENTER_REEXEC=1
exec unshare --mount --uts -- "$0" "$@"
else
mount --make-rprivate /
fi
fi
mountPoint=/mnt
command=("bash" "--login")
system=/nix/var/nix/profiles/system
while [ "$#" -gt 0 ]; do
i="$1"; shift 1
case "$i" in
--root)
mountPoint="$1"; shift 1
;;
--system)
system="$1"; shift 1
;;
--help)
exec man nixos-enter
exit 1
;;
--command|-c)
command=("bash" "-c" "$1")
shift 1
;;
--)
command=("$@")
break
;;
*)
echo "$0: unknown option \`$i'"
exit 1
;;
esac
done
# Set up some bind mounts we'll want regardless of chroot or not
mkdir -m 0755 -p "$mountPoint/dev" "$mountPoint/proc" "$mountPoint/sys" "$mountPoint/run"
mount --rbind /dev "$mountPoint/dev"
mount -t proc none "$mountPoint/proc"
mount -t sysfs none "$mountPoint/sys"
mount -t tmpfs none "$mountPoint/run"
# Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
LOCALE_ARCHIVE=$system/sw/lib/locale/locale-archive chroot "$mountPoint" "$system/activate" >&2
exec chroot "$mountPoint" "${command[@]}"

View File

@ -1,7 +1,9 @@
# This module generates nixos-install, nixos-rebuild,
# nixos-generate-config, etc.
{ config, pkgs, modulesPath, ... }:
{ config, lib, pkgs, modulesPath, ... }:
with lib;
let
cfg = config.installer;
@ -69,6 +71,11 @@ let
inherit (config.system) nixosVersion nixosCodeName nixosRevision;
};
nixos-enter = makeProg {
name = "nixos-enter";
src = ./nixos-enter.sh;
};
in
{
@ -83,10 +90,11 @@ in
nixos-generate-config
nixos-option
nixos-version
nixos-enter
];
system.build = {
inherit nixos-install nixos-prepare-root nixos-generate-config nixos-option nixos-rebuild;
inherit nixos-install nixos-prepare-root nixos-generate-config nixos-option nixos-rebuild nixos-enter;
};
};