func newCondition(conditionType batch.JobConditionType, reason, message string) batch.JobCondition { return batch.JobCondition{ Type: conditionType, Status: v1.ConditionTrue, LastProbeTime: metav1.Now(), LastTransitionTime: metav1.Now(), Reason: reason, Message: message, } }
// NewDeploymentCondition creates a new deployment condition. func NewDeploymentCondition(condType extensions.DeploymentConditionType, status v1.ConditionStatus, reason, message string) *extensions.DeploymentCondition { return &extensions.DeploymentCondition{ Type: condType, Status: status, LastUpdateTime: metav1.Now(), LastTransitionTime: metav1.Now(), Reason: reason, Message: message, } }
// createBatchPodSequential creats pods back-to-back in sequence. func createBatchPodSequential(f *framework.Framework, pods []*v1.Pod) (time.Duration, []framework.PodLatencyData) { batchStartTime := metav1.Now() e2eLags := make([]framework.PodLatencyData, 0) for _, pod := range pods { create := metav1.Now() f.PodClient().CreateSync(pod) e2eLags = append(e2eLags, framework.PodLatencyData{Name: pod.Name, Latency: metav1.Now().Time.Sub(create.Time)}) } batchLag := metav1.Now().Time.Sub(batchStartTime.Time) sort.Sort(framework.LatencySlice(e2eLags)) return batchLag, e2eLags }
func TestNamespaceStatusStrategy(t *testing.T) { ctx := genericapirequest.NewDefaultContext() if StatusStrategy.NamespaceScoped() { t.Errorf("Namespaces should not be namespace scoped") } if StatusStrategy.AllowCreateOnUpdate() { t.Errorf("Namespaces should not allow create on update") } now := metav1.Now() oldNamespace := &api.Namespace{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "10", DeletionTimestamp: &now}, Spec: api.NamespaceSpec{Finalizers: []api.FinalizerName{"kubernetes"}}, Status: api.NamespaceStatus{Phase: api.NamespaceActive}, } namespace := &api.Namespace{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "9", DeletionTimestamp: &now}, Status: api.NamespaceStatus{Phase: api.NamespaceTerminating}, } StatusStrategy.PrepareForUpdate(ctx, namespace, oldNamespace) if namespace.Status.Phase != api.NamespaceTerminating { t.Errorf("Namespace status updates should allow change of phase: %v", namespace.Status.Phase) } if len(namespace.Spec.Finalizers) != 1 || namespace.Spec.Finalizers[0] != api.FinalizerKubernetes { t.Errorf("PrepareForUpdate should have preserved old finalizers") } errs := StatusStrategy.ValidateUpdate(ctx, namespace, oldNamespace) if len(errs) != 0 { t.Errorf("Unexpected error %v", errs) } if namespace.ResourceVersion != "9" { t.Errorf("Incoming resource version on update should not be mutated") } }
// TestDeletedDeploymentShouldNotCleanupOtherOverlaps ensures that the deletion of // a deployment will not cleanup deployments that overlap with another deployment. func TestDeletedDeploymentShouldNotCleanupOtherOverlaps(t *testing.T) { f := newFixture(t) now := metav1.Now() earlier := metav1.Time{Time: now.Add(-time.Minute)} later := metav1.Time{Time: now.Add(time.Minute)} foo := newDeployment("foo", 1, nil, nil, nil, map[string]string{"foo": "bar"}) foo.CreationTimestamp = earlier foo.DeletionTimestamp = &now bar := newDeployment("bar", 1, nil, nil, nil, map[string]string{"bla": "bla"}) bar.CreationTimestamp = later // Notice this deployment is overlapping with another deployment bar.Annotations = map[string]string{util.OverlapAnnotation: "baz"} f.dLister = append(f.dLister, foo, bar) f.objects = append(f.objects, foo, bar) f.expectUpdateDeploymentStatusAction(foo) f.run(getKey(foo, t)) for _, a := range filterInformerActions(f.client.Actions()) { action, ok := a.(core.UpdateAction) if !ok { continue } d := action.GetObject().(*extensions.Deployment) if d.Name != "bar" { continue } if len(d.Annotations[util.OverlapAnnotation]) == 0 { t.Errorf("overlapping annotation should not be cleaned up for bar: %v", d.Annotations) } } }
// TestSyncOverlappedDeployment ensures that from two overlapping deployments, the older // one will be synced and the newer will be marked as overlapping. Note that in reality it's // not always the older deployment that is the one that works vs the rest but the one which // has the selector unchanged for longer time. func TestSyncOverlappedDeployment(t *testing.T) { f := newFixture(t) now := metav1.Now() later := metav1.Time{Time: now.Add(time.Minute)} foo := newDeployment("foo", 1, nil, nil, nil, map[string]string{"foo": "bar"}) foo.CreationTimestamp = now bar := newDeployment("bar", 1, nil, nil, nil, map[string]string{"foo": "bar", "app": "baz"}) bar.CreationTimestamp = later f.dLister = append(f.dLister, foo, bar) f.objects = append(f.objects, foo, bar) f.expectUpdateDeploymentStatusAction(bar) f.expectCreateRSAction(newReplicaSet(foo, "foo-rs", 1)) f.expectUpdateDeploymentStatusAction(foo) f.expectUpdateDeploymentStatusAction(foo) f.run(getKey(foo, t)) for _, a := range filterInformerActions(f.client.Actions()) { action, ok := a.(core.UpdateAction) if !ok { continue } d, ok := action.GetObject().(*extensions.Deployment) if !ok { continue } if d.Name == "bar" && d.Annotations[util.OverlapAnnotation] != "foo" { t.Errorf("annotations weren't updated for the overlapping deployment: %v", d.Annotations) } } }
func (rc *RouteController) updateNetworkingCondition(nodeName types.NodeName, routeCreated bool) error { var err error for i := 0; i < updateNodeStatusMaxRetries; i++ { // Patch could also fail, even though the chance is very slim. So we still do // patch in the retry loop. currentTime := metav1.Now() if routeCreated { err = nodeutil.SetNodeCondition(rc.kubeClient, nodeName, v1.NodeCondition{ Type: v1.NodeNetworkUnavailable, Status: v1.ConditionFalse, Reason: "RouteCreated", Message: "RouteController created a route", LastTransitionTime: currentTime, }) } else { err = nodeutil.SetNodeCondition(rc.kubeClient, nodeName, v1.NodeCondition{ Type: v1.NodeNetworkUnavailable, Status: v1.ConditionTrue, Reason: "NoRouteCreated", Message: "RouteController failed to create a route", LastTransitionTime: currentTime, }) } if err == nil { return nil } if i == updateNodeStatusMaxRetries || !errors.IsConflict(err) { glog.Errorf("Error updating node %s: %v", nodeName, err) return err } glog.Errorf("Error updating node %s, retrying: %v", nodeName, err) } return err }
// Updates existing pod condition or creates a new one. Sets LastTransitionTime to now if the // status has changed. // Returns true if pod condition has changed or has been added. func UpdatePodCondition(status *PodStatus, condition *PodCondition) bool { condition.LastTransitionTime = metav1.Now() // Try to find this pod condition. conditionIndex, oldCondition := GetPodCondition(status, condition.Type) if oldCondition == nil { // We are adding new pod condition. status.Conditions = append(status.Conditions, *condition) return true } else { // We are updating an existing condition, so we need to check if it has changed. if condition.Status == oldCondition.Status { condition.LastTransitionTime = oldCondition.LastTransitionTime } isEqual := condition.Status == oldCondition.Status && condition.Reason == oldCondition.Reason && condition.Message == oldCondition.Message && condition.LastProbeTime.Equal(oldCondition.LastProbeTime) && condition.LastTransitionTime.Equal(oldCondition.LastTransitionTime) status.Conditions[conditionIndex] = *condition // Return true if one of the fields have changed. return !isEqual } }
func TestNodeConditionsObservedSince(t *testing.T) { now := metav1.Now() observedTime := metav1.NewTime(now.Time.Add(-1 * time.Minute)) testCases := map[string]struct { observedAt nodeConditionsObservedAt period time.Duration now time.Time result []v1.NodeConditionType }{ "in-period": { observedAt: nodeConditionsObservedAt{ v1.NodeMemoryPressure: observedTime.Time, }, period: 2 * time.Minute, now: now.Time, result: []v1.NodeConditionType{v1.NodeMemoryPressure}, }, "out-of-period": { observedAt: nodeConditionsObservedAt{ v1.NodeMemoryPressure: observedTime.Time, }, period: 30 * time.Second, now: now.Time, result: []v1.NodeConditionType{}, }, } for testName, testCase := range testCases { actual := nodeConditionsObservedSince(testCase.observedAt, testCase.period, testCase.now) if !nodeConditionList(actual).Equal(nodeConditionList(testCase.result)) { t.Errorf("Test case: %s, expected: %v, actual: %v", testName, testCase.result, actual) } } }
func TestDoNotDeleteMirrorPods(t *testing.T) { staticPod := getTestPod() staticPod.Annotations = map[string]string{kubetypes.ConfigSourceAnnotationKey: "file"} mirrorPod := getTestPod() mirrorPod.UID = "mirror-12345678" mirrorPod.Annotations = map[string]string{ kubetypes.ConfigSourceAnnotationKey: "api", kubetypes.ConfigMirrorAnnotationKey: "mirror", } // Set the deletion timestamp. mirrorPod.DeletionTimestamp = new(metav1.Time) client := fake.NewSimpleClientset(mirrorPod) m := newTestManager(client) m.podManager.AddPod(staticPod) m.podManager.AddPod(mirrorPod) // Verify setup. assert.True(t, kubepod.IsStaticPod(staticPod), "SetUp error: staticPod") assert.True(t, kubepod.IsMirrorPod(mirrorPod), "SetUp error: mirrorPod") assert.Equal(t, m.podManager.TranslatePodUID(mirrorPod.UID), staticPod.UID) status := getRandomPodStatus() now := metav1.Now() status.StartTime = &now m.SetPodStatus(staticPod, status) m.testSyncBatch() // Expect not to see an delete action. verifyActions(t, m.kubeClient, []core.Action{ core.GetActionImpl{ActionImpl: core.ActionImpl{Verb: "get", Resource: schema.GroupVersionResource{Resource: "pods"}}}, core.UpdateActionImpl{ActionImpl: core.ActionImpl{Verb: "update", Resource: schema.GroupVersionResource{Resource: "pods"}, Subresource: "status"}}, }) }
func TestSyncPastDeadlineJobFinished(t *testing.T) { clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &api.Registry.GroupOrDie(v1.GroupName).GroupVersion}}) manager, sharedInformerFactory := newJobControllerFromClient(clientset, controller.NoResyncPeriodFunc) fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl manager.podStoreSynced = alwaysReady manager.jobStoreSynced = alwaysReady var actual *batch.Job manager.updateHandler = func(job *batch.Job) error { actual = job return nil } job := newJob(1, 1) activeDeadlineSeconds := int64(10) job.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds start := metav1.Unix(metav1.Now().Time.Unix()-15, 0) job.Status.StartTime = &start job.Status.Conditions = append(job.Status.Conditions, newCondition(batch.JobFailed, "DeadlineExceeded", "Job was active longer than specified deadline")) sharedInformerFactory.Jobs().Informer().GetIndexer().Add(job) err := manager.syncJob(getKey(job, t)) if err != nil { t.Errorf("Unexpected error when syncing jobs %v", err) } if len(fakePodControl.Templates) != 0 { t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", 0, len(fakePodControl.Templates)) } if len(fakePodControl.DeletePodName) != 0 { t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", 0, len(fakePodControl.DeletePodName)) } if actual != nil { t.Error("Unexpected job modification") } }
// createBatchPodWithRateControl creates a batch of pods concurrently, uses one goroutine for each creation. // between creations there is an interval for throughput control func createBatchPodWithRateControl(f *framework.Framework, pods []*v1.Pod, interval time.Duration) map[string]metav1.Time { createTimes := make(map[string]metav1.Time) for _, pod := range pods { createTimes[pod.ObjectMeta.Name] = metav1.Now() go f.PodClient().Create(pod) time.Sleep(interval) } return createTimes }
// NewReplicationControllerCondition creates a new replication controller condition. func NewReplicationControllerCondition(condType v1.ReplicationControllerConditionType, status v1.ConditionStatus, reason, msg string) v1.ReplicationControllerCondition { return v1.ReplicationControllerCondition{ Type: condType, Status: status, LastTransitionTime: metav1.Now(), Reason: reason, Message: msg, } }
func TestThresholdsMetGracePeriod(t *testing.T) { now := metav1.Now() hardThreshold := Threshold{ Signal: SignalMemoryAvailable, Operator: OpLessThan, Value: ThresholdValue{ Quantity: quantityMustParse("1Gi"), }, } softThreshold := Threshold{ Signal: SignalMemoryAvailable, Operator: OpLessThan, Value: ThresholdValue{ Quantity: quantityMustParse("2Gi"), }, GracePeriod: 1 * time.Minute, } oldTime := metav1.NewTime(now.Time.Add(-2 * time.Minute)) testCases := map[string]struct { observedAt thresholdsObservedAt now time.Time result []Threshold }{ "empty": { observedAt: thresholdsObservedAt{}, now: now.Time, result: []Threshold{}, }, "hard-threshold-met": { observedAt: thresholdsObservedAt{ hardThreshold: now.Time, }, now: now.Time, result: []Threshold{hardThreshold}, }, "soft-threshold-not-met": { observedAt: thresholdsObservedAt{ softThreshold: now.Time, }, now: now.Time, result: []Threshold{}, }, "soft-threshold-met": { observedAt: thresholdsObservedAt{ softThreshold: oldTime.Time, }, now: now.Time, result: []Threshold{softThreshold}, }, } for testName, testCase := range testCases { actual := thresholdsMetGracePeriod(testCase.observedAt, now.Time) if !thresholdList(actual).Equal(thresholdList(testCase.result)) { t.Errorf("Test case: %s, expected: %v, actual: %v", testName, testCase.result, actual) } } }
// NewReplicaSetCondition creates a new replica set condition. func NewReplicaSetCondition(condType extensions.ReplicaSetConditionType, status v1.ConditionStatus, reason, msg string) extensions.ReplicaSetCondition { return extensions.ReplicaSetCondition{ Type: condType, Status: status, LastTransitionTime: metav1.Now(), Reason: reason, Message: msg, } }
// pastActiveDeadline checks if job has ActiveDeadlineSeconds field set and if it is exceeded. func pastActiveDeadline(job *batch.Job) bool { if job.Spec.ActiveDeadlineSeconds == nil || job.Status.StartTime == nil { return false } now := metav1.Now() start := job.Status.StartTime.Time duration := now.Time.Sub(start) allowedDuration := time.Duration(*job.Spec.ActiveDeadlineSeconds) * time.Second return duration >= allowedDuration }
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta. func FillObjectMetaSystemFields(ctx genericapirequest.Context, meta *metav1.ObjectMeta) { meta.CreationTimestamp = metav1.Now() // allows admission controllers to assign a UID earlier in the request processing // to support tracking resources pending creation. uid, found := genericapirequest.UIDFrom(ctx) if !found { uid = uuid.NewUUID() } meta.UID = uid meta.SelfLink = "" }
func TestSyncDeploymentDontDoAnythingDuringDeletion(t *testing.T) { f := newFixture(t) d := newDeployment("foo", 1, nil, nil, nil, map[string]string{"foo": "bar"}) now := metav1.Now() d.DeletionTimestamp = &now f.dLister = append(f.dLister, d) f.objects = append(f.objects, d) f.expectUpdateDeploymentStatusAction(d) f.run(getKey(d, t)) }
func getTestRunningStatus() v1.PodStatus { containerStatus := v1.ContainerStatus{ Name: testContainerName, ContainerID: testContainerID.String(), } containerStatus.State.Running = &v1.ContainerStateRunning{StartedAt: metav1.Now()} podStatus := v1.PodStatus{ Phase: v1.PodRunning, ContainerStatuses: []v1.ContainerStatus{containerStatus}, } return podStatus }
// tryAcquireOrRenew tries to acquire a leader lease if it is not already acquired, // else it tries to renew the lease if it has already been acquired. Returns true // on success else returns false. func (le *LeaderElector) tryAcquireOrRenew() bool { now := metav1.Now() leaderElectionRecord := rl.LeaderElectionRecord{ HolderIdentity: le.config.Lock.Identity(), LeaseDurationSeconds: int(le.config.LeaseDuration / time.Second), RenewTime: now, AcquireTime: now, } // 1. obtain or create the ElectionRecord oldLeaderElectionRecord, err := le.config.Lock.Get() if err != nil { if !errors.IsNotFound(err) { glog.Errorf("error retrieving resource lock %v: %v", le.config.Lock.Describe(), err) return false } if err = le.config.Lock.Create(leaderElectionRecord); err != nil { glog.Errorf("error initially creating leader election record: %v", err) return false } le.observedRecord = leaderElectionRecord le.observedTime = time.Now() return true } // 2. Record obtained, check the Identity & Time if !reflect.DeepEqual(le.observedRecord, *oldLeaderElectionRecord) { le.observedRecord = *oldLeaderElectionRecord le.observedTime = time.Now() } if le.observedTime.Add(le.config.LeaseDuration).After(now.Time) && oldLeaderElectionRecord.HolderIdentity != le.config.Lock.Identity() { glog.V(4).Infof("lock is held by %v and has not yet expired", oldLeaderElectionRecord.HolderIdentity) return false } // 3. We're going to try to update. The leaderElectionRecord is set to it's default // here. Let's correct it before updating. if oldLeaderElectionRecord.HolderIdentity == le.config.Lock.Identity() { leaderElectionRecord.AcquireTime = oldLeaderElectionRecord.AcquireTime } else { leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions + 1 } // update the lock itself if err = le.config.Lock.Update(leaderElectionRecord); err != nil { glog.Errorf("Failed to update lock: %v", err) return false } le.observedRecord = leaderElectionRecord le.observedTime = time.Now() return true }
// executePreStopHook runs the pre-stop lifecycle hooks if applicable and returns the duration it takes. func (m *kubeGenericRuntimeManager) executePreStopHook(pod *v1.Pod, containerID kubecontainer.ContainerID, containerSpec *v1.Container, gracePeriod int64) int64 { glog.V(3).Infof("Running preStop hook for container %q", containerID.String()) start := metav1.Now() done := make(chan struct{}) go func() { defer close(done) defer utilruntime.HandleCrash() if msg, err := m.runner.Run(containerID, pod, containerSpec, containerSpec.Lifecycle.PreStop); err != nil { glog.Errorf("preStop hook for container %q failed: %v", containerSpec.Name, err) m.generateContainerEvent(containerID, v1.EventTypeWarning, events.FailedPreStopHook, msg) } }() select { case <-time.After(time.Duration(gracePeriod) * time.Second): glog.V(2).Infof("preStop hook for container %q did not complete in %d seconds", containerID, gracePeriod) case <-done: glog.V(3).Infof("preStop hook for container %q completed", containerID) } return int64(metav1.Now().Sub(start.Time).Seconds()) }
// TestActiveDeadlineHandler verifies the active deadline handler functions as expected. func TestActiveDeadlineHandler(t *testing.T) { pods := newTestPods(4) fakeClock := clock.NewFakeClock(time.Now()) podStatusProvider := &mockPodStatusProvider{pods: pods} fakeRecorder := &record.FakeRecorder{} handler, err := newActiveDeadlineHandler(podStatusProvider, fakeRecorder, fakeClock) if err != nil { t.Fatalf("unexpected error: %v", err) } now := metav1.Now() startTime := metav1.NewTime(now.Time.Add(-1 * time.Minute)) // this pod has exceeded its active deadline exceededActiveDeadlineSeconds := int64(30) pods[0].Status.StartTime = &startTime pods[0].Spec.ActiveDeadlineSeconds = &exceededActiveDeadlineSeconds // this pod has not exceeded its active deadline notYetActiveDeadlineSeconds := int64(120) pods[1].Status.StartTime = &startTime pods[1].Spec.ActiveDeadlineSeconds = ¬YetActiveDeadlineSeconds // this pod has no deadline pods[2].Status.StartTime = &startTime pods[2].Spec.ActiveDeadlineSeconds = nil testCases := []struct { pod *v1.Pod expected bool }{{pods[0], true}, {pods[1], false}, {pods[2], false}, {pods[3], false}} for i, testCase := range testCases { if actual := handler.ShouldSync(testCase.pod); actual != testCase.expected { t.Errorf("[%d] ShouldSync expected %#v, got %#v", i, testCase.expected, actual) } actual := handler.ShouldEvict(testCase.pod) if actual.Evict != testCase.expected { t.Errorf("[%d] ShouldEvict.Evict expected %#v, got %#v", i, testCase.expected, actual.Evict) } if testCase.expected { if actual.Reason != reason { t.Errorf("[%d] ShouldEvict.Reason expected %#v, got %#v", i, message, actual.Reason) } if actual.Message != message { t.Errorf("[%d] ShouldEvict.Message expected %#v, got %#v", i, message, actual.Message) } } } }
// NewRollingUpdater creates a RollingUpdater from a client. func NewRollingUpdater(namespace string, rcClient coreclient.ReplicationControllersGetter, podClient coreclient.PodsGetter) *RollingUpdater { updater := &RollingUpdater{ rcClient: rcClient, podClient: podClient, ns: namespace, } // Inject real implementations. updater.scaleAndWait = updater.scaleAndWaitWithScaler updater.getOrCreateTargetController = updater.getOrCreateTargetControllerWithClient updater.getReadyPods = updater.readyPods updater.cleanup = updater.cleanupWithClients updater.nowFn = func() metav1.Time { return metav1.Now() } return updater }
func TestThresholdsFirstObservedAt(t *testing.T) { hardThreshold := Threshold{ Signal: SignalMemoryAvailable, Operator: OpLessThan, Value: ThresholdValue{ Quantity: quantityMustParse("1Gi"), }, } now := metav1.Now() oldTime := metav1.NewTime(now.Time.Add(-1 * time.Minute)) testCases := map[string]struct { thresholds []Threshold lastObservedAt thresholdsObservedAt now time.Time result thresholdsObservedAt }{ "empty": { thresholds: []Threshold{}, lastObservedAt: thresholdsObservedAt{}, now: now.Time, result: thresholdsObservedAt{}, }, "no-previous-observation": { thresholds: []Threshold{hardThreshold}, lastObservedAt: thresholdsObservedAt{}, now: now.Time, result: thresholdsObservedAt{ hardThreshold: now.Time, }, }, "previous-observation": { thresholds: []Threshold{hardThreshold}, lastObservedAt: thresholdsObservedAt{ hardThreshold: oldTime.Time, }, now: now.Time, result: thresholdsObservedAt{ hardThreshold: oldTime.Time, }, }, } for testName, testCase := range testCases { actual := thresholdsFirstObservedAt(testCase.thresholds, testCase.lastObservedAt, testCase.now) if !reflect.DeepEqual(actual, testCase.result) { t.Errorf("Test case: %s, expected: %v, actual: %v", testName, testCase.result, actual) } } }
// DaemonSets not take any actions when being deleted func TestDontDoAnythingIfBeingDeleted(t *testing.T) { podSpec := resourcePodSpec("not-too-much-mem", "75M", "75m") manager, podControl, _ := newTestController() node := newNode("not-too-much-mem", nil) node.Status.Allocatable = allocatableResources("200M", "200m") manager.nodeStore.Add(node) manager.podStore.Indexer.Add(&v1.Pod{ Spec: podSpec, }) ds := newDaemonSet("foo") ds.Spec.Template.Spec = podSpec now := metav1.Now() ds.DeletionTimestamp = &now manager.dsStore.Add(ds) syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0) }
// GetClusterHealthStatus gets the kubernetes cluster health status by requesting "/healthz" func (self *ClusterClient) GetClusterHealthStatus() *federation_v1beta1.ClusterStatus { clusterStatus := federation_v1beta1.ClusterStatus{} currentTime := metav1.Now() newClusterReadyCondition := federation_v1beta1.ClusterCondition{ Type: federation_v1beta1.ClusterReady, Status: v1.ConditionTrue, Reason: "ClusterReady", Message: "/healthz responded with ok", LastProbeTime: currentTime, LastTransitionTime: currentTime, } newClusterNotReadyCondition := federation_v1beta1.ClusterCondition{ Type: federation_v1beta1.ClusterReady, Status: v1.ConditionFalse, Reason: "ClusterNotReady", Message: "/healthz responded without ok", LastProbeTime: currentTime, LastTransitionTime: currentTime, } newNodeOfflineCondition := federation_v1beta1.ClusterCondition{ Type: federation_v1beta1.ClusterOffline, Status: v1.ConditionTrue, Reason: "ClusterNotReachable", Message: "cluster is not reachable", LastProbeTime: currentTime, LastTransitionTime: currentTime, } newNodeNotOfflineCondition := federation_v1beta1.ClusterCondition{ Type: federation_v1beta1.ClusterOffline, Status: v1.ConditionFalse, Reason: "ClusterReachable", Message: "cluster is reachable", LastProbeTime: currentTime, LastTransitionTime: currentTime, } body, err := self.discoveryClient.RESTClient().Get().AbsPath("/healthz").Do().Raw() if err != nil { clusterStatus.Conditions = append(clusterStatus.Conditions, newNodeOfflineCondition) } else { if !strings.EqualFold(string(body), "ok") { clusterStatus.Conditions = append(clusterStatus.Conditions, newClusterNotReadyCondition, newNodeNotOfflineCondition) } else { clusterStatus.Conditions = append(clusterStatus.Conditions, newClusterReadyCondition) } } return &clusterStatus }
func makeEvent(reason, message string, involvedObject v1.ObjectReference) v1.Event { eventTime := metav1.Now() event := v1.Event{ Reason: reason, Message: message, InvolvedObject: involvedObject, Source: v1.EventSource{ Component: "kubelet", Host: "kublet.node1", }, Count: 1, FirstTimestamp: eventTime, LastTimestamp: eventTime, Type: v1.EventTypeNormal, } return event }
// GetContainerLogs uses rkt's GetLogs API to get the logs of the container. // By default, it returns a snapshot of the container log. Set |follow| to true to // stream the log. Set |follow| to false and specify the number of lines (e.g. // "100" or "all") to tail the log. // // TODO(yifan): This doesn't work with lkvm stage1 yet. func (r *Runtime) GetContainerLogs(pod *v1.Pod, containerID kubecontainer.ContainerID, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) error { id, err := parseContainerID(containerID) if err != nil { return err } var since int64 if logOptions.SinceSeconds != nil { t := metav1.Now().Add(-time.Duration(*logOptions.SinceSeconds) * time.Second) since = t.Unix() } if logOptions.SinceTime != nil { since = logOptions.SinceTime.Unix() } getLogsRequest := &rktapi.GetLogsRequest{ PodId: id.uuid, AppName: id.appName, Follow: logOptions.Follow, SinceTime: since, } if logOptions.TailLines != nil { getLogsRequest.Lines = int32(*logOptions.TailLines) } stream, err := r.apisvc.GetLogs(context.Background(), getLogsRequest) if err != nil { glog.Errorf("rkt: Failed to create log stream for pod %q: %v", format.Pod(pod), err) return err } for { log, err := stream.Recv() if err == io.EOF { break } if err != nil { glog.Errorf("rkt: Failed to receive log for pod %q: %v", format.Pod(pod), err) return err } processLines(log.Lines, logOptions, stdout, stderr) } return nil }
func TestNodeConditionsLastObservedAt(t *testing.T) { now := metav1.Now() oldTime := metav1.NewTime(now.Time.Add(-1 * time.Minute)) testCases := map[string]struct { nodeConditions []v1.NodeConditionType lastObservedAt nodeConditionsObservedAt now time.Time result nodeConditionsObservedAt }{ "no-previous-observation": { nodeConditions: []v1.NodeConditionType{v1.NodeMemoryPressure}, lastObservedAt: nodeConditionsObservedAt{}, now: now.Time, result: nodeConditionsObservedAt{ v1.NodeMemoryPressure: now.Time, }, }, "previous-observation": { nodeConditions: []v1.NodeConditionType{v1.NodeMemoryPressure}, lastObservedAt: nodeConditionsObservedAt{ v1.NodeMemoryPressure: oldTime.Time, }, now: now.Time, result: nodeConditionsObservedAt{ v1.NodeMemoryPressure: now.Time, }, }, "old-observation": { nodeConditions: []v1.NodeConditionType{}, lastObservedAt: nodeConditionsObservedAt{ v1.NodeMemoryPressure: oldTime.Time, }, now: now.Time, result: nodeConditionsObservedAt{ v1.NodeMemoryPressure: oldTime.Time, }, }, } for testName, testCase := range testCases { actual := nodeConditionsLastObservedAt(testCase.nodeConditions, testCase.lastObservedAt, testCase.now) if !reflect.DeepEqual(actual, testCase.result) { t.Errorf("Test case: %s, expected: %v, actual: %v", testName, testCase.result, actual) } } }
func TestChangedStatusKeepsStartTime(t *testing.T) { syncer := newTestManager(&fake.Clientset{}) testPod := getTestPod() now := metav1.Now() firstStatus := getRandomPodStatus() firstStatus.StartTime = &now syncer.SetPodStatus(testPod, firstStatus) syncer.SetPodStatus(testPod, getRandomPodStatus()) verifyUpdates(t, syncer, 2) finalStatus := expectPodStatus(t, syncer, testPod) if finalStatus.StartTime.IsZero() { t.Errorf("StartTime should not be zero") } expected := now.Rfc3339Copy() if !finalStatus.StartTime.Equal(expected) { t.Errorf("Expected %v, but got %v", expected, finalStatus.StartTime) } }