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