lsb-release: Fix/replace with a custom Bash script (#64258)

See #64258 for more details and some discussion.
Fix #22729.

tl;dr: This fixes the behaviour at run-time but uses "n/a" defaults
inside the Nix build sandbox (build-time).

There might still be a few minor regressions, we might have to tweak
the behaviour over time (e.g. the implementation from Debian also
differs from the original version), and we could refactor the script,
but it should work well enough for now.

authored by Michael Weiss and committed by GitHub 63f93407 c0fe97b1

+203 -26
+13 -26
pkgs/os-specific/linux/lsb-release/default.nix
··· 1 - { stdenv, fetchurl, perl, coreutils, getopt, makeWrapper }: 1 + { substituteAll, lib 2 + , coreutils, getopt 3 + }: 2 4 3 - stdenv.mkDerivation rec { 4 - version = "1.4"; 5 - name = "lsb-release-${version}"; 5 + substituteAll { 6 + name = "lsb_release"; 6 7 7 - src = fetchurl { 8 - url = "mirror://sourceforge/lsb/${name}.tar.gz"; 9 - sha256 = "0wkiy7ymfi3fh2an2g30raw6yxh6rzf6nz2v90fplbnnz2414clr"; 10 - }; 8 + src = ./lsb_release.sh; 11 9 12 - preConfigure = '' 13 - substituteInPlace help2man \ 14 - --replace /usr/bin/perl ${perl}/bin/perl 15 - ''; 10 + dir = "bin"; 11 + isExecutable = true; 16 12 17 - installFlags = [ "prefix=$(out)" ]; 18 - 19 - nativeBuildInputs = [ makeWrapper perl ]; 20 - 21 - buildInputs = [ coreutils getopt ]; 13 + inherit coreutils getopt; 22 14 23 - # Ensure utilities used are available 24 - preFixup = '' 25 - wrapProgram $out/bin/lsb_release --prefix PATH : ${stdenv.lib.makeBinPath [ coreutils getopt ]} 26 - ''; 27 - 28 - meta = { 15 + meta = with lib; { 29 16 description = "Prints certain LSB (Linux Standard Base) and Distribution information"; 30 - homepage = http://www.linuxfoundation.org/collaborate/workgroups/lsb; 31 - license = [ stdenv.lib.licenses.gpl2Plus stdenv.lib.licenses.gpl3Plus ]; 32 - platforms = stdenv.lib.platforms.linux; 17 + license = [ licenses.mit ]; 18 + maintainers = with maintainers; [ primeos ]; 19 + platforms = platforms.linux; 33 20 }; 34 21 }
+190
pkgs/os-specific/linux/lsb-release/lsb_release.sh
··· 1 + #! @shell@ 2 + 3 + set -o errexit 4 + set -o nounset 5 + 6 + show_help() { 7 + @coreutils@/bin/cat << EOF 8 + Usage: lsb_release [options] 9 + 10 + Options: 11 + -h, --help show this help message and exit 12 + -v, --version show LSB modules this system supports 13 + -i, --id show distributor ID 14 + -d, --description show description of this distribution 15 + -r, --release show release number of this distribution 16 + -c, --codename show code name of this distribution 17 + -a, --all show all of the above information 18 + -s, --short show requested information in short format 19 + EOF 20 + exit 0 21 + } 22 + 23 + # Potential command-line options. 24 + version=0 25 + id=0 26 + description=0 27 + release=0 28 + codename=0 29 + all=0 30 + short=0 31 + 32 + @getopt@/bin/getopt --test > /dev/null && rc=$? || rc=$? 33 + if [[ $rc -ne 4 ]]; then 34 + # This shouldn't happen. 35 + echo "Warning: Enhanced getopt not supported, please open an issue." >&2 36 + else 37 + # Define all short and long options. 38 + SHORT=hvidrcas 39 + LONG=help,version,id,description,release,codename,all,short 40 + 41 + # Parse all options. 42 + PARSED=`@getopt@/bin/getopt --options $SHORT --longoptions $LONG --name "$0" -- "$@"` 43 + 44 + eval set -- "$PARSED" 45 + fi 46 + 47 + 48 + # Process each argument, and set the appropriate flag if we recognize it. 49 + while [[ $# -ge 1 ]]; do 50 + case "$1" in 51 + -v|--version) 52 + version=1 53 + ;; 54 + -i|--id) 55 + id=1 56 + ;; 57 + -d|--description) 58 + description=1 59 + ;; 60 + -r|--release) 61 + release=1 62 + ;; 63 + -c|--codename) 64 + codename=1 65 + ;; 66 + -a|--all) 67 + all=1 68 + ;; 69 + -s|--short) 70 + short=1 71 + ;; 72 + -h|--help) 73 + show_help 74 + ;; 75 + --) 76 + shift 77 + break 78 + ;; 79 + *) 80 + echo "lsb_release: unrecognized option '$1'" 81 + echo "Type 'lsb_release -h' for a list of available options." 82 + exit 1 83 + ;; 84 + esac 85 + shift 86 + done 87 + 88 + # Read our variables. 89 + if [[ -e /etc/os-release ]]; then 90 + . /etc/os-release 91 + OS_RELEASE_FOUND=1 92 + else 93 + # This is e.g. relevant for the Nix build sandbox and compatible with the 94 + # original lsb_release binary: 95 + OS_RELEASE_FOUND=0 96 + NAME="n/a" 97 + PRETTY_NAME="(none)" 98 + VERSION_ID="n/a" 99 + VERSION_CODENAME="n/a" 100 + fi 101 + 102 + # Default output 103 + if [[ "$version" = "0" ]] && [[ "$id" = "0" ]] && \ 104 + [[ "$description" = "0" ]] && [[ "$release" = "0" ]] && \ 105 + [[ "$codename" = "0" ]] && [[ "$all" = "0" ]]; then 106 + if [[ "$OS_RELEASE_FOUND" = "1" ]]; then 107 + echo "No LSB modules are available." >&2 108 + else 109 + if [[ "$short" = "0" ]]; then 110 + printf "LSB Version:\tn/a\n" 111 + else 112 + printf "n/a\n" 113 + fi 114 + fi 115 + exit 0 116 + fi 117 + 118 + # Now output the data - The order of these was chosen to match 119 + # what the original lsb_release used. 120 + 121 + SHORT_OUTPUT="" 122 + append_short_output() { 123 + if [[ "$1" = "n/a" ]]; then 124 + SHORT_OUTPUT+=" $1" 125 + else 126 + SHORT_OUTPUT+=" \"$1\"" 127 + fi 128 + } 129 + 130 + if [[ "$all" = "1" ]] || [[ "$version" = "1" ]]; then 131 + if [[ "$OS_RELEASE_FOUND" = "1" ]]; then 132 + if [[ "$short" = "0" ]]; then 133 + echo "No LSB modules are available." >&2 134 + else 135 + append_short_output "n/a" 136 + fi 137 + else 138 + if [[ "$short" = "0" ]]; then 139 + printf "LSB Version:\tn/a\n" 140 + else 141 + append_short_output "n/a" 142 + fi 143 + fi 144 + fi 145 + 146 + if [[ "$all" = "1" ]] || [[ "$id" = "1" ]]; then 147 + if [[ "$short" = "0" ]]; then 148 + printf "Distributor ID:\t$NAME\n" 149 + else 150 + append_short_output "$NAME" 151 + fi 152 + fi 153 + 154 + if [[ "$all" = "1" ]] || [[ "$description" = "1" ]]; then 155 + if [[ "$short" = "0" ]]; then 156 + printf "Description:\t$PRETTY_NAME\n" 157 + else 158 + append_short_output "$PRETTY_NAME" 159 + fi 160 + fi 161 + 162 + if [[ "$all" = "1" ]] || [[ "$release" = "1" ]]; then 163 + if [[ "$short" = "0" ]]; then 164 + printf "Release:\t$VERSION_ID\n" 165 + else 166 + append_short_output "$VERSION_ID" 167 + fi 168 + fi 169 + 170 + if [[ "$all" = "1" ]] || [[ "$codename" = "1" ]]; then 171 + if [[ "$short" = "0" ]]; then 172 + printf "Codename:\t$VERSION_CODENAME\n" 173 + else 174 + append_short_output "$VERSION_CODENAME" 175 + fi 176 + fi 177 + 178 + if [[ "$short" = "1" ]]; then 179 + # Output in one line without the first space: 180 + echo "${SHORT_OUTPUT:1}" 181 + fi 182 + 183 + # For compatibility with the original lsb_release: 184 + if [[ "$OS_RELEASE_FOUND" = "0" ]]; then 185 + if [[ "$all" = "1" ]] || [[ "$id" = "1" ]] || \ 186 + [[ "$description" = "1" ]] || [[ "$release" = "1" ]] || \ 187 + [[ "$codename" = "1" ]]; then 188 + exit 3 189 + fi 190 + fi