3
0
Fork 0
forked from mirrors/nixpkgs

Merge pull request #187793 from xlambein/master

google-cloud-sdk: add support for components
This commit is contained in:
Bernardo Meurer 2022-08-25 10:26:59 -03:00 committed by GitHub
commit 9d201c111f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 7159 additions and 2 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,173 @@
{ stdenv
, lib
, google-cloud-sdk
, system
, snapshotPath
, ...
}:
let
# Mapping from GCS component architecture names to Nix archictecture names
arches = {
x86 = "i686";
x86_64 = "x86_64";
# TODO arm
};
# Mapping from GCS component operating systems to Nix operating systems
oses = {
LINUX = "linux";
MACOSX = "darwin";
WINDOWS = "windows";
CYGWIN = "cygwin";
};
# Convert an archicecture + OS to a Nix platform
toNixPlatform = arch: os:
let
arch' = arches.${arch} or (throw "unsupported architecture '${arch}'");
os' = oses.${os} or (throw "unsupported OS '${os}'");
in
"${arch'}-${os'}";
# All architectures that are supported
allArches = builtins.attrValues arches;
# A description of all available google-cloud-sdk components.
# It's a JSON file with a list of components, along with some metadata
snapshot = builtins.fromJSON (builtins.readFile snapshotPath);
# Generate a snapshot file for a single component. It has the same format as
# `snapshot`, but only contains a single component. These files are
# installed with google-cloud-sdk to let it know which components are
# available.
snapshotFromComponent =
{ component
, revision
, schema_version
, version
}:
builtins.toJSON {
components = [ component ];
inherit revision schema_version version;
};
# Generate a set of components from a JSON file describing these components
componentsFromSnapshot =
{ components
, revision
, schema_version
, version
, ...
}:
lib.fix (
self:
builtins.listToAttrs (
builtins.map
(component: {
name = component.id;
value = componentFromSnapshot self { inherit component revision schema_version version; };
})
components
)
);
# Generate a single component from its snapshot, along with a set of
# available dependencies to choose from.
componentFromSnapshot =
# Component derivations that can be used as dependencies
components:
# This component's snapshot
{ component
, revision
, schema_version
, version
} @ attrs:
let
baseUrl = builtins.dirOf schema_version.url;
# Architectures supported by this component. Defaults to all available
# architectures.
architectures = builtins.filter
(arch: builtins.elem arch (builtins.attrNames arches))
(lib.attrByPath [ "platform" "architectures" ] allArches component);
# Operating systems supported by this component
operating_systems = builtins.filter
(os: builtins.elem os (builtins.attrNames oses))
component.platform.operating_systems;
in
mkComponent
{
name = component.id;
version = component.version.version_string;
src =
if lib.hasAttrByPath [ "data" "source" ] component
then "${baseUrl}/${component.data.source}"
else "";
sha256 = lib.attrByPath [ "data" "checksum" ] "" component;
dependencies = builtins.map (dep: builtins.getAttr dep components) component.dependencies;
platforms =
if component.platform == { }
then lib.platforms.all
else
builtins.concatMap
(arch: builtins.map (os: toNixPlatform arch os) operating_systems)
architectures;
snapshot = snapshotFromComponent attrs;
};
# Filter out dependencies not supported by current system
filterForSystem = builtins.filter (drv: builtins.elem system drv.meta.platforms);
# Make a google-cloud-sdk component
mkComponent =
{ name
, version
# Source tarball, if any
, src ? ""
# Checksum for the source tarball, if there is a source
, sha256 ? ""
# Other components this one depends on
, dependencies ? [ ]
# Short text describing the component
, description ? ""
# Platforms supported
, platforms ? lib.platforms.all
# The snapshot corresponding to this component
, snapshot
}: stdenv.mkDerivation {
inherit name version snapshot;
src =
if src != "" then
builtins.fetchurl
{
url = src;
inherit sha256;
} else "";
phases = [ "installPhase" "fixupPhase" ];
installPhase = ''
mkdir -p $out/google-cloud-sdk/.install
# If there is a source, unpack it
if [ ! -z "$src" ]; then
tar -xf $src -C $out/google-cloud-sdk/
# If the source has binaries, link them to `$out/bin`
if [ -d "$out/google-cloud-sdk/bin" ]; then
mkdir $out/bin
find $out/google-cloud-sdk/bin/ -type f -exec ln -s {} $out/bin/ \;
fi
fi
# Write the snapshot file to the `.install` folder
cp $snapshotPath $out/google-cloud-sdk/.install/${name}.snapshot.json
'';
passthru = {
dependencies = filterForSystem dependencies;
};
passAsFile = [ "snapshot" ];
meta = {
inherit description platforms;
};
};
in
componentsFromSnapshot snapshot

