1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
{ lib, stdenv, system ? builtins.currentSystem, ovftoolBundles ? {}
, requireFile, buildFHSUserEnv, patchelf, autoPatchelfHook, makeWrapper, nix, unzip
, glibc, c-ares, openssl_1_0_2, curl, expat, icu60, xercesc, zlib
}:
let
version = "4.4.1-16812187";
# FHS environment required to unpack ovftool on x86.
ovftoolX86Unpacker = buildFHSUserEnv rec {
name = "ovftool-unpacker";
targetPkgs = pkgs: [ pkgs.bash ];
multiPkgs = targetPkgs;
runScript = "bash";
};
# unpackPhase for i686 and x86_64 ovftool self-extracting bundles.
ovftoolX86UnpackPhase = ''
runHook preUnpack
# This is a self-extracting shell script and needs a FHS environment to run.
# In reality, it could be doing anything, which is bad for reproducibility.
# Our postUnpack uses nix-hash to verify the hash to prevent problems.
#
# Note that the Arch PKGBUILD at
# https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=vmware-ovftool
# appears to use xvfb-run - this hasn't been proven necessary so far.
#
cp ${ovftoolSource} ./ovftool.bundle
chmod +x ./ovftool.bundle
${ovftoolX86Unpacker}/bin/ovftool-unpacker ./ovftool.bundle -x ovftool
rm ovftool.bundle
local extracted=ovftool/vmware-ovftool/
if [ -d "$extracted" ]; then
# Move the directory we care about to ovftool/
mv "$extracted" .
rm -r ovftool
mv "$(basename -- "$extracted")" ovftool
echo "ovftool extracted successfully" >&2
else
echo "Could not find $extracted - are you sure this is ovftool?" >&2
rm -r ovftool
exit 1
fi
runHook postUnpack
'';
# unpackPhase for aarch64 .zip.
ovftoolAarch64UnpackPhase = ''
runHook preUnpack
unzip ${ovftoolSource}
local extracted=ovftool/
if [ -d "$extracted" ]; then
echo "ovftool extracted successfully" >&2
else
echo "Could not find $extracted - are you sure this is ovftool?" >&2
exit 1
fi
runHook postUnpack
'';
# When the version is bumped, postUnpackHash will change
# for all these supported systems. Update it from the printed error on build.
#
# This is just a sanity check, since ovftool is a self-extracting bundle
# that could be doing absolutely anything on 2/3 of the supported platforms.
ovftoolSystems = {
"i686-linux" = {
filename = "VMware-ovftool-${version}-lin.i386.bundle";
sha256 = "0gx78g3s77mmpir7jbiskna10i6262ihal1ywivlb6xxxxbhqzwj";
unpackPhase = ovftoolX86UnpackPhase;
postUnpackHash = "1k8rp8ywhs0cl9aad37v1p0493bdvkxrsvwg5pgv2bhvjs4hqk7n";
};
"x86_64-linux" = {
filename = "VMware-ovftool-${version}-lin.x86_64.bundle";
sha256 = "1kp2bp4d9i8y7q25yqff2bn62mh292lws7b66lyn8ka9b35kvnzc";
unpackPhase = ovftoolX86UnpackPhase;
postUnpackHash = "0zvyakwi4iishqxxisihgh91bmdsfvj5vchm2c192hia03a143py";
};
"aarch64-linux" = {
filename = "VMware-ovftool-${version}-lin.aarch64.zip";
sha256 = "0all8bwv5p5adnzqvrly6nzmxmfpywvlbfr0finr4n100yv0v1xy";
unpackPhase = ovftoolAarch64UnpackPhase;
postUnpackHash = "16vyyzrmryi8b7mrd6nxnhywvvj2pw0ban4qfiqfahw763fn6971";
};
};
ovftoolSystem = if builtins.hasAttr system ovftoolSystems then
ovftoolSystems.${system}
else throw "System '${system}' is unsupported by ovftool";
ovftoolSource = if builtins.hasAttr system ovftoolBundles then
ovftoolBundles.${system}
else
requireFile {
name = ovftoolSystem.filename;
url = "https://my.vmware.com/group/vmware/downloads/get-download?downloadGroup=OVFTOOL441";
sha256 = ovftoolSystem.sha256;
};
in
stdenv.mkDerivation rec {
pname = "ovftool";
inherit version;
src = ovftoolSource;
buildInputs = [
glibc
# This is insecure, but we don't really have a way around it
# since ovftool depends on it. In theory we could ship their OpenSSL
# build... but that makes the reliance on an insecure library less obvious.
openssl_1_0_2
c-ares
(curl.override { openssl = openssl_1_0_2; })
expat
icu60
xercesc
zlib
];
nativeBuildInputs = [ nix patchelf autoPatchelfHook makeWrapper unzip ];
sourceRoot = ".";
unpackPhase = ovftoolSystem.unpackPhase;
postUnpackHash = ovftoolSystem.postUnpackHash;
# Expects a directory named 'ovftool'. Validates the postUnpackHash in
# ovftoolSystem.
postUnpack = ''
if [ -d ovftool ]; then
# Ensure we're in the staging directory
cd ovftool
fi
# Verify the hash with nix-hash before proceeding to ensure reproducibility.
local ovftool_hash
ovftool_hash="$(nix-hash --type sha256 --base32 .)"
if [ "$ovftool_hash" != "$postUnpackHash" ]; then
echo "Expected hash: $postUnpackHash" >&2
echo "Actual hash: $ovftool_hash" >&2
echo "Could not verify post-unpack hash!" >&2
exit 1
fi
'';
# Expects a directory named 'ovftool' containing the ovftool install.
# Based on https://aur.archlinux.org/packages/vmware-ovftool/
# with the addition of a libexec directory and a Nix-style binary wrapper.
installPhase = ''
runHook preInstall
if [ -d ovftool ]; then
# Ensure we're in the staging directory
cd ovftool
fi
# libraries
install -m 755 -d "$out/lib/$pname"
# These all appear to be VMWare proprietary except for libgoogleurl.
# The rest of the libraries that the installer extracts are omitted here,
# and provided in buildInputs.
#
# FIXME: can we replace libgoogleurl? Possibly from Chromium?
#
install -m 644 -t "$out/lib/$pname" \
libgoogleurl.so.59 \
libssoclient.so \
libvim-types.so libvmacore.so libvmomi.so
# ovftool specifically wants 1.0.2 but our libcrypto is named 1.0.0
ln -s "${openssl_1_0_2.out}/lib/libcrypto.so" \
"$out/lib/$pname/libcrypto.so.1.0.2"
ln -s "${openssl_1_0_2.out}/lib/libssl.so" \
"$out/lib/$pname/libssl.so.1.0.2"
# libexec
install -m 755 -d "$out/libexec/$pname"
install -m 755 -t "$out/libexec/$pname" ovftool.bin
install -m 644 -t "$out/libexec/$pname" icudt44l.dat
# libexec resources
for subdir in "certs" "env" "env/en" "schemas/DMTF" "schemas/vmware"; do
install -m 755 -d "$out/libexec/$pname/$subdir"
install -m 644 -t "$out/libexec/$pname/$subdir" "$subdir"/*.*
done
# EULA/OSS files
install -m 755 -d "$out/share/licenses/$pname"
install -m 644 -t "$out/share/licenses/$pname" \
"vmware.eula" "vmware-eula.rtf" "open_source_licenses.txt"
# documentation files
install -m 755 -d "$out/share/doc/$pname"
install -m 644 -t "$out/share/doc/$pname" "README.txt"
# binary wrapper; note that LC_CTYPE is defaulted to en_US.UTF-8 by
# VMWare's wrapper script. We use C.UTF-8 instead.
install -m 755 -d "$out/bin"
makeWrapper "$out/libexec/$pname/ovftool.bin" "$out/bin/ovftool" \
--set-default LC_CTYPE C.UTF-8 \
--prefix LD_LIBRARY_PATH : "$out/lib"
runHook postInstall
'';
preFixup = ''
addAutoPatchelfSearchPath "$out/lib"
'';
dontBuild = true;
dontPatch = true;
dontConfigure = true;
meta = with lib; {
description = "VMWare tools for working with OVF, OVA, and VMX images";
license = licenses.unfree;
maintainers = with maintainers; [ numinit ];
platforms = builtins.attrNames ovftoolSystems;
};
}
|