mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
vendor updates
This commit is contained in:
8
vendor/k8s.io/kubernetes/test/e2e_node/services/BUILD
generated
vendored
8
vendor/k8s.io/kubernetes/test/e2e_node/services/BUILD
generated
vendored
@ -22,9 +22,13 @@ go_library(
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//cmd/kubelet/app/options:go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/controller/namespace:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/scheme:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig/v1beta1:go_default_library",
|
||||
"//test/e2e/framework:go_default_library",
|
||||
"//test/e2e_node/builder:go_default_library",
|
||||
"//vendor/github.com/coreos/etcd/etcdserver:go_default_library",
|
||||
@ -33,8 +37,12 @@ go_library(
|
||||
"//vendor/github.com/coreos/etcd/pkg/types:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/kardianos/osext:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
|
1
vendor/k8s.io/kubernetes/test/e2e_node/services/apiserver.go
generated
vendored
1
vendor/k8s.io/kubernetes/test/e2e_node/services/apiserver.go
generated
vendored
@ -52,6 +52,7 @@ func (a *APIServer) Start() error {
|
||||
}
|
||||
config.ServiceClusterIPRange = *ipnet
|
||||
config.AllowPrivileged = true
|
||||
config.Admission.GenericAdmission.DisablePlugins = []string{"ServiceAccount"}
|
||||
errCh := make(chan error)
|
||||
go func() {
|
||||
defer close(errCh)
|
||||
|
1
vendor/k8s.io/kubernetes/test/e2e_node/services/etcd.go
generated
vendored
1
vendor/k8s.io/kubernetes/test/e2e_node/services/etcd.go
generated
vendored
@ -77,6 +77,7 @@ func NewEtcd(dataDir string) *EtcdServer {
|
||||
MaxWALFiles: maxWALFiles,
|
||||
TickMs: tickMs,
|
||||
ElectionTicks: electionTicks,
|
||||
AuthToken: "simple",
|
||||
}
|
||||
|
||||
return &EtcdServer{
|
||||
|
265
vendor/k8s.io/kubernetes/test/e2e_node/services/kubelet.go
generated
vendored
265
vendor/k8s.io/kubernetes/test/e2e_node/services/kubelet.go
generated
vendored
@ -25,11 +25,20 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilflag "k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/scheme"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/v1beta1"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
"k8s.io/kubernetes/test/e2e_node/builder"
|
||||
)
|
||||
@ -60,9 +69,15 @@ func (a *args) Set(value string) error {
|
||||
|
||||
// kubeletArgs is the override kubelet args specified by the test runner.
|
||||
var kubeletArgs args
|
||||
var kubeletContainerized bool
|
||||
var hyperkubeImage string
|
||||
var genKubeletConfigFile bool
|
||||
|
||||
func init() {
|
||||
flag.Var(&kubeletArgs, "kubelet-flags", "Kubelet flags passed to kubelet, this will override default kubelet flags in the test. Flags specified in multiple kubelet-flags will be concatenate.")
|
||||
flag.BoolVar(&kubeletContainerized, "kubelet-containerized", false, "Run kubelet in a docker container")
|
||||
flag.StringVar(&hyperkubeImage, "hyperkube-image", "", "Docker image with containerized kubelet")
|
||||
flag.BoolVar(&genKubeletConfigFile, "generate-kubelet-config-file", true, "The test runner will generate a Kubelet config file containing test defaults instead of passing default flags to the Kubelet.")
|
||||
}
|
||||
|
||||
// RunKubelet starts kubelet and waits for termination signal. Once receives the
|
||||
@ -93,10 +108,14 @@ const (
|
||||
// startKubelet starts the Kubelet in a separate process or returns an error
|
||||
// if the Kubelet fails to start.
|
||||
func (e *E2EServices) startKubelet() (*server, error) {
|
||||
if kubeletContainerized && hyperkubeImage == "" {
|
||||
return nil, fmt.Errorf("the --hyperkube-image option must be set")
|
||||
}
|
||||
|
||||
glog.Info("Starting kubelet")
|
||||
|
||||
// set feature gates so we can check which features are enabled and pass the appropriate flags
|
||||
utilfeature.DefaultFeatureGate.Set(framework.TestContext.FeatureGates)
|
||||
utilfeature.DefaultFeatureGate.SetFromMap(framework.TestContext.FeatureGates)
|
||||
|
||||
// Build kubeconfig
|
||||
kubeconfigPath, err := createKubeconfigCWD()
|
||||
@ -104,16 +123,71 @@ func (e *E2EServices) startKubelet() (*server, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create pod manifest path
|
||||
manifestPath, err := createPodManifestDirectory()
|
||||
// KubeletConfiguration file path
|
||||
kubeletConfigPath, err := kubeletConfigCWDPath()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e.rmDirs = append(e.rmDirs, manifestPath)
|
||||
|
||||
// Create pod directory
|
||||
podPath, err := createPodDirectory()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e.rmDirs = append(e.rmDirs, podPath)
|
||||
err = createRootDirectory(KubeletRootDirectory)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// PLEASE NOTE: If you set new KubeletConfiguration values or stop setting values here,
|
||||
// you must also update the flag names in kubeletConfigFlags!
|
||||
kubeletConfigFlags := []string{}
|
||||
|
||||
// set up the default kubeletconfiguration
|
||||
kc, err := options.NewKubeletConfiguration()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kc.CgroupRoot = "/"
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "cgroup-root")
|
||||
|
||||
kc.VolumeStatsAggPeriod = metav1.Duration{Duration: 10 * time.Second} // Aggregate volumes frequently so tests don't need to wait as long
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "volume-stats-agg-period")
|
||||
|
||||
kc.SerializeImagePulls = false
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "serialize-image-pulls")
|
||||
|
||||
kc.StaticPodPath = podPath
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "pod-manifest-path")
|
||||
|
||||
kc.FileCheckFrequency = metav1.Duration{Duration: 10 * time.Second} // Check file frequently so tests won't wait too long
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "file-check-frequency")
|
||||
|
||||
// Assign a fixed CIDR to the node because there is no node controller.
|
||||
// Note: this MUST be in sync with with the IP in
|
||||
// - cluster/gce/config-test.sh and
|
||||
// - test/e2e_node/conformance/run_test.sh.
|
||||
kc.PodCIDR = "10.100.0.0/24"
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "pod-cidr")
|
||||
|
||||
kc.EvictionPressureTransitionPeriod = metav1.Duration{Duration: 30 * time.Second}
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "eviction-pressure-transition-period")
|
||||
|
||||
kc.EvictionHard = map[string]string{
|
||||
"memory.available": "250Mi",
|
||||
"nodefs.available": "10%",
|
||||
"nodefs.inodesFree": "5%",
|
||||
}
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "eviction-hard")
|
||||
|
||||
kc.EvictionMinimumReclaim = map[string]string{
|
||||
"nodefs.available": "5%",
|
||||
"nodefs.inodesFree": "5%",
|
||||
}
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "eviction-minimum-reclaim")
|
||||
|
||||
var killCommand, restartCommand *exec.Cmd
|
||||
var isSystemd bool
|
||||
// Apply default kubelet flags.
|
||||
@ -125,54 +199,77 @@ func (e *E2EServices) startKubelet() (*server, error) {
|
||||
// sense to test it that way
|
||||
isSystemd = true
|
||||
unitName := fmt.Sprintf("kubelet-%d.service", rand.Int31())
|
||||
cmdArgs = append(cmdArgs, systemdRun, "--unit="+unitName, "--slice=runtime.slice", "--remain-after-exit", builder.GetKubeletServerBin())
|
||||
if kubeletContainerized {
|
||||
cmdArgs = append(cmdArgs, systemdRun, "--unit="+unitName, "--slice=runtime.slice", "--remain-after-exit",
|
||||
"/usr/bin/docker", "run", "--name=kubelet",
|
||||
"--rm", "--privileged", "--net=host", "--pid=host",
|
||||
"-e HOST=/rootfs", "-e HOST_ETC=/host-etc",
|
||||
"-v", "/etc/localtime:/etc/localtime:ro",
|
||||
"-v", "/etc/machine-id:/etc/machine-id:ro",
|
||||
"-v", filepath.Dir(kubeconfigPath)+":/etc/kubernetes",
|
||||
"-v", "/:/rootfs:ro,rslave",
|
||||
"-v", "/run:/run",
|
||||
"-v", "/sys/fs/cgroup:/sys/fs/cgroup:rw",
|
||||
"-v", "/sys:/sys:rw",
|
||||
"-v", "/usr/bin/docker:/usr/bin/docker:ro",
|
||||
"-v", "/var/lib/cni:/var/lib/cni",
|
||||
"-v", "/var/lib/docker:/var/lib/docker",
|
||||
"-v", "/var/lib/kubelet:/var/lib/kubelet:rw,rslave",
|
||||
"-v", "/var/log:/var/log",
|
||||
"-v", podPath+":"+podPath+":rw",
|
||||
)
|
||||
|
||||
// if we will generate a kubelet config file, we need to mount that path into the container too
|
||||
if genKubeletConfigFile {
|
||||
cmdArgs = append(cmdArgs, "-v", filepath.Dir(kubeletConfigPath)+":"+filepath.Dir(kubeletConfigPath)+":ro")
|
||||
}
|
||||
|
||||
cmdArgs = append(cmdArgs, hyperkubeImage, "/hyperkube", "kubelet", "--containerized")
|
||||
kubeconfigPath = "/etc/kubernetes/kubeconfig"
|
||||
} else {
|
||||
cmdArgs = append(cmdArgs,
|
||||
systemdRun,
|
||||
"--unit="+unitName,
|
||||
"--slice=runtime.slice",
|
||||
"--remain-after-exit",
|
||||
builder.GetKubeletServerBin())
|
||||
}
|
||||
|
||||
killCommand = exec.Command("systemctl", "kill", unitName)
|
||||
restartCommand = exec.Command("systemctl", "restart", unitName)
|
||||
e.logs["kubelet.log"] = LogFileData{
|
||||
Name: "kubelet.log",
|
||||
JournalctlCommand: []string{"-u", unitName},
|
||||
}
|
||||
cmdArgs = append(cmdArgs,
|
||||
"--kubelet-cgroups=/kubelet.slice",
|
||||
"--cgroup-root=/",
|
||||
)
|
||||
|
||||
kc.KubeletCgroups = "/kubelet.slice"
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "kubelet-cgroups")
|
||||
} else {
|
||||
cmdArgs = append(cmdArgs, builder.GetKubeletServerBin())
|
||||
cmdArgs = append(cmdArgs,
|
||||
// TODO(random-liu): Get rid of this docker specific thing.
|
||||
"--runtime-cgroups=/docker-daemon",
|
||||
"--kubelet-cgroups=/kubelet",
|
||||
"--cgroup-root=/",
|
||||
"--system-cgroups=/system",
|
||||
)
|
||||
// TODO(random-liu): Get rid of this docker specific thing.
|
||||
cmdArgs = append(cmdArgs, "--runtime-cgroups=/docker-daemon")
|
||||
|
||||
kc.KubeletCgroups = "/kubelet"
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "kubelet-cgroups")
|
||||
|
||||
kc.SystemCgroups = "/system"
|
||||
kubeletConfigFlags = append(kubeletConfigFlags, "system-cgroups")
|
||||
}
|
||||
cmdArgs = append(cmdArgs,
|
||||
"--kubeconfig", kubeconfigPath,
|
||||
"--address", "0.0.0.0",
|
||||
"--port", kubeletPort,
|
||||
"--read-only-port", kubeletReadOnlyPort,
|
||||
"--root-dir", KubeletRootDirectory,
|
||||
"--volume-stats-agg-period", "10s", // Aggregate volumes frequently so tests don't need to wait as long
|
||||
"--allow-privileged", "true",
|
||||
"--serialize-image-pulls", "false",
|
||||
"--pod-manifest-path", manifestPath,
|
||||
"--file-check-frequency", "10s", // Check file frequently so tests won't wait too long
|
||||
"--docker-disable-shared-pid=false",
|
||||
// Assign a fixed CIDR to the node because there is no node controller.
|
||||
//
|
||||
// Note: this MUST be in sync with with the IP in
|
||||
// - cluster/gce/config-test.sh and
|
||||
// - test/e2e_node/conformance/run_test.sh.
|
||||
"--pod-cidr", "10.100.0.0/24",
|
||||
"--eviction-pressure-transition-period", "30s",
|
||||
// Apply test framework feature gates by default. This could also be overridden
|
||||
// by kubelet-flags.
|
||||
"--feature-gates", framework.TestContext.FeatureGates,
|
||||
"--eviction-hard", "memory.available<250Mi,nodefs.available<10%,nodefs.inodesFree<5%", // The hard eviction thresholds.
|
||||
"--eviction-minimum-reclaim", "nodefs.available=5%,nodefs.inodesFree=5%", // The minimum reclaimed resources after eviction.
|
||||
"--v", LOG_VERBOSITY_LEVEL, "--logtostderr",
|
||||
"--allow-privileged", "true",
|
||||
)
|
||||
|
||||
// Apply test framework feature gates by default. This could also be overridden
|
||||
// by kubelet-flags.
|
||||
if len(framework.TestContext.FeatureGates) > 0 {
|
||||
cmdArgs = append(cmdArgs, "--feature-gates", utilflag.NewMapStringBool(&framework.TestContext.FeatureGates).String())
|
||||
kc.FeatureGates = framework.TestContext.FeatureGates
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) {
|
||||
// Enable dynamic config if the feature gate is enabled
|
||||
dynamicConfigDir, err := getDynamicConfigDir()
|
||||
@ -203,6 +300,30 @@ func (e *E2EServices) startKubelet() (*server, error) {
|
||||
cmdArgs = append(cmdArgs, "--hostname-override", framework.TestContext.NodeName)
|
||||
}
|
||||
|
||||
if framework.TestContext.ContainerRuntime != "" {
|
||||
cmdArgs = append(cmdArgs, "--container-runtime", framework.TestContext.ContainerRuntime)
|
||||
}
|
||||
|
||||
if framework.TestContext.ContainerRuntimeEndpoint != "" {
|
||||
cmdArgs = append(cmdArgs, "--container-runtime-endpoint", framework.TestContext.ContainerRuntimeEndpoint)
|
||||
}
|
||||
|
||||
if framework.TestContext.ImageServiceEndpoint != "" {
|
||||
cmdArgs = append(cmdArgs, "--image-service-endpoint", framework.TestContext.ImageServiceEndpoint)
|
||||
}
|
||||
|
||||
// Write config file or flags, depending on whether --generate-kubelet-config-file was provided
|
||||
if genKubeletConfigFile {
|
||||
if err := writeKubeletConfigFile(kc, kubeletConfigPath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// add the flag to load config from a file
|
||||
cmdArgs = append(cmdArgs, "--config", kubeletConfigPath)
|
||||
} else {
|
||||
// generate command line flags from the default config, since --generate-kubelet-config-file was not provided
|
||||
addKubeletConfigFlags(&cmdArgs, kc, kubeletConfigFlags)
|
||||
}
|
||||
|
||||
// Override the default kubelet flags.
|
||||
cmdArgs = append(cmdArgs, kubeletArgs...)
|
||||
|
||||
@ -224,15 +345,70 @@ func (e *E2EServices) startKubelet() (*server, error) {
|
||||
return server, server.start()
|
||||
}
|
||||
|
||||
// createPodManifestDirectory creates pod manifest directory.
|
||||
func createPodManifestDirectory() (string, error) {
|
||||
// addKubeletConfigFlags adds the flags we care about from the provided kubelet configuration object
|
||||
func addKubeletConfigFlags(cmdArgs *[]string, kc *kubeletconfig.KubeletConfiguration, flags []string) {
|
||||
fs := pflag.NewFlagSet("kubelet", pflag.ExitOnError)
|
||||
options.AddKubeletConfigFlags(fs, kc)
|
||||
for _, name := range flags {
|
||||
*cmdArgs = append(*cmdArgs, "--"+name, fs.Lookup(name).Value.String())
|
||||
}
|
||||
}
|
||||
|
||||
// writeKubeletConfigFile writes the kubelet config file based on the args and returns the filename
|
||||
func writeKubeletConfigFile(internal *kubeletconfig.KubeletConfiguration, path string) error {
|
||||
// extract the KubeletConfiguration and convert to versioned
|
||||
versioned := &v1beta1.KubeletConfiguration{}
|
||||
scheme, _, err := scheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := scheme.Convert(internal, versioned, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
// encode
|
||||
encoder, err := newKubeletConfigJSONEncoder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := runtime.Encode(encoder, versioned)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// create the directory, if it does not exist
|
||||
dir := filepath.Dir(path)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
// write the file
|
||||
if err := ioutil.WriteFile(path, data, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newKubeletConfigJSONEncoder() (runtime.Encoder, error) {
|
||||
_, kubeletCodecs, err := scheme.NewSchemeAndCodecs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mediaType := "application/json"
|
||||
info, ok := runtime.SerializerInfoForMediaType(kubeletCodecs.SupportedMediaTypes(), mediaType)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported media type %q", mediaType)
|
||||
}
|
||||
return kubeletCodecs.EncoderForVersion(info.Serializer, v1beta1.SchemeGroupVersion), nil
|
||||
}
|
||||
|
||||
// createPodDirectory creates pod directory.
|
||||
func createPodDirectory() (string, error) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get current working directory: %v", err)
|
||||
}
|
||||
path, err := ioutil.TempDir(cwd, "pod-manifest")
|
||||
path, err := ioutil.TempDir(cwd, "static-pods")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create static pod manifest directory: %v", err)
|
||||
return "", fmt.Errorf("failed to create static pod directory: %v", err)
|
||||
}
|
||||
return path, nil
|
||||
}
|
||||
@ -280,6 +456,15 @@ func kubeconfigCWDPath() (string, error) {
|
||||
return filepath.Join(cwd, "kubeconfig"), nil
|
||||
}
|
||||
|
||||
func kubeletConfigCWDPath() (string, error) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get current working directory: %v", err)
|
||||
}
|
||||
// DO NOT name this file "kubelet" - you will overwrite the the kubelet binary and be very confused :)
|
||||
return filepath.Join(cwd, "kubelet-config"), nil
|
||||
}
|
||||
|
||||
// like createKubeconfig, but creates kubeconfig at current-working-directory/kubeconfig
|
||||
// returns a fully-qualified path to the kubeconfig file
|
||||
func createKubeconfigCWD() (string, error) {
|
||||
|
45
vendor/k8s.io/kubernetes/test/e2e_node/services/server.go
generated
vendored
45
vendor/k8s.io/kubernetes/test/e2e_node/services/server.go
generated
vendored
@ -94,51 +94,6 @@ func (s *server) String() string {
|
||||
commandToString(s.startCommand), commandToString(s.killCommand), commandToString(s.restartCommand), s.healthCheckUrls, s.outFilename)
|
||||
}
|
||||
|
||||
// readinessCheck checks whether services are ready via the supplied health
|
||||
// check URLs. Once there is an error in errCh, the function will stop waiting
|
||||
// and return the error.
|
||||
// TODO(random-liu): Move this to util
|
||||
func readinessCheck(name string, urls []string, errCh <-chan error) error {
|
||||
glog.Infof("Running readiness check for service %q", name)
|
||||
endTime := time.Now().Add(*serverStartTimeout)
|
||||
blockCh := make(chan error)
|
||||
defer close(blockCh)
|
||||
for endTime.After(time.Now()) {
|
||||
select {
|
||||
// We *always* want to run the health check if there is no error on the channel.
|
||||
// With systemd, reads from errCh report nil because cmd.Run() waits
|
||||
// on systemd-run, rather than the service process. systemd-run quickly
|
||||
// exits with status 0, causing the channel to be closed with no error. In
|
||||
// this case, you want to wait for the health check to complete, rather
|
||||
// than returning from readinessCheck as soon as the channel is closed.
|
||||
case err, ok := <-errCh:
|
||||
if ok { // The channel is not closed, this is a real error
|
||||
if err != nil { // If there is an error, return it
|
||||
return err
|
||||
}
|
||||
// If not, keep checking readiness.
|
||||
} else { // The channel is closed, this is only a zero value.
|
||||
// Replace the errCh with blockCh to avoid busy loop,
|
||||
// and keep checking readiness.
|
||||
errCh = blockCh
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
ready := true
|
||||
for _, url := range urls {
|
||||
resp, err := http.Head(url)
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
ready = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if ready {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("e2e service %q readiness check timeout %v", name, *serverStartTimeout)
|
||||
}
|
||||
|
||||
// start starts the server by running its commands, monitors it with a health
|
||||
// check, and ensures that it is restarted if applicable.
|
||||
//
|
||||
|
2
vendor/k8s.io/kubernetes/test/e2e_node/services/services.go
generated
vendored
2
vendor/k8s.io/kubernetes/test/e2e_node/services/services.go
generated
vendored
@ -108,7 +108,7 @@ func (e *E2EServices) Stop() {
|
||||
func RunE2EServices() {
|
||||
// Populate global DefaultFeatureGate with value from TestContext.FeatureGates.
|
||||
// This way, statically-linked components see the same feature gate config as the test context.
|
||||
utilfeature.DefaultFeatureGate.Set(framework.TestContext.FeatureGates)
|
||||
utilfeature.DefaultFeatureGate.SetFromMap(framework.TestContext.FeatureGates)
|
||||
e := newE2EServices()
|
||||
if err := e.run(); err != nil {
|
||||
glog.Fatalf("Failed to run e2e services: %v", err)
|
||||
|
48
vendor/k8s.io/kubernetes/test/e2e_node/services/util.go
generated
vendored
48
vendor/k8s.io/kubernetes/test/e2e_node/services/util.go
generated
vendored
@ -17,9 +17,13 @@ limitations under the License.
|
||||
package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// terminationSignals are signals that cause the program to exit in the
|
||||
@ -32,3 +36,47 @@ func waitForTerminationSignal() {
|
||||
signal.Notify(sig, terminationSignals...)
|
||||
<-sig
|
||||
}
|
||||
|
||||
// readinessCheck checks whether services are ready via the supplied health
|
||||
// check URLs. Once there is an error in errCh, the function will stop waiting
|
||||
// and return the error.
|
||||
func readinessCheck(name string, urls []string, errCh <-chan error) error {
|
||||
glog.Infof("Running readiness check for service %q", name)
|
||||
endTime := time.Now().Add(*serverStartTimeout)
|
||||
blockCh := make(chan error)
|
||||
defer close(blockCh)
|
||||
for endTime.After(time.Now()) {
|
||||
select {
|
||||
// We *always* want to run the health check if there is no error on the channel.
|
||||
// With systemd, reads from errCh report nil because cmd.Run() waits
|
||||
// on systemd-run, rather than the service process. systemd-run quickly
|
||||
// exits with status 0, causing the channel to be closed with no error. In
|
||||
// this case, you want to wait for the health check to complete, rather
|
||||
// than returning from readinessCheck as soon as the channel is closed.
|
||||
case err, ok := <-errCh:
|
||||
if ok { // The channel is not closed, this is a real error
|
||||
if err != nil { // If there is an error, return it
|
||||
return err
|
||||
}
|
||||
// If not, keep checking readiness.
|
||||
} else { // The channel is closed, this is only a zero value.
|
||||
// Replace the errCh with blockCh to avoid busy loop,
|
||||
// and keep checking readiness.
|
||||
errCh = blockCh
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
ready := true
|
||||
for _, url := range urls {
|
||||
resp, err := http.Head(url)
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
ready = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if ready {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("e2e service %q readiness check timeout %v", name, *serverStartTimeout)
|
||||
}
|
||||
|
Reference in New Issue
Block a user