mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 09:52:49 +00:00
139 lines
4.2 KiB
Go
139 lines
4.2 KiB
Go
/*
|
|
Copyright 2019 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 main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
if strings.Contains(os.Args[0], "run_e2e.sh") || strings.Contains(os.Args[0], "gorunner") {
|
|
log.Print("warn: calling test with e2e.test is deprecated and will be removed in 1.25, please rely on container manifest to invoke executable")
|
|
}
|
|
env := envWithDefaults(map[string]string{
|
|
resultsDirEnvKey: defaultResultsDir,
|
|
skipEnvKey: defaultSkip,
|
|
focusEnvKey: defaultFocus,
|
|
providerEnvKey: defaultProvider,
|
|
parallelEnvKey: defaultParallel,
|
|
ginkgoEnvKey: defaultGinkgoBinary,
|
|
testBinEnvKey: defaultTestBinary,
|
|
})
|
|
|
|
if err := configureAndRunWithEnv(env); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// configureAndRunWithEnv uses the given environment to configure and then start the test run.
|
|
// It will handle TERM signals gracefully and kill the test process and will
|
|
// save the logs/results to the location specified via the RESULTS_DIR environment
|
|
// variable.
|
|
func configureAndRunWithEnv(env Getenver) error {
|
|
// Ensure we save results regardless of other errors. This helps any
|
|
// consumer who may be polling for the results.
|
|
resultsDir := env.Getenv(resultsDirEnvKey)
|
|
defer saveResults(resultsDir)
|
|
|
|
// Print the output to stdout and a logfile which will be returned
|
|
// as part of the results tarball.
|
|
logFilePath := filepath.Join(resultsDir, logFileName)
|
|
// ensure the resultsDir actually exists
|
|
if _, err := os.Stat(resultsDir); os.IsNotExist(err) {
|
|
log.Printf("The resultsDir %v does not exist, will create it", resultsDir)
|
|
if mkdirErr := os.Mkdir(resultsDir, 0755); mkdirErr != nil {
|
|
return fmt.Errorf("failed to create log directory %v: %w", resultsDir, mkdirErr)
|
|
}
|
|
}
|
|
logFile, err := os.Create(logFilePath)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create log file %v: %w", logFilePath, err)
|
|
}
|
|
mw := io.MultiWriter(os.Stdout, logFile)
|
|
cmd := getCmd(env, mw)
|
|
|
|
log.Printf("Running command:\n%v\n", cmdInfo(cmd))
|
|
err = cmd.Start()
|
|
if err != nil {
|
|
return fmt.Errorf("starting command: %w", err)
|
|
}
|
|
|
|
// Handle signals and shutdown process gracefully.
|
|
go setupSigHandler(cmd.Process.Pid)
|
|
|
|
err = cmd.Wait()
|
|
if err != nil {
|
|
return fmt.Errorf("running command: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// setupSigHandler will kill the process identified by the given PID if it
|
|
// gets a TERM signal.
|
|
func setupSigHandler(pid int) {
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, os.Interrupt)
|
|
|
|
// Block until a signal is received.
|
|
log.Println("Now listening for interrupts")
|
|
s := <-c
|
|
log.Printf("Got signal: %v. Shutting down test process (PID: %v)\n", s, pid)
|
|
p, err := os.FindProcess(pid)
|
|
if err != nil {
|
|
log.Printf("Could not find process %v to shut down.\n", pid)
|
|
return
|
|
}
|
|
if err := p.Signal(s); err != nil {
|
|
log.Printf("Failed to signal test process to terminate: %v\n", err)
|
|
return
|
|
}
|
|
log.Printf("Signalled process %v to terminate successfully.\n", pid)
|
|
}
|
|
|
|
// saveResults will tar the results directory and write the resulting tarball path
|
|
// into the donefile.
|
|
func saveResults(resultsDir string) error {
|
|
log.Printf("Saving results at %v\n", resultsDir)
|
|
|
|
err := tarDir(resultsDir, filepath.Join(resultsDir, resultsTarballName))
|
|
if err != nil {
|
|
return fmt.Errorf("tar directory %v: %w", resultsDir, err)
|
|
}
|
|
|
|
doneFile := filepath.Join(resultsDir, doneFileName)
|
|
|
|
resultsTarball := filepath.Join(resultsDir, resultsTarballName)
|
|
resultsTarball, err = filepath.Abs(resultsTarball)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to find absolute path for %v: %w", resultsTarball, err)
|
|
}
|
|
|
|
err = os.WriteFile(doneFile, []byte(resultsTarball), os.FileMode(0777))
|
|
if err != nil {
|
|
return fmt.Errorf("writing donefile: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|