diff --git a/nixos/modules/config/system-path.nix b/nixos/modules/config/system-path.nix index 5d339eaea485..d3212d931605 100644 --- a/nixos/modules/config/system-path.nix +++ b/nixos/modules/config/system-path.nix @@ -31,6 +31,7 @@ let pkgs.nano pkgs.ncurses pkgs.netcat + pkgs.nix-info config.programs.ssh.package pkgs.perl pkgs.procps diff --git a/pkgs/tools/nix/info/default.nix b/pkgs/tools/nix/info/default.nix new file mode 100644 index 000000000000..756478dccb77 --- /dev/null +++ b/pkgs/tools/nix/info/default.nix @@ -0,0 +1,37 @@ +{ stdenv, lib, coreutils, findutils, gnugrep, darwin, shellcheck }: +stdenv.mkDerivation { + name = "nix-info"; + src = ./info.sh; + + buildInputs = [ + shellcheck + ]; + + path = lib.makeBinPath ([ + coreutils findutils gnugrep + ] ++ (if stdenv.isDarwin then [ darwin.DarwinTools ] else [])); + is_darwin = if stdenv.isDarwin then "yes" else "no"; + + sandboxtest = ./sandbox.nix; + relaxedsandboxtest = ./relaxedsandbox.nix; + multiusertest = ./multiuser.nix; + + unpackCmd = '' + mkdir nix-info + cp $src ./nix-info/nix-info + ''; + + buildPhase = '' + substituteAllInPlace ./nix-info + ''; + + doCheck = true; + checkPhase = '' + shellcheck ./nix-info + ''; + + installPhase = '' + mkdir -p $out/bin + cp ./nix-info $out/bin/nix-info + ''; +} diff --git a/pkgs/tools/nix/info/info.sh b/pkgs/tools/nix/info/info.sh new file mode 100755 index 000000000000..473e035b8e0a --- /dev/null +++ b/pkgs/tools/nix/info/info.sh @@ -0,0 +1,169 @@ +#!/bin/bash + +PATH="@path@:$PATH" +IS_DARWIN="@is_darwin@" + +set -eu +set -o pipefail + +DEBUG=0 +MARKDOWN=0 +HOST_OS=0 +SANDBOX=0 +while true; do + case "${1:-}" in + "") + break + ;; + -d | --debug) + set -x + DEBUG=1 + shift + ;; + -m | --markdown) + MARKDOWN=1 + HOST_OS=1 + SANDBOX=1 + shift + ;; + --host-os) + HOST_OS=1 + shift + ;; + --sandbox) + SANDBOX=1 + shift + ;; + + * ) + cat <&2 + else + cat > /dev/null + fi +} + +nixev() { + nix-instantiate --eval --strict -E "$1" +} + +desc_system() { + nixev '(import {}).system' +} + +desc_host_os() { + printf "%s" "$(uname -sr)" + + if [ "$IS_DARWIN" = "yes" ]; then + printf ", macOS %s" "$(sw_vers -productVersion)" + fi + + if [ -f /etc/os-release ]; then + ( + # shellcheck disable=SC1091 + . /etc/os-release + printf ", %s, %s" "${NAME:-$(uname -v)}" "${VERSION:-noversion}" + ) + fi +} + +desc_multi_user() { + if nix-build --no-out-link @multiusertest@ 2>&1 | debuglog; then + printf "yes" + else + printf "no" + fi +} + +desc_nixpkgs_path() { + nixev '' +} + +channel_facts() { + find /nix/var/nix/profiles/per-user \ + -mindepth 2 \ + -maxdepth 2 \ + -name channels \ + -print0 \ + |\ + while IFS= read -r -d '' userchannelset; do + manifest="$userchannelset/manifest.nix" + + if [ -e "$manifest" ]; then + userchannels=$(nixev \ + "builtins.concatStringsSep \", \" + (map (ch: ch.name) + (import \"$manifest\"))") + + fact "channels($(echo "$manifest" | cut -d/ -f7))" \ + "$userchannels" + fi + done +} + +desc_sandbox() { + if nix-build --no-out-link @sandboxtest@ 2>&1 | debuglog; then + printf "no" + elif nix-build --no-out-link @relaxedsandboxtest@ 2>&1 | debuglog; then + printf "relaxed" + else + printf "yes" + fi +} + +fact() { + name="${1:-0}" + value="${2:-0}" + last="${3:-1}" + if [ $MARKDOWN -eq 0 ]; then + printf "%s: %s" "$name" "$value" + if [ "$last" -eq 1 ]; then + printf ", " + fi + else + printf " - %s: \`%s\`\n" "$name" "$value" + fi + + if [ "$last" -eq 0 ]; then + echo "" + fi +} + +last_fact() { + fact "$1" "$2" 0 +} + +fact "system" "$(desc_system)" +if [ $HOST_OS -eq 1 ]; then + fact "host os" "$(desc_host_os)" +fi +fact "multi-user?" "$(desc_multi_user)" +if [ $SANDBOX -eq 1 ]; then + fact "sandbox" "$(desc_sandbox)" +fi + +fact "version" "$(nix-env --version)" +channel_facts +last_fact "nixpkgs" "$(desc_nixpkgs_path)" diff --git a/pkgs/tools/nix/info/multiuser.nix b/pkgs/tools/nix/info/multiuser.nix new file mode 100644 index 000000000000..827d52987673 --- /dev/null +++ b/pkgs/tools/nix/info/multiuser.nix @@ -0,0 +1,12 @@ +let + pkgs = import {}; +in pkgs.runCommand "diagnostics-multiuser" + { } + '' + set -x + # no cache: ${toString builtins.currentTime} + # For reproducibility, nix always uses nixbld group: + # https://github.com/NixOS/nix/blob/1dd29d7aebae706f3e90a18bbfae727f2ed03c70/src/libstore/build.cc#L1896-L1908 + test "$(groups)" == "nixbld" + touch $out + '' diff --git a/pkgs/tools/nix/info/relaxedsandbox.nix b/pkgs/tools/nix/info/relaxedsandbox.nix new file mode 100644 index 000000000000..625a6ecc39e0 --- /dev/null +++ b/pkgs/tools/nix/info/relaxedsandbox.nix @@ -0,0 +1,12 @@ +let + pkgs = import {}; +in pkgs.runCommand "diagnostics-sandbox" + { + __noChroot = true; + } + '' + set -x + # no cache: ${toString builtins.currentTime} + test -d "$(dirname "$out")/../var/nix" + touch $out + '' diff --git a/pkgs/tools/nix/info/sandbox.nix b/pkgs/tools/nix/info/sandbox.nix new file mode 100644 index 000000000000..fa4288c2f944 --- /dev/null +++ b/pkgs/tools/nix/info/sandbox.nix @@ -0,0 +1,10 @@ +let + pkgs = import {}; +in pkgs.runCommand "diagnostics-sandbox" + { } + '' + set -x + # no cache: ${toString builtins.currentTime} + test -d "$(dirname "$out")/../var/nix" + touch $out + '' diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 6057489c5657..faacdcb59e50 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -19154,6 +19154,8 @@ with pkgs; nix-bundle = callPackage ../tools/package-management/nix-bundle { nix = nixUnstable; }; + nix-info = callPackage ../tools/nix/info { }; + nix-index = callPackage ../tools/package-management/nix-index { }; inherit (callPackages ../tools/package-management/nix-prefetch-scripts { }) diff --git a/pkgs/top-level/release.nix b/pkgs/top-level/release.nix index d6cefb8d184b..952b1e8927e4 100644 --- a/pkgs/top-level/release.nix +++ b/pkgs/top-level/release.nix @@ -47,6 +47,7 @@ let jobs.nix-repl.x86_64-darwin jobs.nix.x86_64-darwin jobs.nox.x86_64-darwin + jobs.nix-info.x86_64-darwin jobs.openssh.x86_64-darwin jobs.openssl.x86_64-darwin jobs.postgresql.x86_64-darwin @@ -88,6 +89,9 @@ let # Needed by travis-ci to test PRs jobs.nox.x86_64-linux jobs.nox.x86_64-darwin + # Needed for support + jobs.nix-info.x86_64-linux + jobs.nix-info.x86_64-darwin # Ensure that X11/GTK+ are in order. jobs.thunderbird.x86_64-linux # Ensure that basic stuff works on darwin