@@ -1,15 +1,20 @@
11{ lib
2+, callPackage
3+, nixosTests
24, stdenv
5+, fetchurl
36, autoPatchelfHook
7+, rpmextract
8+, openssl
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`)
415, buildEnv
5−, fetchurl
616, makeWrapper
7−, procps
8−, zlib
9−# optional packages that enable certain features
10−, acl ? null # EXT2/EXT3/XFS ACL support
11−, jdk8 ? null # Java GUI
12−, lvm2 ? null # LVM image backup and restore functions
17+, enableGui ? false # enables Java GUI `dsmj`
1318# path to `dsm.sys` configuration files
1419, dsmSysCli ? "/etc/tsm-client/cli.dsm.sys"
1520, dsmSysApi ? "/etc/tsm-client/api.dsm.sys"
@@ -18,7 +23,7 @@
1823
1924# For an explanation of optional packages
2025# (features provided by them, version limits), see
21−# https://www-01.ibm.com/support/docview.wss?uid=swg21052223#Version%208.1
26+# https://www.ibm.com/support/pages/node/660813#Version%208.1
2227
2328
2429# IBM Tivoli Storage Manager Client uses a system-wide
@@ -40,22 +45,33 @@
4045# point to this derivations `/dsmi_dir` directory symlink.
4146# Other environment variables might be necessary,
4247# depending on local configuration or usage; see:
43−# https://www.ibm.com/support/knowledgecenter/en/SSEQVQ_8.1.8/client/c_cfg_sapiunix.html
44−
45−
46−# The newest version of TSM client should be discoverable
47−# by going the the `downloadPage` (see `meta` below),
48−# there to "Client Latest Downloads",
49−# "IBM Spectrum Protect Client Downloads and READMEs",
50−# then to "Linux x86_64 Ubuntu client" (as of 2019-07-15).
48+# https://www.ibm.com/docs/en/spectrum-protect/8.1.13?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+# Here, two links must be checked:
56+# * "IBM Spectrum Protect Client ... Downloads and READMEs":
57+# In the table at the page's bottom,
58+# check the date of the "Linux x86_64 client"
59+# * "IBM Spectrum Protect BA client ... interim fix downloads"
60+# Look for the "Linux x86_64 client" rows
61+# in the table # at the bottom of each page.
62+# Follow the "HTTPS" link of the row with the latest date stamp.
63+# In the directory listing to show up, pick the big `.tar` file.
64+#
65+# (as of 2021-12-18)
5166
5267
5368let
5469
5570 meta = {
56− homepage = "https://www.ibm.com/us-en/marketplace/data-protection-and-recovery";
57− downloadPage = "https://www-01.ibm.com/support/docview.wss?uid=swg21239415";
71+ homepage = "https://www.ibm.com/products/data-protection-and-recovery";
72+ downloadPage = "https://www.ibm.com/support/pages/ibm-spectrum-protect-downloads-latest-fix-packs-and-interim-fixes";
5873 platforms = [ "x86_64-linux" ];
74+ mainProgram = "dsmc";
5975 license = lib.licenses.unfree;
6076 maintainers = [ lib.maintainers.yarny ];
6177 description = "IBM Spectrum Protect (Tivoli Storage Manager) CLI and API";
@@ -74,34 +90,53 @@ let
7490 '';
7591 };
7692
93+ passthru.tests = {
94+ test-cli = callPackage ./test-cli.nix {};
95+ test-gui = nixosTests.tsm-client-gui;
96+ };
97+
98+ mkSrcUrl = version:
99+ let
100+ major = lib.versions.major version;
101+ minor = lib.versions.minor version;
102+ patch = lib.versions.patch version;
103+ fixup = lib.lists.elemAt (lib.versions.splitVersion version) 3;
104+ in
105+ "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";
106+
77107 unwrapped = stdenv.mkDerivation rec {
78108 name = "tsm-client-${version}-unwrapped";
79− version = "8.1.8.0";
109+ version = "8.1.13.3";
80110 src = fetchurl {
81− url = "ftp://public.dhe.ibm.com/storage/tivoli-storage-management/maintenance/client/v8r1/Linux/LinuxX86_DEB/BA/v818/${version}-TIV-TSMBAC-LinuxX86_DEB.tar";
82− sha256 = "0c1d0jm0i7qjd314nhj2vj8fs7sncm1x2n4d6dg4049jniyvjhpk";
111+ url = mkSrcUrl version;
112+ sha256 = "1dwczf236drdaf4jcfzz5154vdwvxf5zraxhrhiddl6n80hnvbcd";
83113 };
84− inherit meta;
114+ inherit meta passthru;
85115
86116 nativeBuildInputs = [
87117 autoPatchelfHook
118+ rpmextract
88119 ];
89120 buildInputs = [
121+ openssl
90122 stdenv.cc.cc
91123 zlib
92124 ];
93125 runtimeDependencies = [
94− lvm2
126+ (lib.attrsets.getLib lvm2)
95127 ];
96128 sourceRoot = ".";
97129
98130 postUnpack = ''
99− for debfile in *.deb
100− do
101− ar -x "$debfile"
102− tar --xz --extract --file=data.tar.xz
103− rm data.tar.xz
104− done
131+ rpmextract TIVsm-API64.x86_64.rpm
132+ rpmextract TIVsm-APIcit.x86_64.rpm
133+ rpmextract TIVsm-BA.x86_64.rpm
134+ rpmextract TIVsm-BAcit.x86_64.rpm
135+ rpmextract TIVsm-BAhdw.x86_64.rpm
136+ rpmextract TIVsm-JBB.x86_64.rpm
137+ # use globbing so that version updates don't break the build:
138+ rpmextract gskcrypt64-*.linux.x86_64.rpm
139+ rpmextract gskssl64-*.linux.x86_64.rpm
105140 '';
106141
107142 installPhase = ''
@@ -113,7 +148,7 @@ let
113148
114149 # Fix relative symlinks after `/usr` was moved up one level
115150 preFixup = ''
116− for link in $out/lib/* $out/bin/*
151+ for link in $out/lib{,64}/* $out/bin/*
117152 do
118153 target=$(readlink "$link")
119154 if [ "$(cut -b -6 <<< "$target")" != "../../" ]
@@ -126,14 +161,19 @@ let
126161 '';
127162 };
128163
164+ binPath = lib.makeBinPath ([ acl gnugrep procps ]
165+ ++ lib.optional enableGui jdk8);
166+
129167in
130168
131169buildEnv {
132170 name = "tsm-client-${unwrapped.version}";
133− inherit meta;
134− passthru = { inherit unwrapped; };
171+ meta = meta // lib.attrsets.optionalAttrs enableGui {
172+ mainProgram = "dsmj";
173+ };
174+ passthru = passthru // { inherit unwrapped; };
135175 paths = [ unwrapped ];
136− buildInputs = [ makeWrapper ];
176+ nativeBuildInputs = [ makeWrapper ];
137177 pathsToLink = [
138178 "/"
139179 "/bin"
@@ -144,7 +184,7 @@ buildEnv {
144184 # to the so-called "installation directories"
145185 # * Add symlinks to the "installation directories"
146186 # that point to the `dsm.sys` configuration files
147− # * Drop the Java GUI executable unless `jdk` is present
187+ # * Drop the Java GUI executable unless `enableGui` is set
148188 # * Create wrappers for the command-line interface to
149189 # prepare `PATH` and `DSM_DIR` environment variables
150190 postBuild = ''
@@ -152,13 +192,13 @@ buildEnv {
152192 ln --symbolic --no-target-directory opt/tivoli/tsm/client/api/bin64 $out/dsmi_dir
153193 ln --symbolic --no-target-directory "${dsmSysCli}" $out/dsm_dir/dsm.sys
154194 ln --symbolic --no-target-directory "${dsmSysApi}" $out/dsmi_dir/dsm.sys
155− ${lib.optionalString (jdk8==null) "rm $out/bin/dsmj"}
195+ ${lib.optionalString (!enableGui) "rm $out/bin/dsmj"}
156196 for bin in $out/bin/*
157197 do
158198 target=$(readlink "$bin")
159199 rm "$bin"
160200 makeWrapper "$target" "$bin" \
161− --prefix PATH : "$out/dsm_dir:${lib.strings.makeBinPath [ procps acl jdk8 ]}" \
201+ --prefix PATH : "$out/dsm_dir:${binPath}" \
162202 --set DSM_DIR $out/dsm_dir
163203 done
164204 '';