From 76ef9c9074f99c77617d87fbff821f9fbd550727 Mon Sep 17 00:00:00 2001 From: Filipe Brandenburger Date: Mon, 26 Mar 2018 10:38:40 -0700 Subject: [PATCH] Make systemd service name for kubelet use a timestamp in e2e-node tests. This makes it easier to figure out which execution was last when looking at the output of `systemd list-units kubelet-*.service`. We try to find the name of the /tmp/node-e2e-* directory and use the same timestamp if we can. Otherwise, we just call Now() again, which isn't as nice (as the unit name and directory name will not match) but will still produce unit names that will be ordered when launching multiple subsequent executions on the same host. --- test/e2e_node/remote/remote.go | 30 +++++++++++++++++++++++++++--- test/e2e_node/services/BUILD | 1 + test/e2e_node/services/kubelet.go | 9 +++++++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/test/e2e_node/remote/remote.go b/test/e2e_node/remote/remote.go index c54b35ec66..746899f8b5 100644 --- a/test/e2e_node/remote/remote.go +++ b/test/e2e_node/remote/remote.go @@ -23,6 +23,8 @@ import ( "os" "os/exec" "path/filepath" + "regexp" + "strings" "time" "github.com/golang/glog" @@ -66,7 +68,7 @@ func CreateTestArchive(suite TestSuite, systemSpecName string) (string, error) { 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()) + workspace := newWorkspaceDir() // 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 @@ -126,13 +128,35 @@ func RunRemote(suite TestSuite, archive string, host string, cleanup bool, image return output, len(aggErrs) == 0, utilerrors.NewAggregate(aggErrs) } -// timestampFormat is the timestamp format used in the node e2e directory name. -const timestampFormat = "20060102T150405" +const ( + // workspaceDirPrefix is the string prefix used in the workspace directory name. + workspaceDirPrefix = "node-e2e-" + // timestampFormat is the timestamp format used in the node e2e directory name. + timestampFormat = "20060102T150405" +) func getTimestamp() string { return fmt.Sprintf(time.Now().Format(timestampFormat)) } +func newWorkspaceDir() string { + return filepath.Join("/tmp", workspaceDirPrefix+getTimestamp()) +} + +// Parses the workspace directory name and gets the timestamp part of it. +// This can later be used to name other artifacts (such as the +// kubelet-${instance}.service systemd transient service used to launch +// Kubelet) so that they can be matched to each other. +func GetTimestampFromWorkspaceDir(dir string) string { + dirTimestamp := strings.TrimPrefix(filepath.Base(dir), workspaceDirPrefix) + re := regexp.MustCompile("^\\d{8}T\\d{6}$") + if re.MatchString(dirTimestamp) { + return dirTimestamp + } + // Fallback: if we can't find that timestamp, default to using Now() + return getTimestamp() +} + func getTestArtifacts(host, testDir string) error { logPath := filepath.Join(*resultsDir, host) if err := os.MkdirAll(logPath, 0755); err != nil { diff --git a/test/e2e_node/services/BUILD b/test/e2e_node/services/BUILD index f5992b2eba..4614e13e4f 100644 --- a/test/e2e_node/services/BUILD +++ b/test/e2e_node/services/BUILD @@ -31,6 +31,7 @@ go_library( "//pkg/kubelet/apis/kubeletconfig/v1beta1:go_default_library", "//test/e2e/framework:go_default_library", "//test/e2e_node/builder:go_default_library", + "//test/e2e_node/remote:go_default_library", "//vendor/github.com/coreos/etcd/etcdserver:go_default_library", "//vendor/github.com/coreos/etcd/etcdserver/api/v2http:go_default_library", "//vendor/github.com/coreos/etcd/pkg/transport:go_default_library", diff --git a/test/e2e_node/services/kubelet.go b/test/e2e_node/services/kubelet.go index b1f631e08e..8672973c86 100644 --- a/test/e2e_node/services/kubelet.go +++ b/test/e2e_node/services/kubelet.go @@ -20,7 +20,6 @@ import ( "flag" "fmt" "io/ioutil" - "math/rand" "os" "os/exec" "path/filepath" @@ -41,6 +40,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1" "k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e_node/builder" + "k8s.io/kubernetes/test/e2e_node/remote" ) // TODO(random-liu): Replace this with standard kubelet launcher. @@ -198,7 +198,12 @@ func (e *E2EServices) startKubelet() (*server, error) { // Since kubelet will typically be run as a service it also makes more // sense to test it that way isSystemd = true - unitName := fmt.Sprintf("kubelet-%d.service", rand.Int31()) + // We can ignore errors, to have GetTimestampFromWorkspaceDir() fallback + // to the current time. + cwd, _ := os.Getwd() + // Use the timestamp from the current directory to name the systemd unit. + unitTimestamp := remote.GetTimestampFromWorkspaceDir(cwd) + unitName := fmt.Sprintf("kubelet-%s.service", unitTimestamp) if kubeletContainerized { cmdArgs = append(cmdArgs, systemdRun, "--unit="+unitName, "--slice=runtime.slice", "--remain-after-exit", "/usr/bin/docker", "run", "--name=kubelet",