From 96ebc83053b12a488dfeef144f288827b819d023 Mon Sep 17 00:00:00 2001 From: Artturin Date: Tue, 10 Jan 2023 22:45:10 +0200 Subject: [PATCH] deterministic-uname: init for reproducibility deterministic-uname: dont hardcode OPERATING_SYSTEM_VAL to GNU/Linux --- .../deterministic-uname/default.nix | 54 ++++++ .../deterministic-uname.sh | 175 ++++++++++++++++++ .../linux/lsb-release/lsb_release.sh | 2 +- pkgs/top-level/all-packages.nix | 2 + 4 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 pkgs/build-support/deterministic-uname/default.nix create mode 100644 pkgs/build-support/deterministic-uname/deterministic-uname.sh diff --git a/pkgs/build-support/deterministic-uname/default.nix b/pkgs/build-support/deterministic-uname/default.nix new file mode 100644 index 000000000000..917569618b4f --- /dev/null +++ b/pkgs/build-support/deterministic-uname/default.nix @@ -0,0 +1,54 @@ +# expr and script based on our lsb_release +{ stdenv +, lib +, substituteAll +, coreutils +, getopt +, modDirVersion ? "" +}: + +substituteAll { + name = "uname"; + + src = ./deterministic-uname.sh; + + dir = "bin"; + isExecutable = true; + + inherit coreutils getopt; + + uSystem = if stdenv.buildPlatform.uname.system != null then stdenv.buildPlatform.uname.system else "unknown"; + inherit (stdenv.buildPlatform.uname) processor; + + # uname -o + # maybe add to lib/systems/default.nix uname attrset + # https://github.com/coreutils/coreutils/blob/7fc84d1c0f6b35231b0b4577b70aaa26bf548a7c/src/uname.c#L373-L374 + # https://stackoverflow.com/questions/61711186/where-does-host-operating-system-in-uname-c-comes-from + # https://github.com/coreutils/gnulib/blob/master/m4/host-os.m4 + operatingSystem = + if stdenv.buildPlatform.isLinux + then "GNU/Linux" + else if stdenv.buildPlatform.isDarwin + then "Darwin" # darwin isn't in host-os.m4 so where does this come from? + else "unknown"; + + # in os-specific/linux module packages + # --replace '$(shell uname -r)' "${kernel.modDirVersion}" \ + # is a common thing to do. + modDirVersion = if modDirVersion != "" then modDirVersion else "unknown"; + + meta = with lib; { + description = "Print certain system information (hardcoded with values)"; + longDescription = '' + This package provides a replacement for `uname` whose output depends only + on `stdenv.buildPlatform`. It is meant to be used from within derivations. + Many packages' build processes run `uname` at compile time and embed its + output into the result of the build. Since `uname` calls into the kernel, + and the Nix sandbox currently does not intercept these calls, builds made + on different kernels will produce different results. + ''; + license = [ licenses.mit ]; + maintainers = with maintainers; [ artturin ]; + platforms = platforms.all; + }; +} diff --git a/pkgs/build-support/deterministic-uname/deterministic-uname.sh b/pkgs/build-support/deterministic-uname/deterministic-uname.sh new file mode 100644 index 000000000000..134bd467bce3 --- /dev/null +++ b/pkgs/build-support/deterministic-uname/deterministic-uname.sh @@ -0,0 +1,175 @@ +#! @shell@ + +set -o errexit +set -o nounset + +show_help() { + @coreutils@/bin/cat << EOF +Usage: uname [OPTION]... +Print certain system information. With no OPTION, same as -s. + + -a, --all print all information, in the following order, + except omit -p and -i if unknown: + -s, --kernel-name print the kernel name + -n, --nodename print the network node hostname + -r, --kernel-release print the kernel release + -v, --kernel-version print the kernel version + -m, --machine print the machine hardware name + -p, --processor print the processor type (non-portable) + -i, --hardware-platform print the hardware platform (non-portable) + -o, --operating-system print the operating system + --help display this help and exit + --version output version information and exit +EOF + exit 0 +} + +# Potential command-line options. +version=0 +all=0 + + +kernel_name=0 +nodename=0 +kernel_release=0 +kernel_version=0 +machine=0 +processor=0 +hardware_platform=0 +operating_system=0 + + +@getopt@/bin/getopt --test > /dev/null && rc=$? || rc=$? +if [[ $rc -ne 4 ]]; then + # This shouldn't happen. + echo "Warning: Enhanced getopt not supported, please open an issue in nixpkgs." >&2 +else + # Define all short and long options. + SHORT=hvsnrvmpioa + LONG=help,version,kernel-name,nodename,kernel-release,kernel-version,machine,processor,hardware-platform,operating-system,all + + # Parse all options. + PARSED=`@getopt@/bin/getopt --options $SHORT --longoptions $LONG --name "$0" -- "$@"` + + eval set -- "$PARSED" +fi + +# With no OPTION, same as -s. +if [[ $# -eq 0 ]]; then + kernel_name=1 +fi + +# Process each argument, and set the appropriate flag if we recognize it. +while [[ $# -ge 1 ]]; do + case "$1" in + --version) + version=1 + ;; + -s|--kernel-name) + kernel_name=1 + ;; + -n|--nodename) + nodename=1 + ;; + -r|--kernel-release) + kernel_release=1 + ;; + -v|--kernel-version) + kernel_version=1 + ;; + -m|--machine) + machine=1 + ;; + -p|--processor) + processor=1 + ;; + -i|--hardware-platform) + hardware_platform=1 + ;; + -o|--operating-system) + operating_system=1 + ;; + -a|--all) + all=1 + ;; + --help) + show_help + ;; + --) + shift + break + ;; + *) + echo "uname: unrecognized option '$1'" + echo "Type 'uname --help' for a list of available options." + exit 1 + ;; + esac + shift +done + + +KERNEL_NAME_VAL=@uSystem@ +NODENAME_VAL=nixpkgs +KERNEL_RELEASE_VAL=@modDirVersion@ +# #1-NixOS SMP PREEMPT_DYNAMIC Wed Dec 14 10:41:06 UTC 2022 +KERNEL_VERSION_VAL="#1-NixOS Tue Jan 1 00:00:00 UTC 1980" +MACHINE_VAL=@processor@ +PROCESSOR_VAL=unknown +HARDWARE_PLATFORM_VAL=unknown +OPERATING_SYSTEM_VAL=@operatingSystem@ + + +if [[ "$version" = "1" ]]; then + # in case some script greps for GNU coreutils. + echo "uname (GNU coreutils) 9.1" + echo "Nixpkgs deterministic-uname" + exit +fi + +# output of the real uname from GNU coreutils +# Darwin: +# Darwin *nodename* 22.1.0 Darwin Kernel Version 22.1.0: Sun Oct 9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103 arm64 arm Darwin +# NixOS: +# Linux *nodename* 6.0.13 #1-NixOS SMP PREEMPT_DYNAMIC Wed Dec 14 10:41:06 UTC 2022 x86_64 GNU/Linux +if [[ "$all" = "1" ]]; then + echo -n "$KERNEL_NAME_VAL $NODENAME_VAL $KERNEL_RELEASE_VAL $KERNEL_VERSION_VAL $MACHINE_VAL" + # in help: except omit -p and -i if unknown. + #echo -n "$PROCESSOR_VAL $HARDWARE_PLATFORM_VAL\n" + echo -n "$OPERATING_SYSTEM_VAL" +fi + +if [[ "$kernel_name" = "1" ]]; then + echo -n "$KERNEL_NAME_VAL" +fi + +if [[ "$nodename" = "1" ]]; then + echo -n "$NODENAME_VAL" +fi + +if [[ "$kernel_release" = "1" ]]; then + echo -n "$KERNEL_RELEASE_VAL" +fi + +if [[ "$kernel_version" = "1" ]]; then + echo -n "$KERNEL_VERSION_VAL" +fi + +if [[ "$machine" = "1" ]]; then + echo -n "$MACHINE_VAL" +fi + +if [[ "$processor" = "1" ]]; then + echo -n "$PROCESSOR_VAL" +fi + +if [[ "$hardware_platform" = "1" ]]; then + echo -n "$HARDWARE_PLATFORM_VAL" +fi + +if [[ "$operating_system" = "1" ]]; then + echo -n "$OPERATING_SYSTEM_VAL" +fi + +# for newline. +echo diff --git a/pkgs/os-specific/linux/lsb-release/lsb_release.sh b/pkgs/os-specific/linux/lsb-release/lsb_release.sh index 47b449c31614..ae524181e88a 100644 --- a/pkgs/os-specific/linux/lsb-release/lsb_release.sh +++ b/pkgs/os-specific/linux/lsb-release/lsb_release.sh @@ -32,7 +32,7 @@ short=0 @getopt@/bin/getopt --test > /dev/null && rc=$? || rc=$? if [[ $rc -ne 4 ]]; then # This shouldn't happen. - echo "Warning: Enhanced getopt not supported, please open an issue." >&2 + echo "Warning: Enhanced getopt not supported, please open an issue in nixpkgs." >&2 else # Define all short and long options. SHORT=hvidrcas diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 2470aae99a26..0a43cafe6b83 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2984,6 +2984,8 @@ with pkgs; detect-secrets = with python3Packages; toPythonApplication detect-secrets; + deterministic-uname = callPackage ../build-support/deterministic-uname { }; + dfmt = callPackage ../tools/text/dfmt { }; diopser = callPackage ../applications/audio/diopser { stdenv = gcc10StdenvCompat; };