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}
}