func InstallGsutilIfNeeded()

in integration_test/gce-testing-internal/gce/gce_testing.go [1946:2031]


func InstallGsutilIfNeeded(ctx context.Context, logger *log.Logger, vm *VM) error {
	if IsWindows(vm.ImageSpec) {
		return nil
	}
	if _, err := RunRemotely(ctx, logger, vm, "sudo gsutil --version"); err == nil {
		// Success, no need to install gsutil.
		return nil
	}
	logger.Printf("gsutil not found, installing it...")

	// SUSE seems to be the only distro without gsutil, so what follows is all
	// very SUSE-specific.
	if !IsSUSEVM(vm) {
		return installErr("gsutil", vm.OS.ID)
	}

	gcloudArch := "x86_64"
	if IsARM(vm.ImageSpec) {
		gcloudArch = "arm"
	}
	gcloudPkg := "google-cloud-cli-453.0.0-linux-" + gcloudArch + ".tar.gz"
	installFromTarball := `
curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/` + gcloudPkg + `
INSTALL_DIR="$(readlink --canonicalize .)"
(
	INSTALL_LOG="$(mktemp)"
	# This command produces a lot of console spam, so we only display that
	# output if there is a problem.
	sudo tar -xf ` + gcloudPkg + ` -C ${INSTALL_DIR}
	sudo --preserve-env ${INSTALL_DIR}/google-cloud-sdk/install.sh -q &>"${INSTALL_LOG}" || \
		EXIT_CODE=$?
	if [[ "${EXIT_CODE-}" ]]; then
		cat "${INSTALL_LOG}"
		exit "${EXIT_CODE}"
	fi
)`
	installCmd := `set -ex
` + installFromTarball + `

# Upgrade to the latest version
sudo ${INSTALL_DIR}/google-cloud-sdk/bin/gcloud components update --quiet

sudo ln -s ${INSTALL_DIR}/google-cloud-sdk/bin/gsutil /usr/bin/gsutil
`
	// b/308962066: The GCloud CLI ARM Linux tarballs do not have bundled Python
	// and the GCloud CLI requires Python >= 3.8. Install Python311 for ARM VMs
	if IsARM(vm.ImageSpec) {
		// This is what's used on openSUSE.
		repoSetupCmd := "sudo zypper --non-interactive refresh"
		if strings.Contains(vm.ImageSpec, "sles-12") {
			return installErr("gsutil", vm.ImageSpec)
		}
		// For SLES 15 ARM: use a vendored repo to reduce flakiness of the
		// external repos. See http://go/sdi/releases/build-test-release/vendored
		// for details.
		if strings.Contains(vm.ImageSpec, "sles-15") {
			repoSetupCmd = `sudo zypper --non-interactive addrepo -g -t YUM https://us-yum.pkg.dev/projects/cloud-ops-agents-artifacts-dev/google-cloud-monitoring-sles15-aarch64-test-vendor test-vendor
sudo rpm --import https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
sudo zypper --non-interactive refresh test-vendor`
		}

		installCmd = `set -ex
` + repoSetupCmd + `
sudo zypper --non-interactive install python311 python3-certifi

# On SLES 15 and OpenSUSE Leap arm, python3 is Python 3.6. Tell gsutil/gcloud to use python3.11.
export CLOUDSDK_PYTHON=/usr/bin/python3.11

` + installFromTarball + `

# Upgrade to the latest version
sudo CLOUDSDK_PYTHON=/usr/bin/python3.11 ${INSTALL_DIR}/google-cloud-sdk/bin/gcloud components update --quiet

# Make a "gsutil" bash script in /usr/bin that runs the copy of gsutil that
# was installed into $INSTALL_DIR with CLOUDSDK_PYTHON set.
sudo tee /usr/bin/gsutil > /dev/null << EOF
#!/usr/bin/env bash
CLOUDSDK_PYTHON=/usr/bin/python3.11 ${INSTALL_DIR}/google-cloud-sdk/bin/gsutil "\$@"
EOF
sudo chmod a+x /usr/bin/gsutil
`
	}

	_, err := RunRemotely(ctx, logger, vm, installCmd)
	return err
}