View file

@ -7,7 +7,7 @@
# 3) used by `google-cloud-sdk` only on GCE guests
#
{ stdenv, lib, fetchurl, makeWrapper, nixosTests, python, openssl, jq, with-gce ? false }:
{ stdenv, lib, fetchurl, makeWrapper, nixosTests, python, openssl, jq, callPackage, with-gce ? false }:
let
pythonEnv = python.withPackages (p: with p; [
@ -21,6 +21,12 @@ let
sources = system:
data.googleCloudSdkPkgs.${system} or (throw "Unsupported system: ${system}");
components = callPackage ./components.nix {
snapshotPath = ./components.json;
};
withExtraComponents = callPackage ./withExtraComponents.nix { inherit components; };
in stdenv.mkDerivation rec {
pname = "google-cloud-sdk";
inherit (data) version;
@ -105,6 +111,10 @@ in stdenv.mkDerivation rec {
$out/bin/gcloud version --format json | jq '."Google Cloud SDK"' | grep "${version}"
'';
passthru = {
inherit components withExtraComponents;
};
meta = with lib; {
description = "Tools for the google cloud platform";
longDescription = "The Google Cloud SDK. This package has the programs: gcloud, gsutil, and bq";

View file

@ -1,7 +1,8 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p nix
BASE_URL="https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk"
CHANNEL_URL="https://dl.google.com/dl/cloudsdk/channels/rapid"
BASE_URL="$CHANNEL_URL/downloads/google-cloud-sdk"
# Version of Google Cloud SDK from
# https://cloud.google.com/sdk/docs/release-notes
@ -45,3 +46,5 @@ EOF
echo "}"
} >data.nix
curl "${CHANNEL_URL}/components-v${VERSION}.json" > components.json

View file

@ -0,0 +1,61 @@
{ lib, google-cloud-sdk, callPackage, runCommand, components }:
comps_:
let
# Remove components which are already installed by default
filterPreInstalled =
let
preInstalledComponents = with components; [ bq bq-nix core core-nix gcloud-deps gcloud gsutil gsutil-nix ];
in
builtins.filter (drv: !(builtins.elem drv preInstalledComponents));
# Recursively build a list of components with their dependencies
# TODO this could be made faster, it checks the dependencies too many times
findDepsRecursive = lib.converge
(drvs: lib.unique (drvs ++ (builtins.concatMap (drv: drv.dependencies) drvs)));
# Components to install by default
defaultComponents = with components; [ alpha beta ];
comps = [ google-cloud-sdk ] ++ filterPreInstalled (findDepsRecursive (defaultComponents ++ comps_));
in
# Components are installed by copying the `google-cloud-sdk` package, along
# with each component, over to a new location, and then patching that location
# with `sed` to ensure the proper paths are used.
# For some reason, this does not work properly with a `symlinkJoin`: the
# `gcloud` binary doesn't seem able to find the installed components.
runCommand "google-cloud-sdk-${google-cloud-sdk.version}"
{
inherit (google-cloud-sdk) meta;
inherit comps;
passAsFile = [ "comps" ];
doInstallCheck = true;
installCheckPhase =
let
compNames = builtins.map (drv: drv.name) comps_;
in
''
$out/bin/gcloud components list > component_list.txt
for comp in ${builtins.toString compNames}; do
if [ ! grep ... component_list.txt | grep "Not Installed" ]; then
echo "Failed to install component '$comp'"
exit 1
fi
done
'';
}
''
mkdir -p $out
# Install each component
for comp in $(cat $compsPath); do
echo "installing component $comp"
cp -dRf $comp/. $out
find $out -type d -exec chmod 744 {} +
done
# Replace references to the original google-cloud-sdk with this one
find $out/google-cloud-sdk/bin/ -type f -exec sed -i -e "s#${google-cloud-sdk}#$out#" {} \;
''