mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 10:53:34 +00:00
vendor files
This commit is contained in:
37
vendor/k8s.io/kubernetes/test/e2e_node/remote/BUILD
generated
vendored
Normal file
37
vendor/k8s.io/kubernetes/test/e2e_node/remote/BUILD
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"node_conformance.go",
|
||||
"node_e2e.go",
|
||||
"remote.go",
|
||||
"ssh.go",
|
||||
"types.go",
|
||||
"utils.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/test/e2e_node/remote",
|
||||
deps = [
|
||||
"//test/e2e_node/builder:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
303
vendor/k8s.io/kubernetes/test/e2e_node/remote/node_conformance.go
generated
vendored
Normal file
303
vendor/k8s.io/kubernetes/test/e2e_node/remote/node_conformance.go
generated
vendored
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package remote
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/test/e2e_node/builder"
|
||||
)
|
||||
|
||||
// ConformanceRemote contains the specific functions in the node conformance test suite.
|
||||
type ConformanceRemote struct{}
|
||||
|
||||
func InitConformanceRemote() TestSuite {
|
||||
return &ConformanceRemote{}
|
||||
}
|
||||
|
||||
// getConformanceDirectory gets node conformance test build directory.
|
||||
func getConformanceDirectory() (string, error) {
|
||||
k8sRoot, err := builder.GetK8sRootDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(k8sRoot, "test", "e2e_node", "conformance", "build"), nil
|
||||
}
|
||||
|
||||
// commandToString is a helper function which formats command to string.
|
||||
func commandToString(c *exec.Cmd) string {
|
||||
return strings.Join(append([]string{c.Path}, c.Args[1:]...), " ")
|
||||
}
|
||||
|
||||
// Image path constants.
|
||||
const (
|
||||
conformanceRegistry = "gcr.io/google_containers"
|
||||
conformanceArch = runtime.GOARCH
|
||||
conformanceTarfile = "node_conformance.tar"
|
||||
conformanceTestBinary = "e2e_node.test"
|
||||
conformanceImageLoadTimeout = time.Duration(30) * time.Second
|
||||
)
|
||||
|
||||
// timestamp is used as an unique id of current test.
|
||||
var timestamp = getTimestamp()
|
||||
|
||||
// getConformanceTestImageName returns name of the conformance test image given the system spec name.
|
||||
func getConformanceTestImageName(systemSpecName string) string {
|
||||
if systemSpecName == "" {
|
||||
return fmt.Sprintf("%s/node-test-%s:%s", conformanceRegistry, conformanceArch, timestamp)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/node-test-%s-%s:%s", conformanceRegistry, systemSpecName, conformanceArch, timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
// buildConformanceTest builds node conformance test image tarball into binDir.
|
||||
func buildConformanceTest(binDir, systemSpecName string) error {
|
||||
// Get node conformance directory.
|
||||
conformancePath, err := getConformanceDirectory()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get node conformance directory: %v", err)
|
||||
}
|
||||
// Build docker image.
|
||||
cmd := exec.Command("make", "-C", conformancePath, "BIN_DIR="+binDir,
|
||||
"REGISTRY="+conformanceRegistry,
|
||||
"ARCH="+conformanceArch,
|
||||
"VERSION="+timestamp,
|
||||
"SYSTEM_SPEC_NAME="+systemSpecName)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to build node conformance docker image: command - %q, error - %v, output - %q",
|
||||
commandToString(cmd), err, output)
|
||||
}
|
||||
// Save docker image into tar file.
|
||||
cmd = exec.Command("docker", "save", "-o", filepath.Join(binDir, conformanceTarfile), getConformanceTestImageName(systemSpecName))
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to save node conformance docker image into tar file: command - %q, error - %v, output - %q",
|
||||
commandToString(cmd), err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupTestPackage sets up the test package with binaries k8s required for node conformance test
|
||||
func (c *ConformanceRemote) SetupTestPackage(tardir, systemSpecName string) error {
|
||||
// Build the executables
|
||||
if err := builder.BuildGo(); err != nil {
|
||||
return fmt.Errorf("failed to build the depedencies: %v", err)
|
||||
}
|
||||
|
||||
// Make sure we can find the newly built binaries
|
||||
buildOutputDir, err := builder.GetK8sBuildOutputDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to locate kubernetes build output directory %v", err)
|
||||
}
|
||||
|
||||
// Build node conformance tarball.
|
||||
if err := buildConformanceTest(buildOutputDir, systemSpecName); err != nil {
|
||||
return fmt.Errorf("failed to build node conformance test: %v", err)
|
||||
}
|
||||
|
||||
// Copy files
|
||||
requiredFiles := []string{"kubelet", conformanceTestBinary, conformanceTarfile}
|
||||
for _, file := range requiredFiles {
|
||||
source := filepath.Join(buildOutputDir, file)
|
||||
if _, err := os.Stat(source); err != nil {
|
||||
return fmt.Errorf("failed to locate test file %s: %v", file, err)
|
||||
}
|
||||
output, err := exec.Command("cp", source, filepath.Join(tardir, file)).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy %q: error - %v output - %q", file, err, output)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadConformanceImage loads node conformance image from tar file.
|
||||
func loadConformanceImage(host, workspace string) error {
|
||||
tarfile := filepath.Join(workspace, conformanceTarfile)
|
||||
if output, err := SSH(host, "timeout", conformanceImageLoadTimeout.String(),
|
||||
"docker", "load", "-i", tarfile); err != nil {
|
||||
return fmt.Errorf("failed to load node conformance image from tar file %q: error - %v output - %q",
|
||||
tarfile, err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// kubeletLauncherLog is the log of kubelet launcher.
|
||||
const kubeletLauncherLog = "kubelet-launcher.log"
|
||||
|
||||
// kubeletPodManifestPath is a fixed known pod manifest path. We can not use the random pod
|
||||
// manifest directory generated in e2e_node.test because we need to mount the directory into
|
||||
// the conformance test container, it's easier if it's a known directory.
|
||||
// TODO(random-liu): Get rid of this once we switch to cluster e2e node bootstrap script.
|
||||
var kubeletPodManifestPath = "conformance-pod-manifest-" + timestamp
|
||||
|
||||
// getPodManifestPath returns pod manifest full path.
|
||||
func getPodManifestPath(workspace string) string {
|
||||
return filepath.Join(workspace, kubeletPodManifestPath)
|
||||
}
|
||||
|
||||
// isSystemd returns whether the node is a systemd node.
|
||||
func isSystemd(host string) (bool, error) {
|
||||
// Returns "systemd" if /run/systemd/system is found, empty string otherwise.
|
||||
output, err := SSH(host, "test", "-e", "/run/systemd/system", "&&", "echo", "systemd", "||", "true")
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to check systemd: error - %v output - %q", err, output)
|
||||
}
|
||||
return strings.TrimSpace(output) != "", nil
|
||||
}
|
||||
|
||||
// launchKubelet launches kubelet by running e2e_node.test binary in run-kubelet-mode.
|
||||
// This is a temporary solution, we should change node e2e to use the same node bootstrap
|
||||
// with cluster e2e and launch kubelet outside of the test for both regular node e2e and
|
||||
// node conformance test.
|
||||
// TODO(random-liu): Switch to use standard node bootstrap script.
|
||||
func launchKubelet(host, workspace, results, testArgs string) error {
|
||||
podManifestPath := getPodManifestPath(workspace)
|
||||
if output, err := SSH(host, "mkdir", podManifestPath); err != nil {
|
||||
return fmt.Errorf("failed to create kubelet pod manifest path %q: error - %v output - %q",
|
||||
podManifestPath, err, output)
|
||||
}
|
||||
startKubeletCmd := fmt.Sprintf("./%s --run-kubelet-mode --logtostderr --node-name=%s"+
|
||||
" --report-dir=%s %s --kubelet-flags=--pod-manifest-path=%s > %s 2>&1",
|
||||
conformanceTestBinary, host, results, testArgs, podManifestPath, filepath.Join(results, kubeletLauncherLog))
|
||||
var cmd []string
|
||||
systemd, err := isSystemd(host)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check systemd: %v", err)
|
||||
}
|
||||
if systemd {
|
||||
cmd = []string{
|
||||
"systemd-run", "sh", "-c", getSSHCommand(" && ",
|
||||
// Switch to workspace.
|
||||
fmt.Sprintf("cd %s", workspace),
|
||||
// Launch kubelet by running e2e_node.test in run-kubelet-mode.
|
||||
startKubeletCmd,
|
||||
),
|
||||
}
|
||||
} else {
|
||||
cmd = []string{
|
||||
"sh", "-c", getSSHCommand(" && ",
|
||||
// Switch to workspace.
|
||||
fmt.Sprintf("cd %s", workspace),
|
||||
// Launch kubelet by running e2e_node.test in run-kubelet-mode with nohup.
|
||||
fmt.Sprintf("(nohup %s &)", startKubeletCmd),
|
||||
),
|
||||
}
|
||||
}
|
||||
glog.V(2).Infof("Launch kubelet with command: %v", cmd)
|
||||
output, err := SSH(host, cmd...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to launch kubelet with command %v: error - %v output - %q",
|
||||
cmd, err, output)
|
||||
}
|
||||
glog.Info("Successfully launch kubelet")
|
||||
return nil
|
||||
}
|
||||
|
||||
// kubeletStopGracePeriod is the grace period to wait before forcibly killing kubelet.
|
||||
const kubeletStopGracePeriod = 10 * time.Second
|
||||
|
||||
// stopKubelet stops kubelet launcher and kubelet gracefully.
|
||||
func stopKubelet(host, workspace string) error {
|
||||
glog.Info("Gracefully stop kubelet launcher")
|
||||
if output, err := SSH(host, "pkill", conformanceTestBinary); err != nil {
|
||||
return fmt.Errorf("failed to gracefully stop kubelet launcher: error - %v output - %q",
|
||||
err, output)
|
||||
}
|
||||
glog.Info("Wait for kubelet launcher to stop")
|
||||
stopped := false
|
||||
for start := time.Now(); time.Since(start) < kubeletStopGracePeriod; time.Sleep(time.Second) {
|
||||
// Check whether the process is still running.
|
||||
output, err := SSH(host, "pidof", conformanceTestBinary, "||", "true")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check kubelet stopping: error - %v output -%q",
|
||||
err, output)
|
||||
}
|
||||
// Kubelet is stopped
|
||||
if strings.TrimSpace(output) == "" {
|
||||
stopped = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !stopped {
|
||||
glog.Info("Forcibly stop kubelet")
|
||||
if output, err := SSH(host, "pkill", "-SIGKILL", conformanceTestBinary); err != nil {
|
||||
return fmt.Errorf("failed to forcibly stop kubelet: error - %v output - %q",
|
||||
err, output)
|
||||
}
|
||||
}
|
||||
glog.Info("Successfully stop kubelet")
|
||||
// Clean up the pod manifest path
|
||||
podManifestPath := getPodManifestPath(workspace)
|
||||
if output, err := SSH(host, "rm", "-f", filepath.Join(workspace, podManifestPath)); err != nil {
|
||||
return fmt.Errorf("failed to cleanup pod manifest directory %q: error - %v, output - %q",
|
||||
podManifestPath, err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunTest runs test on the node.
|
||||
func (c *ConformanceRemote) RunTest(host, workspace, results, imageDesc, junitFilePrefix, testArgs, _, systemSpecName string, timeout time.Duration) (string, error) {
|
||||
// Install the cni plugins and add a basic CNI configuration.
|
||||
if err := setupCNI(host, workspace); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Configure iptables firewall rules.
|
||||
if err := configureFirewall(host); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Kill any running node processes.
|
||||
cleanupNodeProcesses(host)
|
||||
|
||||
// Load node conformance image.
|
||||
if err := loadConformanceImage(host, workspace); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Launch kubelet.
|
||||
if err := launchKubelet(host, workspace, results, testArgs); err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Stop kubelet.
|
||||
defer func() {
|
||||
if err := stopKubelet(host, workspace); err != nil {
|
||||
// Only log an error if failed to stop kubelet because it is not critical.
|
||||
glog.Errorf("failed to stop kubelet: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Run the tests
|
||||
glog.V(2).Infof("Starting tests on %q", host)
|
||||
podManifestPath := getPodManifestPath(workspace)
|
||||
cmd := fmt.Sprintf("'timeout -k 30s %fs docker run --rm --privileged=true --net=host -v /:/rootfs -v %s:%s -v %s:/var/result -e TEST_ARGS=--report-prefix=%s %s'",
|
||||
timeout.Seconds(), podManifestPath, podManifestPath, results, junitFilePrefix, getConformanceTestImageName(systemSpecName))
|
||||
testOutput, err := SSH(host, "sh", "-c", cmd)
|
||||
if err != nil {
|
||||
return testOutput, err
|
||||
}
|
||||
|
||||
return testOutput, nil
|
||||
}
|
173
vendor/k8s.io/kubernetes/test/e2e_node/remote/node_e2e.go
generated
vendored
Normal file
173
vendor/k8s.io/kubernetes/test/e2e_node/remote/node_e2e.go
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package remote
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/test/e2e_node/builder"
|
||||
)
|
||||
|
||||
const (
|
||||
systemSpecPath = "test/e2e_node/system/specs"
|
||||
)
|
||||
|
||||
// NodeE2ERemote contains the specific functions in the node e2e test suite.
|
||||
type NodeE2ERemote struct{}
|
||||
|
||||
func InitNodeE2ERemote() TestSuite {
|
||||
// TODO: Register flags.
|
||||
return &NodeE2ERemote{}
|
||||
}
|
||||
|
||||
// SetupTestPackage sets up the test package with binaries k8s required for node e2e tests
|
||||
func (n *NodeE2ERemote) SetupTestPackage(tardir, systemSpecName string) error {
|
||||
// Build the executables
|
||||
if err := builder.BuildGo(); err != nil {
|
||||
return fmt.Errorf("failed to build the depedencies: %v", err)
|
||||
}
|
||||
|
||||
// Make sure we can find the newly built binaries
|
||||
buildOutputDir, err := builder.GetK8sBuildOutputDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to locate kubernetes build output directory: %v", err)
|
||||
}
|
||||
|
||||
rootDir, err := builder.GetK8sRootDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to locate kubernetes root directory: %v", err)
|
||||
}
|
||||
|
||||
// Copy binaries
|
||||
requiredBins := []string{"kubelet", "e2e_node.test", "ginkgo", "mounter"}
|
||||
for _, bin := range requiredBins {
|
||||
source := filepath.Join(buildOutputDir, bin)
|
||||
if _, err := os.Stat(source); err != nil {
|
||||
return fmt.Errorf("failed to locate test binary %s: %v", bin, err)
|
||||
}
|
||||
out, err := exec.Command("cp", source, filepath.Join(tardir, bin)).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy %q: %v Output: %q", bin, err, out)
|
||||
}
|
||||
}
|
||||
|
||||
if systemSpecName != "" {
|
||||
// Copy system spec file
|
||||
source := filepath.Join(rootDir, systemSpecPath, systemSpecName+".yaml")
|
||||
if _, err := os.Stat(source); err != nil {
|
||||
return fmt.Errorf("failed to locate system spec %q: %v", source, err)
|
||||
}
|
||||
out, err := exec.Command("cp", source, tardir).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy system spec %q: %v, output: %q", source, err, out)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dest is relative to the root of the tar
|
||||
func tarAddFile(tar, source, dest string) error {
|
||||
dir := filepath.Dir(dest)
|
||||
tardir := filepath.Join(tar, dir)
|
||||
tardest := filepath.Join(tar, dest)
|
||||
|
||||
out, err := exec.Command("mkdir", "-p", tardir).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create archive bin subdir %q, was dest for file %q. Err: %v. Output:\n%s", tardir, source, err, out)
|
||||
}
|
||||
out, err = exec.Command("cp", source, tardest).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy file %q to the archive bin subdir %q. Err: %v. Output:\n%s", source, tardir, err, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// prependCOSMounterFlag prepends the flag for setting the GCI mounter path to
|
||||
// args and returns the result.
|
||||
func prependCOSMounterFlag(args, host, workspace string) (string, error) {
|
||||
glog.V(2).Infof("GCI/COS node and GCI/COS mounter both detected, modifying --experimental-mounter-path accordingly")
|
||||
mounterPath := filepath.Join(workspace, "mounter")
|
||||
args = fmt.Sprintf("--kubelet-flags=--experimental-mounter-path=%s ", mounterPath) + args
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// prependMemcgNotificationFlag prepends the flag for enabling memcg
|
||||
// notification to args and returns the result.
|
||||
func prependMemcgNotificationFlag(args string) string {
|
||||
return "--kubelet-flags=--experimental-kernel-memcg-notification=true " + args
|
||||
}
|
||||
|
||||
// updateOSSpecificKubeletFlags updates the Kubelet args with OS specific
|
||||
// settings.
|
||||
func updateOSSpecificKubeletFlags(args, host, workspace string) (string, error) {
|
||||
output, err := SSH(host, "cat", "/etc/os-release")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("issue detecting node's OS via node's /etc/os-release. Err: %v, Output:\n%s", err, output)
|
||||
}
|
||||
switch {
|
||||
case strings.Contains(output, "ID=gci"), strings.Contains(output, "ID=cos"):
|
||||
args = prependMemcgNotificationFlag(args)
|
||||
return prependCOSMounterFlag(args, host, workspace)
|
||||
case strings.Contains(output, "ID=ubuntu"):
|
||||
return prependMemcgNotificationFlag(args), nil
|
||||
}
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// RunTest runs test on the node.
|
||||
func (n *NodeE2ERemote) RunTest(host, workspace, results, imageDesc, junitFilePrefix, testArgs, ginkgoArgs, systemSpecName string, timeout time.Duration) (string, error) {
|
||||
// Install the cni plugins and add a basic CNI configuration.
|
||||
// TODO(random-liu): Do this in cloud init after we remove containervm test.
|
||||
if err := setupCNI(host, workspace); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Configure iptables firewall rules
|
||||
if err := configureFirewall(host); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Kill any running node processes
|
||||
cleanupNodeProcesses(host)
|
||||
|
||||
testArgs, err := updateOSSpecificKubeletFlags(testArgs, host, workspace)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
systemSpecFile := ""
|
||||
if systemSpecName != "" {
|
||||
systemSpecFile = systemSpecName + ".yaml"
|
||||
}
|
||||
|
||||
// Run the tests
|
||||
glog.V(2).Infof("Starting tests on %q", host)
|
||||
cmd := getSSHCommand(" && ",
|
||||
fmt.Sprintf("cd %s", workspace),
|
||||
fmt.Sprintf("timeout -k 30s %fs ./ginkgo %s ./e2e_node.test -- --system-spec-name=%s --system-spec-file=%s --logtostderr --v 4 --node-name=%s --report-dir=%s --report-prefix=%s --image-description=\"%s\" %s",
|
||||
timeout.Seconds(), ginkgoArgs, systemSpecName, systemSpecFile, host, results, junitFilePrefix, imageDesc, testArgs),
|
||||
)
|
||||
return SSH(host, "sh", "-c", cmd)
|
||||
}
|
203
vendor/k8s.io/kubernetes/test/e2e_node/remote/remote.go
generated
vendored
Normal file
203
vendor/k8s.io/kubernetes/test/e2e_node/remote/remote.go
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package remote
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
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.")
|
||||
|
||||
const archiveName = "e2e_node_test.tar.gz"
|
||||
|
||||
func CreateTestArchive(suite TestSuite, systemSpecName string) (string, error) {
|
||||
glog.V(2).Infof("Building archive...")
|
||||
tardir, err := ioutil.TempDir("", "node-e2e-archive")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create temporary directory %v.", err)
|
||||
}
|
||||
defer os.RemoveAll(tardir)
|
||||
|
||||
// Call the suite function to setup the test package.
|
||||
err = suite.SetupTestPackage(tardir, systemSpecName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to setup test package %q: %v", tardir, err)
|
||||
}
|
||||
|
||||
// Build the tar
|
||||
out, err := exec.Command("tar", "-zcvf", archiveName, "-C", tardir, ".").CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to build tar %v. Output:\n%s", err, out)
|
||||
}
|
||||
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get working directory %v.", err)
|
||||
}
|
||||
return filepath.Join(dir, archiveName), nil
|
||||
}
|
||||
|
||||
// Returns the command output, whether the exit was ok, and any errors
|
||||
// TODO(random-liu): junitFilePrefix is not prefix actually, the file name is junit-junitFilePrefix.xml. Change the variable name.
|
||||
func RunRemote(suite TestSuite, archive string, host string, cleanup bool, imageDesc, junitFilePrefix string, testArgs string, ginkgoArgs string, systemSpecName string) (string, bool, error) {
|
||||
// Create the temp staging directory
|
||||
glog.V(2).Infof("Staging test binaries on %q", host)
|
||||
workspace := fmt.Sprintf("/tmp/node-e2e-%s", getTimestamp())
|
||||
// Do not sudo here, so that we can use scp to copy test archive to the directdory.
|
||||
if output, err := SSHNoSudo(host, "mkdir", workspace); err != nil {
|
||||
// Exit failure with the error
|
||||
return "", false, fmt.Errorf("failed to create workspace directory %q on host %q: %v output: %q", workspace, host, err, output)
|
||||
}
|
||||
if cleanup {
|
||||
defer func() {
|
||||
output, err := SSH(host, "rm", "-rf", workspace)
|
||||
if err != nil {
|
||||
glog.Errorf("failed to cleanup workspace %q on host %q: %v. Output:\n%s", workspace, host, err, output)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Copy the archive to the staging directory
|
||||
if output, err := runSSHCommand("scp", archive, fmt.Sprintf("%s:%s/", GetHostnameOrIp(host), workspace)); err != nil {
|
||||
// Exit failure with the error
|
||||
return "", false, fmt.Errorf("failed to copy test archive: %v, output: %q", err, output)
|
||||
}
|
||||
|
||||
// Extract the archive
|
||||
cmd := getSSHCommand(" && ",
|
||||
fmt.Sprintf("cd %s", workspace),
|
||||
fmt.Sprintf("tar -xzvf ./%s", archiveName),
|
||||
)
|
||||
glog.V(2).Infof("Extracting tar on %q", host)
|
||||
// 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)
|
||||
}
|
||||
|
||||
// Create the test result directory.
|
||||
resultDir := filepath.Join(workspace, "results")
|
||||
if output, err := SSHNoSudo(host, "mkdir", resultDir); err != nil {
|
||||
// Exit failure with the error
|
||||
return "", false, fmt.Errorf("failed to create test result directory %q on host %q: %v output: %q", resultDir, host, err, output)
|
||||
}
|
||||
|
||||
glog.V(2).Infof("Running test on %q", host)
|
||||
output, err := suite.RunTest(host, workspace, resultDir, imageDesc, junitFilePrefix, testArgs, ginkgoArgs, systemSpecName, *testTimeoutSeconds)
|
||||
|
||||
aggErrs := []error{}
|
||||
// Do not log the output here, let the caller deal with the test output.
|
||||
if err != nil {
|
||||
aggErrs = append(aggErrs, err)
|
||||
collectSystemLog(host)
|
||||
}
|
||||
|
||||
glog.V(2).Infof("Copying test artifacts from %q", host)
|
||||
scpErr := getTestArtifacts(host, workspace)
|
||||
if scpErr != nil {
|
||||
aggErrs = append(aggErrs, scpErr)
|
||||
}
|
||||
|
||||
return output, len(aggErrs) == 0, utilerrors.NewAggregate(aggErrs)
|
||||
}
|
||||
|
||||
// timestampFormat is the timestamp format used in the node e2e directory name.
|
||||
const timestampFormat = "20060102T150405"
|
||||
|
||||
func getTimestamp() string {
|
||||
return fmt.Sprintf(time.Now().Format(timestampFormat))
|
||||
}
|
||||
|
||||
func getTestArtifacts(host, testDir string) error {
|
||||
logPath := filepath.Join(*resultsDir, host)
|
||||
if err := os.MkdirAll(logPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create log directory %q: %v", logPath, err)
|
||||
}
|
||||
// Copy logs to artifacts/hostname
|
||||
_, err := runSSHCommand("scp", "-r", fmt.Sprintf("%s:%s/results/*.log", GetHostnameOrIp(host), testDir), logPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Copy json files (if any) to artifacts.
|
||||
if _, err = SSH(host, "ls", fmt.Sprintf("%s/results/*.json", testDir)); err == nil {
|
||||
_, err = runSSHCommand("scp", "-r", fmt.Sprintf("%s:%s/results/*.json", GetHostnameOrIp(host), testDir), *resultsDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Copy junit to the top of artifacts
|
||||
_, err = runSSHCommand("scp", fmt.Sprintf("%s:%s/results/junit*", GetHostnameOrIp(host), testDir), *resultsDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectSystemLog is a temporary hack to collect system log when encountered on
|
||||
// unexpected error.
|
||||
func collectSystemLog(host string) {
|
||||
// Encountered an unexpected error. The remote test harness may not
|
||||
// have finished retrieved and stored all the logs in this case. Try
|
||||
// to get some logs for debugging purposes.
|
||||
// TODO: This is a best-effort, temporary hack that only works for
|
||||
// journald nodes. We should have a more robust way to collect logs.
|
||||
var (
|
||||
logName = "system.log"
|
||||
logPath = fmt.Sprintf("/tmp/%s-%s", getTimestamp(), logName)
|
||||
destPath = fmt.Sprintf("%s/%s-%s", *resultsDir, host, logName)
|
||||
)
|
||||
glog.V(2).Infof("Test failed unexpectedly. Attempting to retrieving system logs (only works for nodes with journald)")
|
||||
// Try getting the system logs from journald and store it to a file.
|
||||
// Don't reuse the original test directory on the remote host because
|
||||
// it could've be been removed if the node was rebooted.
|
||||
if output, err := SSH(host, "sh", "-c", fmt.Sprintf("'journalctl --system --all > %s'", logPath)); err == nil {
|
||||
glog.V(2).Infof("Got the system logs from journald; copying it back...")
|
||||
if output, err := runSSHCommand("scp", fmt.Sprintf("%s:%s", GetHostnameOrIp(host), logPath), destPath); err != nil {
|
||||
glog.V(2).Infof("Failed to copy the log: err: %v, output: %q", err, output)
|
||||
}
|
||||
} else {
|
||||
glog.V(2).Infof("Failed to run journactl (normal if it doesn't exist on the node): %v, output: %q", err, output)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteLog is a temporary function to make it possible to write log
|
||||
// in the runner. This is used to collect serial console log.
|
||||
// TODO(random-liu): Use the log-dump script in cluster e2e.
|
||||
func WriteLog(host, filename, content string) error {
|
||||
logPath := filepath.Join(*resultsDir, host)
|
||||
if err := os.MkdirAll(logPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create log directory %q: %v", logPath, err)
|
||||
}
|
||||
f, err := os.Create(filepath.Join(logPath, filename))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString(content)
|
||||
return err
|
||||
}
|
111
vendor/k8s.io/kubernetes/test/e2e_node/remote/ssh.go
generated
vendored
Normal file
111
vendor/k8s.io/kubernetes/test/e2e_node/remote/ssh.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package remote
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
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 sshKey = flag.String("ssh-key", "", "Path to ssh private key.")
|
||||
var sshUser = flag.String("ssh-user", "", "Use predefined user for ssh.")
|
||||
|
||||
var sshOptionsMap map[string]string
|
||||
var sshDefaultKeyMap map[string]string
|
||||
|
||||
func init() {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
glog.Fatal(err)
|
||||
}
|
||||
sshOptionsMap = map[string]string{
|
||||
"gce": "-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o CheckHostIP=no -o StrictHostKeyChecking=no -o ServerAliveInterval=30 -o LogLevel=ERROR",
|
||||
}
|
||||
sshDefaultKeyMap = map[string]string{
|
||||
"gce": fmt.Sprintf("%s/.ssh/google_compute_engine", usr.HomeDir),
|
||||
}
|
||||
}
|
||||
|
||||
var hostnameIpOverrides = struct {
|
||||
sync.RWMutex
|
||||
m map[string]string
|
||||
}{m: make(map[string]string)}
|
||||
|
||||
func AddHostnameIp(hostname, ip string) {
|
||||
hostnameIpOverrides.Lock()
|
||||
defer hostnameIpOverrides.Unlock()
|
||||
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 {
|
||||
host = ip
|
||||
}
|
||||
if *sshUser != "" {
|
||||
host = fmt.Sprintf("%s@%s", *sshUser, host)
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
// getSSHCommand handles proper quoting so that multiple commands are executed in the same shell over ssh
|
||||
func getSSHCommand(sep string, args ...string) string {
|
||||
return fmt.Sprintf("'%s'", strings.Join(args, sep))
|
||||
}
|
||||
|
||||
// SSH executes ssh command with runSSHCommand as root. The `sudo` makes sure that all commands
|
||||
// are executed by root, so that there won't be permission mismatch between different commands.
|
||||
func SSH(host string, cmd ...string) (string, error) {
|
||||
return runSSHCommand("ssh", append([]string{GetHostnameOrIp(host), "--", "sudo"}, cmd...)...)
|
||||
}
|
||||
|
||||
// SSHNoSudo executes ssh command with runSSHCommand as normal user. Sometimes we need this,
|
||||
// for example creating a directory that we'll copy files there with scp.
|
||||
func SSHNoSudo(host string, cmd ...string) (string, error) {
|
||||
return runSSHCommand("ssh", append([]string{GetHostnameOrIp(host), "--"}, cmd...)...)
|
||||
}
|
||||
|
||||
// runSSHCommand executes the ssh or scp command, adding the flag provided --ssh-options
|
||||
func runSSHCommand(cmd string, args ...string) (string, error) {
|
||||
if *sshKey != "" {
|
||||
args = append([]string{"-i", *sshKey}, args...)
|
||||
} else if key, found := sshDefaultKeyMap[*sshEnv]; found {
|
||||
args = append([]string{"-i", key}, args...)
|
||||
}
|
||||
if env, found := sshOptionsMap[*sshEnv]; found {
|
||||
args = append(strings.Split(env, " "), args...)
|
||||
}
|
||||
if *sshOptions != "" {
|
||||
args = append(strings.Split(*sshOptions, " "), args...)
|
||||
}
|
||||
output, err := exec.Command(cmd, args...).CombinedOutput()
|
||||
if err != nil {
|
||||
return string(output), fmt.Errorf("command [%s %s] failed with error: %v", cmd, strings.Join(args, " "), err)
|
||||
}
|
||||
return string(output), nil
|
||||
}
|
49
vendor/k8s.io/kubernetes/test/e2e_node/remote/types.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/test/e2e_node/remote/types.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package remote
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestSuite is the interface of a test suite, such as node e2e, node conformance,
|
||||
// node soaking, cri validation etc.
|
||||
type TestSuite interface {
|
||||
// SetupTestPackage setup the test package in the given directory. TestSuite
|
||||
// should put all necessary binaries and dependencies into the path. The caller
|
||||
// will:
|
||||
// * create a tarball with the directory.
|
||||
// * deploy the tarball to the testing host.
|
||||
// * untar the tarball to the testing workspace on the testing host.
|
||||
SetupTestPackage(path, systemSpecName string) error
|
||||
// RunTest runs test on the node in the given workspace and returns test output
|
||||
// and test error if there is any.
|
||||
// * host is the target node to run the test.
|
||||
// * workspace is the directory on the testing host the test is running in. Note
|
||||
// that the test package is unpacked in the workspace before running the test.
|
||||
// * results is the directory the test should write result into. All logs should be
|
||||
// saved as *.log, all junit file should start with junit*.
|
||||
// * imageDesc is the description of the image the test is running on.
|
||||
// It will be used for logging purpose only.
|
||||
// * junitFilePrefix is the prefix of output junit file.
|
||||
// * testArgs is the arguments passed to test.
|
||||
// * ginkgoArgs is the arguments passed to ginkgo.
|
||||
// * systemSpecName is the name of the system spec used for validating the
|
||||
// image on which the test runs.
|
||||
// * timeout is the test timeout.
|
||||
RunTest(host, workspace, results, imageDesc, junitFilePrefix, testArgs, ginkgoArgs, systemSpecName string, timeout time.Duration) (string, error)
|
||||
}
|
133
vendor/k8s.io/kubernetes/test/e2e_node/remote/utils.go
generated
vendored
Normal file
133
vendor/k8s.io/kubernetes/test/e2e_node/remote/utils.go
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package remote
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// utils.go contains functions used across test suites.
|
||||
|
||||
const (
|
||||
cniVersion = "v0.6.0"
|
||||
cniArch = "amd64"
|
||||
cniDirectory = "cni/bin" // The CNI tarball places binaries under directory under "cni/bin".
|
||||
cniConfDirectory = "cni/net.d"
|
||||
cniURL = "https://dl.k8s.io/network-plugins/cni-plugins-" + cniArch + "-" + cniVersion + ".tgz"
|
||||
)
|
||||
|
||||
const cniConfig = `{
|
||||
"name": "mynet",
|
||||
"type": "bridge",
|
||||
"bridge": "mynet0",
|
||||
"isDefaultGateway": true,
|
||||
"forceAddress": false,
|
||||
"ipMasq": true,
|
||||
"hairpinMode": true,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.10.0.0/16"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
// Install the cni plugin and add basic bridge configuration to the
|
||||
// configuration directory.
|
||||
func setupCNI(host, workspace string) error {
|
||||
glog.V(2).Infof("Install CNI on %q", host)
|
||||
cniPath := filepath.Join(workspace, cniDirectory)
|
||||
cmd := getSSHCommand(" ; ",
|
||||
fmt.Sprintf("mkdir -p %s", cniPath),
|
||||
fmt.Sprintf("wget -O - %s | tar -xz -C %s", cniURL, cniPath),
|
||||
)
|
||||
if output, err := SSH(host, "sh", "-c", cmd); err != nil {
|
||||
return fmt.Errorf("failed to install cni plugin on %q: %v output: %q", host, err, output)
|
||||
}
|
||||
|
||||
// The added CNI network config is not needed for kubenet. It is only
|
||||
// used when testing the CNI network plugin, but is added in both cases
|
||||
// for consistency and simplicity.
|
||||
glog.V(2).Infof("Adding CNI configuration on %q", host)
|
||||
cniConfigPath := filepath.Join(workspace, cniConfDirectory)
|
||||
cmd = getSSHCommand(" ; ",
|
||||
fmt.Sprintf("mkdir -p %s", cniConfigPath),
|
||||
fmt.Sprintf("echo %s > %s", quote(cniConfig), filepath.Join(cniConfigPath, "mynet.conf")),
|
||||
)
|
||||
if output, err := SSH(host, "sh", "-c", cmd); err != nil {
|
||||
return fmt.Errorf("failed to write cni configuration on %q: %v output: %q", host, err, output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// configureFirewall configures iptable firewall rules.
|
||||
func configureFirewall(host string) error {
|
||||
glog.V(2).Infof("Configure iptables firewall rules on %q", host)
|
||||
// TODO: consider calling bootstrap script to configure host based on OS
|
||||
output, err := SSH(host, "iptables", "-L", "INPUT")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get iptables INPUT on %q: %v output: %q", host, err, output)
|
||||
}
|
||||
if strings.Contains(output, "Chain INPUT (policy DROP)") {
|
||||
cmd := getSSHCommand("&&",
|
||||
"(iptables -C INPUT -w -p TCP -j ACCEPT || iptables -A INPUT -w -p TCP -j ACCEPT)",
|
||||
"(iptables -C INPUT -w -p UDP -j ACCEPT || iptables -A INPUT -w -p UDP -j ACCEPT)",
|
||||
"(iptables -C INPUT -w -p ICMP -j ACCEPT || iptables -A INPUT -w -p ICMP -j ACCEPT)")
|
||||
output, err := SSH(host, "sh", "-c", cmd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to configured firewall on %q: %v output: %v", host, err, output)
|
||||
}
|
||||
}
|
||||
output, err = SSH(host, "iptables", "-L", "FORWARD")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get iptables FORWARD on %q: %v output: %q", host, err, output)
|
||||
}
|
||||
if strings.Contains(output, "Chain FORWARD (policy DROP)") {
|
||||
cmd := getSSHCommand("&&",
|
||||
"(iptables -C FORWARD -w -p TCP -j ACCEPT || iptables -A FORWARD -w -p TCP -j ACCEPT)",
|
||||
"(iptables -C FORWARD -w -p UDP -j ACCEPT || iptables -A FORWARD -w -p UDP -j ACCEPT)",
|
||||
"(iptables -C FORWARD -w -p ICMP -j ACCEPT || iptables -A FORWARD -w -p ICMP -j ACCEPT)")
|
||||
output, err = SSH(host, "sh", "-c", cmd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to configured firewall on %q: %v output: %v", host, err, output)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleanupNodeProcesses kills all running node processes may conflict with the test.
|
||||
func cleanupNodeProcesses(host string) {
|
||||
glog.V(2).Infof("Killing any existing node processes on %q", host)
|
||||
cmd := getSSHCommand(" ; ",
|
||||
"pkill kubelet",
|
||||
"pkill kube-apiserver",
|
||||
"pkill etcd",
|
||||
"pkill e2e_node.test",
|
||||
)
|
||||
// No need to log an error if pkill fails since pkill will fail if the commands are not running.
|
||||
// If we are unable to stop existing running k8s processes, we should see messages in the kubelet/apiserver/etcd
|
||||
// logs about failing to bind the required ports.
|
||||
SSH(host, "sh", "-c", cmd)
|
||||
}
|
||||
|
||||
// Quotes a shell literal so it can be nested within another shell scope.
|
||||
func quote(s string) string {
|
||||
return fmt.Sprintf("'\"'\"'%s'\"'\"'", s)
|
||||
}
|
Reference in New Issue
Block a user