func linuxCopy()

in pkg/testing/linux/linux.go [54:157]


func linuxCopy(ctx context.Context, sshClient ssh.SSHClient, logger common.Logger, repoArchive string, builds []common.Build) error {
	// copy the archive and extract it on the host
	logger.Logf("Copying repo")
	destRepoName := filepath.Base(repoArchive)
	err := sshClient.Copy(repoArchive, destRepoName)
	if err != nil {
		return fmt.Errorf("failed to SCP repo archive %s: %w", repoArchive, err)
	}

	// remove build paths, on cases where the build path is different from agent.
	for _, build := range builds {
		for _, remoteBuildPath := range []string{build.Path, build.SHA512Path} {
			relativeAgentDir := filepath.Join("agent", remoteBuildPath)
			_, _, err := sshClient.Exec(ctx, "sudo", []string{"rm", "-rf", relativeAgentDir}, nil)
			// doesn't need to be a fatal error.
			if err != nil {
				logger.Logf("error removing build dir %s: %w", relativeAgentDir, err)
			}
		}
	}

	// ensure that agent directory is removed (possible it already exists if instance already used)
	stdout, stderr, err := sshClient.Exec(ctx,
		"sudo", []string{"rm", "-rf", "agent"}, nil)
	if err != nil {
		return fmt.Errorf(
			"failed to remove agent directory before unziping new one: %w. stdout: %q, stderr: %q",
			err, stdout, stderr)
	}

	stdOut, errOut, err := sshClient.Exec(ctx, "unzip", []string{destRepoName, "-d", "agent"}, nil)
	if err != nil {
		return fmt.Errorf("failed to unzip %s to agent directory: %w (stdout: %s, stderr: %s)", destRepoName, err, stdOut, errOut)
	}

	// prepare for testing
	logger.Logf("Running make mage and prepareOnRemote")
	envs := `GOPATH="$HOME/go" PATH="$HOME/go/bin:$PATH"`
	installMage := strings.NewReader(fmt.Sprintf(`cd agent && %s make mage && %s mage integration:prepareOnRemote`, envs, envs))
	stdOut, errOut, err = sshClient.Exec(ctx, "bash", nil, installMage)
	if err != nil {
		return fmt.Errorf("failed to perform make mage and prepareOnRemote: %w (stdout: %s, stderr: %s)", err, stdOut, errOut)
	}

	// determine if the build needs to be replaced on the host
	// if it already exists and the SHA512 are the same contents, then
	// there is no reason to waste time uploading the build
	for _, build := range builds {
		copyBuild := true
		localSHA512, err := os.ReadFile(build.SHA512Path)
		if err != nil {
			return fmt.Errorf("failed to read local SHA52 contents %s: %w", build.SHA512Path, err)
		}
		hostSHA512Path := filepath.Base(build.SHA512Path)
		hostSHA512, err := sshClient.GetFileContents(ctx, hostSHA512Path)
		if err == nil {
			if string(localSHA512) == string(hostSHA512) {
				logger.Logf("Skipping copy agent build %s; already the same", filepath.Base(build.Path))
				copyBuild = false
			}
		}

		if copyBuild {
			// ensure the existing copies are removed first
			toRemove := filepath.Base(build.Path)
			stdOut, errOut, err = sshClient.Exec(ctx,
				"sudo", []string{"rm", "-f", toRemove}, nil)
			if err != nil {
				return fmt.Errorf("failed to remove %q: %w (stdout: %q, stderr: %q)",
					toRemove, err, stdOut, errOut)
			}

			toRemove = filepath.Base(build.SHA512Path)
			stdOut, errOut, err = sshClient.Exec(ctx,
				"sudo", []string{"rm", "-f", toRemove}, nil)
			if err != nil {
				return fmt.Errorf("failed to remove %q: %w (stdout: %q, stderr: %q)",
					toRemove, err, stdOut, errOut)
			}

			logger.Logf("Copying agent build %s", filepath.Base(build.Path))
		}

		for _, buildPath := range []string{build.Path, build.SHA512Path} {
			if copyBuild {
				err = sshClient.Copy(buildPath, filepath.Base(buildPath))
				if err != nil {
					return fmt.Errorf("failed to SCP build %s: %w", filepath.Base(buildPath), err)
				}
			}
			insideAgentDir := filepath.Join("agent", buildPath)
			stdOut, errOut, err = sshClient.Exec(ctx, "mkdir", []string{"-p", filepath.Dir(insideAgentDir)}, nil)
			if err != nil {
				return fmt.Errorf("failed to create %s directory: %w (stdout: %s, stderr: %s)", filepath.Dir(insideAgentDir), err, stdOut, errOut)
			}
			stdOut, errOut, err = sshClient.Exec(ctx, "ln", []string{filepath.Base(buildPath), insideAgentDir}, nil)
			if err != nil {
				return fmt.Errorf("failed to hard link %s to %s: %w (stdout: %s, stderr: %s)", filepath.Base(buildPath), insideAgentDir, err, stdOut, errOut)
			}
		}
	}

	return nil
}