mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-06 16:06:51 +00:00
Merge pull request #26470 from timstclair/node-e2e
Automatic merge from submit-queue Refactor common pod patterns to e2e framework. Priveledged pods could benifit from this as well, but I'll wait for https://github.com/kubernetes/kubernetes/pull/26228 to go in. Prerequisite for https://github.com/kubernetes/kubernetes/issues/26215
This commit is contained in:
@@ -121,13 +121,8 @@ var _ = framework.KubeDescribe("ConfigMap", func() {
|
||||
},
|
||||
}
|
||||
|
||||
assignPodToNode(pod)
|
||||
|
||||
By("Creating the pod")
|
||||
_, err = f.Client.Pods(f.Namespace.Name).Create(pod)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
framework.ExpectNoError(framework.WaitForPodRunningInNamespace(f.Client, pod.Name, f.Namespace.Name))
|
||||
f.CreatePod(pod)
|
||||
|
||||
pollLogs := func() (string, error) {
|
||||
return framework.GetPodLogs(f.Client, f.Namespace.Name, pod.Name, containerName)
|
||||
@@ -184,7 +179,7 @@ var _ = framework.KubeDescribe("ConfigMap", func() {
|
||||
},
|
||||
}
|
||||
|
||||
assignPodToNode(pod)
|
||||
f.MungePodSpec(pod)
|
||||
|
||||
framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{
|
||||
"CONFIG_DATA_1=value-1",
|
||||
@@ -265,7 +260,7 @@ func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64) {
|
||||
pod.Spec.SecurityContext.FSGroup = &fsGroup
|
||||
}
|
||||
|
||||
assignPodToNode(pod)
|
||||
f.MungePodSpec(pod)
|
||||
|
||||
framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{
|
||||
"content of file \"/etc/configmap-volume/data-1\": value-1",
|
||||
@@ -338,7 +333,7 @@ func doConfigMapE2EWithMappings(f *framework.Framework, uid, fsGroup int64) {
|
||||
pod.Spec.SecurityContext.FSGroup = &fsGroup
|
||||
}
|
||||
|
||||
assignPodToNode(pod)
|
||||
f.MungePodSpec(pod)
|
||||
|
||||
framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{
|
||||
"content of file \"/etc/configmap-volume/path/to/data-2\": value-2",
|
||||
|
||||
@@ -21,24 +21,23 @@ import (
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
)
|
||||
|
||||
// One pod one container
|
||||
// TODO: This should be migrated to the e2e framework.
|
||||
type ConformanceContainer struct {
|
||||
Framework *framework.Framework
|
||||
Container api.Container
|
||||
Client *client.Client
|
||||
RestartPolicy api.RestartPolicy
|
||||
Volumes []api.Volume
|
||||
ImagePullSecrets []string
|
||||
NodeName string
|
||||
Namespace string
|
||||
|
||||
podName string
|
||||
}
|
||||
|
||||
func (cc *ConformanceContainer) Create() error {
|
||||
func (cc *ConformanceContainer) Create() {
|
||||
cc.podName = cc.Container.Name + string(util.NewUUID())
|
||||
imagePullSecrets := []api.LocalObjectReference{}
|
||||
for _, s := range cc.ImagePullSecrets {
|
||||
@@ -46,11 +45,9 @@ func (cc *ConformanceContainer) Create() error {
|
||||
}
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: cc.podName,
|
||||
Namespace: cc.Namespace,
|
||||
Name: cc.podName,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
NodeName: cc.NodeName,
|
||||
RestartPolicy: cc.RestartPolicy,
|
||||
Containers: []api.Container{
|
||||
cc.Container,
|
||||
@@ -59,17 +56,15 @@ func (cc *ConformanceContainer) Create() error {
|
||||
ImagePullSecrets: imagePullSecrets,
|
||||
},
|
||||
}
|
||||
|
||||
_, err := cc.Client.Pods(cc.Namespace).Create(pod)
|
||||
return err
|
||||
cc.Framework.CreatePodAsync(pod)
|
||||
}
|
||||
|
||||
func (cc *ConformanceContainer) Delete() error {
|
||||
return cc.Client.Pods(cc.Namespace).Delete(cc.podName, api.NewDeleteOptions(0))
|
||||
return cc.Framework.PodClient().Delete(cc.podName, api.NewDeleteOptions(0))
|
||||
}
|
||||
|
||||
func (cc *ConformanceContainer) IsReady() (bool, error) {
|
||||
pod, err := cc.Client.Pods(cc.Namespace).Get(cc.podName)
|
||||
pod, err := cc.Framework.PodClient().Get(cc.podName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -77,7 +72,7 @@ func (cc *ConformanceContainer) IsReady() (bool, error) {
|
||||
}
|
||||
|
||||
func (cc *ConformanceContainer) GetPhase() (api.PodPhase, error) {
|
||||
pod, err := cc.Client.Pods(cc.Namespace).Get(cc.podName)
|
||||
pod, err := cc.Framework.PodClient().Get(cc.podName)
|
||||
if err != nil {
|
||||
return api.PodUnknown, err
|
||||
}
|
||||
@@ -85,7 +80,7 @@ func (cc *ConformanceContainer) GetPhase() (api.PodPhase, error) {
|
||||
}
|
||||
|
||||
func (cc *ConformanceContainer) GetStatus() (api.ContainerStatus, error) {
|
||||
pod, err := cc.Client.Pods(cc.Namespace).Get(cc.podName)
|
||||
pod, err := cc.Framework.PodClient().Get(cc.podName)
|
||||
if err != nil {
|
||||
return api.ContainerStatus{}, err
|
||||
}
|
||||
@@ -97,7 +92,7 @@ func (cc *ConformanceContainer) GetStatus() (api.ContainerStatus, error) {
|
||||
}
|
||||
|
||||
func (cc *ConformanceContainer) Present() (bool, error) {
|
||||
_, err := cc.Client.Pods(cc.Namespace).Get(cc.podName)
|
||||
_, err := cc.Framework.PodClient().Get(cc.podName)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -36,14 +36,11 @@ var _ = framework.KubeDescribe("Kubelet Container Manager", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
podName = "bin-false" + string(util.NewUUID())
|
||||
pod := &api.Pod{
|
||||
f.CreatePodAsync(&api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: podName,
|
||||
Namespace: f.Namespace.Name,
|
||||
Name: podName,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
// Force the Pod to schedule to the node without a scheduler running
|
||||
NodeName: *nodeName,
|
||||
// Don't restart the Pod since it is expected to exit
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
Containers: []api.Container{
|
||||
@@ -54,15 +51,12 @@ var _ = framework.KubeDescribe("Kubelet Container Manager", func() {
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := f.Client.Pods(f.Namespace.Name).Create(pod)
|
||||
Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
|
||||
})
|
||||
})
|
||||
|
||||
It("should have an error terminated reason", func() {
|
||||
Eventually(func() error {
|
||||
podData, err := f.Client.Pods(f.Namespace.Name).Get(podName)
|
||||
podData, err := f.PodClient().Get(podName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -81,7 +75,7 @@ var _ = framework.KubeDescribe("Kubelet Container Manager", func() {
|
||||
})
|
||||
|
||||
It("should be possible to delete", func() {
|
||||
err := f.Client.Pods(f.Namespace.Name).Delete(podName, &api.DeleteOptions{})
|
||||
err := f.PodClient().Delete(podName, &api.DeleteOptions{})
|
||||
Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -158,7 +158,7 @@ func testDownwardAPI(f *framework.Framework, podName string, env []api.EnvVar, e
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
},
|
||||
}
|
||||
assignPodToNode(pod)
|
||||
f.MungePodSpec(pod)
|
||||
|
||||
f.TestContainerOutputRegexp("downward api env vars", pod, 0, expectations)
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
|
||||
"github.com/golang/glog"
|
||||
. "github.com/onsi/ginkgo"
|
||||
more_reporters "github.com/onsi/ginkgo/reporters"
|
||||
@@ -42,6 +44,11 @@ var e2es *e2eService
|
||||
var prePullImages = flag.Bool("prepull-images", true, "If true, prepull images so image pull failures do not cause test failures.")
|
||||
var junitFileNumber = flag.Int("junit-file-number", 1, "Used to create junit filename - e.g. junit_01.xml.")
|
||||
|
||||
func init() {
|
||||
framework.RegisterCommonFlags()
|
||||
framework.RegisterNodeFlags()
|
||||
}
|
||||
|
||||
func TestE2eNode(t *testing.T) {
|
||||
flag.Parse()
|
||||
|
||||
@@ -67,12 +74,12 @@ var _ = BeforeSuite(func() {
|
||||
if *buildServices {
|
||||
buildGo()
|
||||
}
|
||||
if *nodeName == "" {
|
||||
if framework.TestContext.NodeName == "" {
|
||||
output, err := exec.Command("hostname").CombinedOutput()
|
||||
if err != nil {
|
||||
glog.Fatalf("Could not get node name from hostname %v. Output:\n%s", err, output)
|
||||
}
|
||||
*nodeName = strings.TrimSpace(fmt.Sprintf("%s", output))
|
||||
framework.TestContext.NodeName = strings.TrimSpace(fmt.Sprintf("%s", output))
|
||||
}
|
||||
|
||||
// Pre-pull the images tests depend on so we can fail immediately if there is an image pull issue
|
||||
@@ -89,7 +96,7 @@ var _ = BeforeSuite(func() {
|
||||
maskLocksmithdOnCoreos()
|
||||
|
||||
if *startServices {
|
||||
e2es = newE2eService(*nodeName)
|
||||
e2es = newE2eService(framework.TestContext.NodeName)
|
||||
if err := e2es.start(); err != nil {
|
||||
Fail(fmt.Sprintf("Unable to start node services.\n%v", err))
|
||||
}
|
||||
|
||||
@@ -42,14 +42,11 @@ var _ = framework.KubeDescribe("Kubelet", func() {
|
||||
Context("when scheduling a busybox command in a pod", func() {
|
||||
podName := "busybox-scheduling-" + string(util.NewUUID())
|
||||
It("it should print the output to logs", func() {
|
||||
podClient := f.Client.Pods(f.Namespace.Name)
|
||||
pod := &api.Pod{
|
||||
f.CreatePod(&api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: podName,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
// Force the Pod to schedule to the node without a scheduler running
|
||||
NodeName: *nodeName,
|
||||
// Don't restart the Pod since it is expected to exit
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
Containers: []api.Container{
|
||||
@@ -60,14 +57,10 @@ var _ = framework.KubeDescribe("Kubelet", func() {
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
defer podClient.Delete(pod.Name, nil)
|
||||
_, err := podClient.Create(pod)
|
||||
Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
|
||||
framework.ExpectNoError(f.WaitForPodRunning(pod.Name))
|
||||
})
|
||||
Eventually(func() string {
|
||||
sinceTime := apiUnversioned.NewTime(time.Now().Add(time.Duration(-1 * time.Hour)))
|
||||
rc, err := podClient.GetLogs(podName, &api.PodLogOptions{SinceTime: &sinceTime}).Stream()
|
||||
rc, err := f.PodClient().GetLogs(podName, &api.PodLogOptions{SinceTime: &sinceTime}).Stream()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
@@ -82,15 +75,12 @@ var _ = framework.KubeDescribe("Kubelet", func() {
|
||||
Context("when scheduling a read only busybox container", func() {
|
||||
podName := "busybox-readonly-fs" + string(util.NewUUID())
|
||||
It("it should not write to root filesystem", func() {
|
||||
podClient := f.Client.Pods(f.Namespace.Name)
|
||||
isReadOnly := true
|
||||
pod := &api.Pod{
|
||||
f.CreatePod(&api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: podName,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
// Force the Pod to schedule to the node without a scheduler running
|
||||
NodeName: *nodeName,
|
||||
// Don't restart the Pod since it is expected to exit
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
Containers: []api.Container{
|
||||
@@ -104,12 +94,9 @@ var _ = framework.KubeDescribe("Kubelet", func() {
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
defer podClient.Delete(pod.Name, nil)
|
||||
_, err := podClient.Create(pod)
|
||||
Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
|
||||
})
|
||||
Eventually(func() string {
|
||||
rc, err := podClient.GetLogs(podName, &api.PodLogOptions{}).Stream()
|
||||
rc, err := f.PodClient().GetLogs(podName, &api.PodLogOptions{}).Stream()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
@@ -172,46 +159,38 @@ func createSummaryTestPods(f *framework.Framework, podNamePrefix string, count i
|
||||
podNames.Insert(fmt.Sprintf("%s%v", podNamePrefix, i))
|
||||
}
|
||||
|
||||
var pods []*api.Pod
|
||||
for _, podName := range podNames.List() {
|
||||
createPod(f, podName, []api.Container{
|
||||
{
|
||||
Image: ImageRegistry[busyBoxImage],
|
||||
Command: []string{"sh", "-c", "while true; do echo 'hello world' | tee /test-empty-dir-mnt/file ; sleep 1; done"},
|
||||
Name: podName + containerSuffix,
|
||||
VolumeMounts: []api.VolumeMount{
|
||||
{MountPath: "/test-empty-dir-mnt", Name: volumeNamePrefix},
|
||||
pods = append(pods, &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: podName,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
// Don't restart the Pod since it is expected to exit
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Image: ImageRegistry[busyBoxImage],
|
||||
Command: []string{"sh", "-c", "while true; do echo 'hello world' | tee /test-empty-dir-mnt/file ; sleep 1; done"},
|
||||
Name: podName + containerSuffix,
|
||||
VolumeMounts: []api.VolumeMount{
|
||||
{MountPath: "/test-empty-dir-mnt", Name: volumeNamePrefix},
|
||||
},
|
||||
},
|
||||
},
|
||||
Volumes: []api.Volume{
|
||||
// TODO: Test secret volumes
|
||||
// TODO: Test hostpath volumes
|
||||
{Name: volumeNamePrefix, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
|
||||
},
|
||||
},
|
||||
}, []api.Volume{
|
||||
// TODO: Test secret volumes
|
||||
// TODO: Test hostpath volumes
|
||||
{Name: volumeNamePrefix, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
|
||||
})
|
||||
}
|
||||
f.CreatePods(pods)
|
||||
|
||||
return podNames, volumes
|
||||
}
|
||||
|
||||
func createPod(f *framework.Framework, podName string, containers []api.Container, volumes []api.Volume) {
|
||||
podClient := f.Client.Pods(f.Namespace.Name)
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: podName,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
// Force the Pod to schedule to the node without a scheduler running
|
||||
NodeName: *nodeName,
|
||||
// Don't restart the Pod since it is expected to exit
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
Containers: containers,
|
||||
Volumes: volumes,
|
||||
},
|
||||
}
|
||||
_, err := podClient.Create(pod)
|
||||
Expect(err).To(BeNil(), fmt.Sprintf("Error creating Pod %v", err))
|
||||
framework.ExpectNoError(f.WaitForPodRunning(pod.Name))
|
||||
}
|
||||
|
||||
// Returns pods missing from summary.
|
||||
func podsMissingFromSummary(s stats.Summary, expectedPods sets.String) sets.String {
|
||||
expectedPods = sets.StringKeySet(expectedPods)
|
||||
@@ -244,7 +223,7 @@ func testSummaryMetrics(s stats.Summary, podNamePrefix string) error {
|
||||
nonNilValue = "expected %q to not be nil"
|
||||
nonZeroValue = "expected %q to not be zero"
|
||||
)
|
||||
if s.Node.NodeName != *nodeName {
|
||||
if s.Node.NodeName != framework.TestContext.NodeName {
|
||||
return fmt.Errorf("unexpected node name - %q", s.Node.NodeName)
|
||||
}
|
||||
if s.Node.CPU.UsageCoreNanoSeconds == nil {
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@@ -211,7 +212,7 @@ func createPodAndWaitUntilRunning(c *client.Client, pod *api.Pod) *api.Pod {
|
||||
func createPodWithSpec(c *client.Client, pod *api.Pod) (*api.Pod, error) {
|
||||
// Manually assign pod to node because we don't run the scheduler in node
|
||||
// e2e tests.
|
||||
assignPodToNode(pod)
|
||||
pod.Spec.NodeName = framework.TestContext.NodeName
|
||||
createdPod, err := c.Pods(pod.Namespace).Create(pod)
|
||||
return createdPod, err
|
||||
}
|
||||
|
||||
@@ -97,14 +97,12 @@ while true; do sleep 1; done
|
||||
testContainer.Name = testCase.Name
|
||||
testContainer.Command = []string{"sh", "-c", tmpCmd}
|
||||
terminateContainer := ConformanceContainer{
|
||||
Framework: f,
|
||||
Container: testContainer,
|
||||
Client: f.Client,
|
||||
RestartPolicy: testCase.RestartPolicy,
|
||||
Volumes: testVolumes,
|
||||
NodeName: *nodeName,
|
||||
Namespace: f.Namespace.Name,
|
||||
}
|
||||
Expect(terminateContainer.Create()).To(Succeed())
|
||||
terminateContainer.Create()
|
||||
defer terminateContainer.Delete()
|
||||
|
||||
By("it should get the expected 'RestartCount'")
|
||||
@@ -136,6 +134,7 @@ while true; do sleep 1; done
|
||||
terminationMessage := "DONE"
|
||||
terminationMessagePath := "/dev/termination-log"
|
||||
c := ConformanceContainer{
|
||||
Framework: f,
|
||||
Container: api.Container{
|
||||
Image: ImageRegistry[busyBoxImage],
|
||||
Name: name,
|
||||
@@ -143,14 +142,11 @@ while true; do sleep 1; done
|
||||
Args: []string{fmt.Sprintf("/bin/echo -n %s > %s", terminationMessage, terminationMessagePath)},
|
||||
TerminationMessagePath: terminationMessagePath,
|
||||
},
|
||||
Client: f.Client,
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
NodeName: *nodeName,
|
||||
Namespace: f.Namespace.Name,
|
||||
}
|
||||
|
||||
By("create the container")
|
||||
Expect(c.Create()).To(Succeed())
|
||||
c.Create()
|
||||
defer c.Delete()
|
||||
|
||||
By("wait for the container to succeed")
|
||||
@@ -236,6 +232,7 @@ while true; do sleep 1; done
|
||||
name := "image-pull-test"
|
||||
command := []string{"/bin/sh", "-c", "while true; do sleep 1; done"}
|
||||
container := ConformanceContainer{
|
||||
Framework: f,
|
||||
Container: api.Container{
|
||||
Name: name,
|
||||
Image: testCase.image,
|
||||
@@ -243,10 +240,7 @@ while true; do sleep 1; done
|
||||
// PullAlways makes sure that the image will always be pulled even if it is present before the test.
|
||||
ImagePullPolicy: api.PullAlways,
|
||||
},
|
||||
Client: f.Client,
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
NodeName: *nodeName,
|
||||
Namespace: f.Namespace.Name,
|
||||
}
|
||||
if testCase.secret {
|
||||
secret.Name = "image-pull-secret-" + string(util.NewUUID())
|
||||
@@ -258,7 +252,7 @@ while true; do sleep 1; done
|
||||
}
|
||||
|
||||
By("create the container")
|
||||
Expect(container.Create()).To(Succeed())
|
||||
container.Create()
|
||||
defer container.Delete()
|
||||
|
||||
By("check the pod phase")
|
||||
|
||||
@@ -19,14 +19,13 @@ package e2e_node
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
)
|
||||
|
||||
var kubeletAddress = flag.String("kubelet-address", "http://127.0.0.1:10255", "Host and port of the kubelet")
|
||||
var apiServerAddress = flag.String("api-server-address", "http://127.0.0.1:8080", "Host and port of the api server")
|
||||
var nodeName = flag.String("node-name", "", "Name of the node")
|
||||
|
||||
var buildServices = flag.Bool("build-services", true, "If true, build local executables")
|
||||
var startServices = flag.Bool("start-services", true, "If true, start local node services")
|
||||
var stopServices = flag.Bool("stop-services", true, "If true, stop local node services after running tests")
|
||||
@@ -42,7 +41,3 @@ func NewDefaultFramework(baseName string) *framework.Framework {
|
||||
ClientBurst: 100,
|
||||
}, nil, f)
|
||||
}
|
||||
|
||||
func assignPodToNode(pod *api.Pod) {
|
||||
pod.Spec.NodeName = *nodeName
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user