at 23.11-beta 208 lines 7.1 kB view raw
1{ lib 2, callPackage 3, nixosTests 4, stdenv 5, fetchurl 6, autoPatchelfHook 7, rpmextract 8, libxcrypt-legacy 9, zlib 10, lvm2 # LVM image backup and restore functions (optional) 11, acl # EXT2/EXT3/XFS ACL support (optional) 12, gnugrep 13, procps 14, jdk8 # Java GUI (needed for `enableGui`) 15, buildEnv 16, makeWrapper 17, enableGui ? false # enables Java GUI `dsmj` 18# path to `dsm.sys` configuration files 19, dsmSysCli ? "/etc/tsm-client/cli.dsm.sys" 20, dsmSysApi ? "/etc/tsm-client/api.dsm.sys" 21}: 22 23 24# For an explanation of optional packages 25# (features provided by them, version limits), see 26# https://www.ibm.com/support/pages/node/660813#Version%208.1 27 28 29# IBM Tivoli Storage Manager Client uses a system-wide 30# client system-options file `dsm.sys` and expects it 31# to be located in a directory within the package. 32# Note that the command line client and the API use 33# different "dms.sys" files (located in different directories). 34# Since these files contain settings to be altered by the 35# admin user (e.g. TSM server name), we create symlinks 36# in place of the files that the client attempts to open. 37# Use the arguments `dsmSysCli` and `dsmSysApi` to 38# provide the location of the configuration files for 39# the command-line interface and the API, respectively. 40# 41# While the command-line interface contains wrappers 42# that help the executables find the configuration file, 43# packages that link against the API have to 44# set the environment variable `DSMI_DIR` to 45# point to this derivations `/dsmi_dir` directory symlink. 46# Other environment variables might be necessary, 47# depending on local configuration or usage; see: 48# https://www.ibm.com/docs/en/spectrum-protect/8.1.20?topic=solaris-set-api-environment-variables 49 50 51# The newest version of TSM client should be discoverable by 52# going to the `downloadPage` (see `meta` below). 53# Find the "Backup-archive client" table on that page. 54# Look for "Download Documents" of the latest release. 55# Follow the "Download Information" link. 56# Look for the "Linux x86_64 ..." rows in the table at 57# the bottom of the page and follow their "HTTPS" links (one 58# link per row -- each link might point to the latest release). 59# In the directory listings to show up, 60# check the big `.tar` file. 61# 62# (as of 2023-07-01) 63 64 65let 66 67 meta = { 68 homepage = "https://www.ibm.com/products/storage-protect"; 69 downloadPage = "https://www.ibm.com/support/pages/ibm-storage-protect-downloads-latest-fix-packs-and-interim-fixes"; 70 platforms = [ "x86_64-linux" ]; 71 mainProgram = "dsmc"; 72 sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; 73 license = lib.licenses.unfree; 74 maintainers = [ lib.maintainers.yarny ]; 75 description = "IBM Storage Protect (Tivoli Storage Manager) CLI and API"; 76 longDescription = '' 77 IBM Storage Protect (Tivoli Storage Manager) provides 78 a single point of control for backup and recovery. 79 This package contains the client software, that is, 80 a command line client and linkable libraries. 81 82 Note that the software requires a system-wide 83 client system-options file (commonly named "dsm.sys"). 84 This package allows to use separate files for 85 the command-line interface and for the linkable API. 86 The location of those files can 87 be provided as build parameters. 88 ''; 89 }; 90 91 passthru.tests = { 92 test-cli = callPackage ./test-cli.nix {}; 93 test-gui = nixosTests.tsm-client-gui; 94 }; 95 96 mkSrcUrl = version: 97 let 98 major = lib.versions.major version; 99 minor = lib.versions.minor version; 100 patch = lib.versions.patch version; 101 fixup = lib.lists.elemAt (lib.versions.splitVersion version) 3; 102 in 103 "https://public.dhe.ibm.com/storage/tivoli-storage-management/${if fixup=="0" then "maintenance" else "patches"}/client/v${major}r${minor}/Linux/LinuxX86/BA/v${major}${minor}${patch}/${version}-TIV-TSMBAC-LinuxX86.tar"; 104 105 unwrapped = stdenv.mkDerivation rec { 106 name = "tsm-client-${version}-unwrapped"; 107 version = "8.1.20.0"; 108 src = fetchurl { 109 url = mkSrcUrl version; 110 hash = "sha512-UZ5hRXGlB/1B4gZ8/i9OCHsxSuRkbAcp195zl/M75HtTi8o0rOfOh3LMmn4x4/M1V8d60ix7Tn4Mv8xkm7QXzw=="; 111 }; 112 inherit meta passthru; 113 114 nativeBuildInputs = [ 115 autoPatchelfHook 116 rpmextract 117 ]; 118 buildInputs = [ 119 libxcrypt-legacy 120 stdenv.cc.cc 121 zlib 122 ]; 123 runtimeDependencies = [ 124 (lib.attrsets.getLib lvm2) 125 ]; 126 sourceRoot = "."; 127 128 postUnpack = '' 129 rpmextract TIVsm-API64.x86_64.rpm 130 rpmextract TIVsm-APIcit.x86_64.rpm 131 rpmextract TIVsm-BA.x86_64.rpm 132 rpmextract TIVsm-BAcit.x86_64.rpm 133 rpmextract TIVsm-BAhdw.x86_64.rpm 134 rpmextract TIVsm-JBB.x86_64.rpm 135 # use globbing so that version updates don't break the build: 136 rpmextract gskcrypt64-*.linux.x86_64.rpm 137 rpmextract gskssl64-*.linux.x86_64.rpm 138 ''; 139 140 installPhase = '' 141 runHook preInstall 142 mkdir --parents $out 143 mv --target-directory=$out usr/* opt 144 runHook postInstall 145 ''; 146 147 # fix relative symlinks after `/usr` was moved up one level, 148 # fix absolute symlinks pointing to `/opt` 149 preFixup = '' 150 for link in $out/lib{,64}/* $out/bin/* 151 do 152 target=$(readlink "$link") 153 if [ "$(cut -b -6 <<< "$target")" != "../../" ] 154 then 155 echo "cannot fix this symlink: $link -> $target" 156 exit 1 157 fi 158 ln --symbolic --force --no-target-directory "$out/$(cut -b 7- <<< "$target")" "$link" 159 done 160 for link in $(find $out -type l -lname '/opt/*') 161 do 162 ln --symbolic --force --no-target-directory "$out$(readlink "$link")" "$link" 163 done 164 ''; 165 }; 166 167 binPath = lib.makeBinPath ([ acl gnugrep procps ] 168 ++ lib.optional enableGui jdk8); 169 170in 171 172buildEnv { 173 name = "tsm-client-${unwrapped.version}"; 174 meta = meta // lib.attrsets.optionalAttrs enableGui { 175 mainProgram = "dsmj"; 176 }; 177 passthru = passthru // { inherit unwrapped; }; 178 paths = [ unwrapped ]; 179 nativeBuildInputs = [ makeWrapper ]; 180 pathsToLink = [ 181 "/" 182 "/bin" 183 "/opt/tivoli/tsm/client/ba/bin" 184 "/opt/tivoli/tsm/client/api/bin64" 185 ]; 186 # * Provide top-level symlinks `dsm_dir` and `dsmi_dir` 187 # to the so-called "installation directories" 188 # * Add symlinks to the "installation directories" 189 # that point to the `dsm.sys` configuration files 190 # * Drop the Java GUI executable unless `enableGui` is set 191 # * Create wrappers for the command-line interface to 192 # prepare `PATH` and `DSM_DIR` environment variables 193 postBuild = '' 194 ln --symbolic --no-target-directory opt/tivoli/tsm/client/ba/bin $out/dsm_dir 195 ln --symbolic --no-target-directory opt/tivoli/tsm/client/api/bin64 $out/dsmi_dir 196 ln --symbolic --no-target-directory "${dsmSysCli}" $out/dsm_dir/dsm.sys 197 ln --symbolic --no-target-directory "${dsmSysApi}" $out/dsmi_dir/dsm.sys 198 ${lib.optionalString (!enableGui) "rm $out/bin/dsmj"} 199 for bin in $out/bin/* 200 do 201 target=$(readlink "$bin") 202 rm "$bin" 203 makeWrapper "$target" "$bin" \ 204 --prefix PATH : "$out/dsm_dir:${binPath}" \ 205 --set DSM_DIR $out/dsm_dir 206 done 207 ''; 208}