diff --git a/test/e2e_node/jenkins/e2e-node-jenkins.sh b/test/e2e_node/jenkins/e2e-node-jenkins.sh index 7e035f9dbb67..050c6a9d5539 100755 --- a/test/e2e_node/jenkins/e2e-node-jenkins.sh +++ b/test/e2e_node/jenkins/e2e-node-jenkins.sh @@ -41,9 +41,9 @@ TIMEOUT=${TIMEOUT:-"45m"} mkdir -p ${ARTIFACTS} -go run test/e2e_node/runner/remote/run_remote.go --logtostderr --vmodule=*=4 --ssh-env="gce" \ - --zone="$GCE_ZONE" --project="$GCE_PROJECT" --hosts="$GCE_HOSTS" \ - --images="$GCE_IMAGES" --image-project="$GCE_IMAGE_PROJECT" \ +go run test/e2e_node/runner/remote/run_remote.go --logtostderr --vmodule=*=4 \ + --ssh-env="gce" --ssh-user="$GCE_USER" --zone="$GCE_ZONE" --project="$GCE_PROJECT" \ + --hosts="$GCE_HOSTS" --images="$GCE_IMAGES" --image-project="$GCE_IMAGE_PROJECT" \ --image-config-file="$GCE_IMAGE_CONFIG_PATH" --cleanup="$CLEANUP" \ --results-dir="$ARTIFACTS" --ginkgo-flags="--nodes=$PARALLELISM $GINKGO_FLAGS" \ --test-timeout="$TIMEOUT" --setup-node="$SETUP_NODE" --test_args="$TEST_ARGS --kubelet-flags=\"$KUBELET_ARGS\"" \ diff --git a/test/e2e_node/jenkins/template.properties b/test/e2e_node/jenkins/template.properties index 5b9377eb4a41..2e9857aefa11 100644 --- a/test/e2e_node/jenkins/template.properties +++ b/test/e2e_node/jenkins/template.properties @@ -1,4 +1,6 @@ # Copy this file to your home directory and modify +# User used on the gce instances to run the test. +GCE_USER= # Path to a yaml or json file describing images to run or empty GCE_IMAGE_CONFIG_PATH= # Names of gce hosts to test against (must be resolvable) or empty diff --git a/test/e2e_node/remote/remote.go b/test/e2e_node/remote/remote.go index 3a1d07bd88fb..719a109f4aee 100644 --- a/test/e2e_node/remote/remote.go +++ b/test/e2e_node/remote/remote.go @@ -35,6 +35,7 @@ import ( var sshOptions = flag.String("ssh-options", "", "Commandline options passed to ssh.") var sshEnv = flag.String("ssh-env", "", "Use predefined ssh options for environment. Options: gce") +var sshUser = flag.String("ssh-user", "", "Use predefined user for ssh.") var testTimeoutSeconds = flag.Duration("test-timeout", 45*time.Minute, "How long (in golang duration format) to wait for ginkgo tests to complete.") var resultsDir = flag.String("results-dir", "/tmp/", "Directory to scp test results to.") @@ -69,13 +70,18 @@ func AddHostnameIp(hostname, ip string) { hostnameIpOverrides.m[hostname] = ip } +// GetHostnameOrIp converts hostname into ip and apply user if necessary. func GetHostnameOrIp(hostname string) string { hostnameIpOverrides.RLock() defer hostnameIpOverrides.RUnlock() + host := hostname if ip, found := hostnameIpOverrides.m[hostname]; found { - return ip + host = ip } - return hostname + if *sshUser != "" { + host = fmt.Sprintf("%s@%s", *sshUser, host) + } + return host } // CreateTestArchive builds the local source and creates a tar archive e2e_node_test.tar.gz containing @@ -237,7 +243,9 @@ func RunRemote(archive string, host string, cleanup bool, junitFilePrefix string fmt.Sprintf("tar -xzvf ./%s", archiveName), ) glog.Infof("Extracting tar on %s", host) - if output, err = SSH(host, "sh", "-c", cmd); err != nil { + // Do not use sudo here, because `sudo tar -x` will recover the file ownership inside the tar ball, but + // we want the extracted files to be owned by the current user. + if output, err := SSHNoSudo(host, "sh", "-c", cmd); err != nil { // Exit failure with the error return "", false, fmt.Errorf("failed to extract test archive: %v, output: %q", err, output) }