func collectRemoteGcloud()

in internal/workloadmanager/remote.go [230:319]


func collectRemoteGcloud(ctx context.Context, a any) {
	var opts collectOptions
	var ok bool
	if opts, ok = a.(collectOptions); !ok {
		log.CtxLogger(ctx).Errorw("Cannot collect remote metrics using gcloud", "reason", fmt.Sprintf("args of type %T does not match collectOptions", a))
		return
	}

	var metrics []*mrpb.TimeSeries
	if !opts.exists("gcloud") {
		log.CtxLogger(ctx).Error("gcloud command not found. Ensure the google cloud SDK is installed and that the gcloud command is in systemd's PATH environment variable: `systemctl show-environment`, `systemctl set-environment PATH=</path:/another/path>")
		opts.wm <- WorkloadMetrics{Metrics: metrics}
		return
	}

	log.CtxLogger(ctx).Infow("Collecting remote metrics using gcloud", "instance", opts.i)
	iName := gcloudInstanceName(opts.rc, opts.i)
	// remove the binary just in case it still exists on the remote
	sshArgs := []string{"compute", "ssh"}
	sshArgs = appendCommonGcloudArgs(sshArgs, opts.rc, opts.i)
	sshArgs = append(sshArgs, iName, "--command", "sudo rm -f "+remoteAgentBinary)
	result := opts.execute(ctx, commandlineexecutor.Params{
		Executable: "gcloud",
		Args:       sshArgs,
	})
	if result.Error != nil {
		log.CtxLogger(ctx).Errorw("Could not ssh to remote instance to remove existing tmp binary", "instance", opts.i, "error", result.Error, "stderr", result.StdErr, "stdout", result.StdOut)
	}

	// gcloud compute scp --project someproject --zone somezone [--tunnel-through-iap] [--internal-ip] [otherargs] filetotransfer [user@]instancename:path
	scpArgs := []string{"compute", "scp"}
	scpArgs = appendCommonGcloudArgs(scpArgs, opts.rc, opts.i)
	scpArgs = append(scpArgs, opts.configPath, fmt.Sprintf("%s:%s", iName, remoteValidationConfig))
	log.CtxLogger(ctx).Debugw("Sending workload validation config to remote host", "instance", opts.i)
	result = opts.execute(ctx, commandlineexecutor.Params{
		Executable: "gcloud",
		Args:       scpArgs,
	})
	if result.Error != nil {
		log.CtxLogger(ctx).Errorw("Could not copy workload validation config to remote instance", "instance", opts.i, "error", result.Error, "stderr", result.StdErr, "stdout", result.StdOut)
		opts.wm <- WorkloadMetrics{Metrics: metrics}
		return
	}

	// gcloud compute scp --project someproject --zone somezone [--tunnel-through-iap] [--internal-ip] [otherargs] filetotransfer [user@]instancename:path
	scpArgs = []string{"compute", "scp"}
	scpArgs = appendCommonGcloudArgs(scpArgs, opts.rc, opts.i)
	scpArgs = append(scpArgs, agentBinary, fmt.Sprintf("%s:%s", iName, remoteAgentBinary))
	log.CtxLogger(ctx).Debugw("Sending binary to remote host", "instance", opts.i)
	result = opts.execute(ctx, commandlineexecutor.Params{
		Executable: "gcloud",
		Args:       scpArgs,
	})
	if result.Error != nil {
		log.CtxLogger(ctx).Errorw("Could not copy binary to remote instance", "instance", opts.i, "error", result.Error, "stderr", result.StdErr, "stdout", result.StdOut)
		opts.wm <- WorkloadMetrics{Metrics: metrics}
		return
	}

	// gcloud compute ssh ---project someproject --zone somezone [--tunnel-through-iap] [--internal-ip] [otherargs] [user@]instancename --command="commandtoexec"
	command := "sudo " + remoteAgentBinary + fmt.Sprintf(" remote -c=%s -p=%s -z=%s -i=%s -n=%s", remoteValidationConfig, opts.i.GetProjectId(), opts.i.GetZone(), opts.i.GetInstanceId(), opts.i.GetInstanceName()) + "; rm " + remoteAgentBinary + "; rm " + remoteValidationConfig
	sshArgs = []string{"compute", "ssh"}
	sshArgs = appendCommonGcloudArgs(sshArgs, opts.rc, opts.i)
	sshArgs = append(sshArgs, iName, "--command", command)
	result = opts.execute(ctx, commandlineexecutor.Params{
		Executable: "gcloud",
		Args:       sshArgs,
	})
	if result.Error != nil {
		log.CtxLogger(ctx).Errorw("Could not execute remote collection on instance", "instance", opts.i, "error", result.Error, "stderr", result.StdErr, "stdout", result.StdOut)
		opts.wm <- WorkloadMetrics{Metrics: metrics}
		return
	}
	if strings.HasPrefix(result.StdOut, "ERROR") {
		log.CtxLogger(ctx).Errorw("Error encountered on remote instance", "instance", opts.i, "error", result.StdOut)
		opts.wm <- WorkloadMetrics{Metrics: metrics}
		return
	}

	err := parseRemoteJSON(result.StdOut, &metrics)
	if err != nil {
		log.CtxLogger(ctx).Errorw("Error parsing metrics collected from remote instance", "instance", opts.i, "error", err)
	}

	if len(metrics) == 0 {
		log.CtxLogger(ctx).Warnw("No data collected from remote instance", "instance", opts.i)
	}

	opts.wm <- WorkloadMetrics{Metrics: metrics}
}