summary refs log tree commit diff
path: root/pkgs/tools/virtualization/ovftool/default.nix
blob: c4b4acdbb48d3365d3a7ab4da8e778de0ac1d18e (plain) (blame)
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
{ lib, stdenv, system ? builtins.currentSystem, ovftoolBundles ? {}
, requireFile, buildFHSUserEnv, autoPatchelfHook, makeWrapper, unzip
, glibc, c-ares, libressl, 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
    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}
    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
    libressl
    c-ares
    (curl.override { openssl = libressl; })
    expat
    icu60
    xercesc
    zlib
  ];

  nativeBuildInputs = [ autoPatchelfHook makeWrapper unzip ];

  sourceRoot = ".";

  unpackPhase = ovftoolSystem.unpackPhase;

  postUnpackHash = ovftoolSystem.postUnpackHash;

  # 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 "${lib.getLib libressl}/lib/libcrypto.so" \
      "$out/lib/${pname}/libcrypto.so.1.0.2"
    ln -s "${lib.getLib libressl}/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"
  '';

  meta = with lib; {
    description = "VMWare tools for working with OVF, OVA, and VMX images";
    license = licenses.unfree;
    maintainers = with maintainers; [ numinit wolfangaukang ];
    platforms = builtins.attrNames ovftoolSystems;
  };
}