1# Make sure that the "with-gce" flag is set when building `google-cloud-sdk`
2# for GCE hosts. This flag prevents "google-compute-engine" from being a
3# default dependency which is undesirable because this package is
4#
5# 1) available only on GNU/Linux (requires `systemd` in particular)
6# 2) intended only for GCE guests (and is useless elsewhere)
7# 3) used by `google-cloud-sdk` only on GCE guests
8#
9
10{
11 stdenv,
12 lib,
13 fetchurl,
14 makeWrapper,
15 python3,
16 openssl,
17 jq,
18 callPackage,
19 installShellFiles,
20 with-gce ? false,
21}:
22
23let
24 # include a compatible pyopenssl version: https://github.com/NixOS/nixpkgs/issues/379291
25 # remove ASAP: https://github.com/googleapis/google-api-python-client/issues/2554
26 pythonCustom = python3.override {
27 self = pythonCustom;
28 packageOverrides = _: super: {
29 pyopenssl = super.pyopenssl.overridePythonAttrs (old: rec {
30 version = "24.2.1";
31 src = old.src.override {
32 tag = version;
33 hash = "sha256-/TQnDWdycN4hQ7ZGvBhMJEZVafmL+0wy9eJ8hC6rfio=";
34 };
35 # 36 failed tests
36 doCheck = false;
37 });
38 };
39 };
40
41 pythonEnv = pythonCustom.withPackages (
42 p:
43 with p;
44 [
45 cffi
46 cryptography
47 pyopenssl
48 crcmod
49 numpy
50 grpcio
51 ]
52 ++ lib.optional (with-gce) google-compute-engine
53 );
54
55 data = import ./data.nix { };
56 sources = system: data.googleCloudSdkPkgs.${system} or (throw "Unsupported system: ${system}");
57
58 components = callPackage ./components.nix {
59 snapshotPath = ./components.json;
60 };
61
62 withExtraComponents = callPackage ./withExtraComponents.nix { inherit components; };
63
64in
65stdenv.mkDerivation rec {
66 pname = "google-cloud-sdk";
67 inherit (data) version;
68
69 src = fetchurl (sources stdenv.hostPlatform.system);
70
71 buildInputs = [ python3 ];
72
73 nativeBuildInputs = [
74 jq
75 makeWrapper
76 installShellFiles
77 ];
78
79 patches = [
80 # For kubectl configs, don't store the absolute path of the `gcloud` binary as it can be garbage-collected
81 ./gcloud-path.patch
82 # Disable checking for updates for the package
83 ./gsutil-disable-updates.patch
84 ];
85
86 installPhase = ''
87 runHook preInstall
88
89 mkdir -p $out/google-cloud-sdk
90 if [ -d platform/bundledpythonunix ]; then
91 rm -r platform/bundledpythonunix
92 fi
93 cp -R * .install $out/google-cloud-sdk/
94
95 mkdir -p $out/google-cloud-sdk/lib/surface/{alpha,beta}
96 cp ${./alpha__init__.py} $out/google-cloud-sdk/lib/surface/alpha/__init__.py
97 cp ${./beta__init__.py} $out/google-cloud-sdk/lib/surface/beta/__init__.py
98
99 # create wrappers with correct env
100 for program in gcloud bq gsutil git-credential-gcloud.sh docker-credential-gcloud; do
101 programPath="$out/google-cloud-sdk/bin/$program"
102 binaryPath="$out/bin/$program"
103 wrapProgram "$programPath" \
104 --set CLOUDSDK_PYTHON "${pythonEnv}/bin/python" \
105 --set CLOUDSDK_PYTHON_ARGS "-S -W ignore" \
106 --prefix PYTHONPATH : "${pythonEnv}/${python3.sitePackages}" \
107 --prefix PATH : "${openssl.bin}/bin"
108
109 mkdir -p $out/bin
110 ln -s $programPath $binaryPath
111 done
112
113 # disable component updater and update check
114 substituteInPlace $out/google-cloud-sdk/lib/googlecloudsdk/core/config.json \
115 --replace-fail "\"disable_updater\": false" "\"disable_updater\": true"
116 echo "
117 [component_manager]
118 disable_update_check = true" >> $out/google-cloud-sdk/properties
119
120 # setup bash completion
121 mkdir -p $out/share/bash-completion/completions
122 mv $out/google-cloud-sdk/completion.bash.inc $out/share/bash-completion/completions/gcloud
123 ln -s $out/share/bash-completion/completions/gcloud $out/share/bash-completion/completions/gsutil
124
125 # setup zsh completion
126 mkdir -p $out/share/zsh/site-functions
127 mv $out/google-cloud-sdk/completion.zsh.inc $out/share/zsh/site-functions/_gcloud
128 ln -s $out/share/zsh/site-functions/_gcloud $out/share/zsh/site-functions/_gsutil
129 # zsh doesn't load completions from $FPATH without #compdef as the first line
130 sed -i '1 i #compdef gcloud' $out/share/zsh/site-functions/_gcloud
131
132 # setup fish completion
133 installShellCompletion --cmd gcloud \
134 --fish <(echo "complete -c gcloud -f -a '(__fish_argcomplete_complete gcloud)'")
135 installShellCompletion --cmd gsutil \
136 --fish <(echo "complete -c gsutil -f -a '(__fish_argcomplete_complete gsutil)'")
137
138 # This directory contains compiled mac binaries. We used crcmod from
139 # nixpkgs instead.
140 rm -r $out/google-cloud-sdk/platform/gsutil/third_party/crcmod \
141 $out/google-cloud-sdk/platform/gsutil/third_party/crcmod_osx
142
143 # remove tests and test data
144 find $out -name tests -type d -exec rm -rf '{}' +
145 rm $out/google-cloud-sdk/platform/gsutil/gslib/commands/test.py
146
147 # compact all the JSON
148 find $out -name \*.json | while read path; do
149 jq -c . $path > $path.min
150 mv $path.min $path
151 done
152
153 runHook postInstall
154 '';
155
156 doInstallCheck = true;
157 installCheckPhase = ''
158 # Avoid trying to write logs to homeless-shelter
159 export HOME=$(mktemp -d)
160 $out/bin/gcloud version --format json | jq '."Google Cloud SDK"' | grep "${version}"
161 $out/bin/gsutil version | grep -w "$(cat platform/gsutil/VERSION)"
162 '';
163
164 passthru = {
165 inherit components withExtraComponents;
166 updateScript = ./update.sh;
167 };
168
169 meta = with lib; {
170 description = "Tools for the google cloud platform";
171 longDescription = "The Google Cloud SDK for GCE hosts. Used by `google-cloud-sdk` only on GCE guests.";
172 sourceProvenance = with sourceTypes; [
173 fromSource
174 binaryNativeCode # anthoscli and possibly more
175 ];
176 # This package contains vendored dependencies. All have free licenses.
177 license = licenses.free;
178 homepage = "https://cloud.google.com/sdk/";
179 changelog = "https://cloud.google.com/sdk/docs/release-notes";
180 maintainers = with maintainers; [
181 iammrinal0
182 marcusramberg
183 pradyuman
184 stephenmw
185 zimbatm
186 ryan4yin
187 ];
188 platforms = builtins.attrNames data.googleCloudSdkPkgs;
189 mainProgram = "gcloud";
190 };
191}