-
Notifications
You must be signed in to change notification settings - Fork 244
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactors, cleans and moves some resources to the new files. (#4250)
Signed-off-by: mik-dass <mrinald7@gmail.com>
- Loading branch information
Showing
26 changed files
with
1,424 additions
and
1,377 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package kclient | ||
|
||
import ( | ||
"fmt" | ||
"github.com/openshift/odo/pkg/log" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/klog" | ||
"sync" | ||
) | ||
|
||
// We use a mutex here in order to make 100% sure that functions such as CollectEvents | ||
// so that there are no race conditions | ||
var mu sync.Mutex | ||
|
||
const ( | ||
failedEventCount = 5 | ||
) | ||
|
||
// CollectEvents collects events in a Goroutine by manipulating a spinner. | ||
// We don't care about the error (it's usually ran in a go routine), so erroring out is not needed. | ||
func (c *Client) CollectEvents(selector string, events map[string]corev1.Event, spinner *log.Status, quit <-chan int) { | ||
|
||
// Secondly, we will start a go routine for watching for events related to the pod and update our pod status accordingly. | ||
eventWatcher, err := c.KubeClient.CoreV1().Events(c.Namespace).Watch(metav1.ListOptions{}) | ||
if err != nil { | ||
log.Warningf("Unable to watch for events: %s", err) | ||
return | ||
} | ||
defer eventWatcher.Stop() | ||
|
||
// Create an endless loop for collecting | ||
for { | ||
select { | ||
case <-quit: | ||
klog.V(3).Info("Quitting collect events") | ||
return | ||
case val, ok := <-eventWatcher.ResultChan(): | ||
mu.Lock() | ||
if !ok { | ||
log.Warning("Watch channel was closed") | ||
return | ||
} | ||
if e, ok := val.Object.(*corev1.Event); ok { | ||
|
||
// If there are many warning events happening during deployment, let's log them. | ||
if e.Type == "Warning" { | ||
|
||
if e.Count >= failedEventCount { | ||
newEvent := e | ||
(events)[e.Name] = *newEvent | ||
klog.V(3).Infof("Warning Event: Count: %d, Reason: %s, Message: %s", e.Count, e.Reason, e.Message) | ||
// Change the spinner message to show the warning | ||
spinner.WarningStatus(fmt.Sprintf("WARNING x%d: %s", e.Count, e.Reason)) | ||
} | ||
|
||
} | ||
|
||
} else { | ||
log.Warning("Unable to convert object to event") | ||
return | ||
} | ||
mu.Unlock() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package kclient | ||
|
||
import ( | ||
"fmt" | ||
"github.com/openshift/odo/pkg/log" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/watch" | ||
ktesting "k8s.io/client-go/testing" | ||
"strings" | ||
"testing" | ||
time "time" | ||
) | ||
|
||
func fakeEventStatus(podName string, eventWarningMessage string, count int32) *corev1.Event { | ||
return &corev1.Event{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: podName, | ||
}, | ||
Type: "Warning", | ||
Count: count, | ||
Reason: eventWarningMessage, | ||
Message: "Foobar", | ||
} | ||
} | ||
|
||
func TestCollectEvents(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
podName string | ||
eventWarningMessage string | ||
}{ | ||
{ | ||
name: "Case 1: Collect an arbitrary amount of events", | ||
podName: "ruby", | ||
eventWarningMessage: "Fake event warning message", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
|
||
// Create a fake client | ||
fakeClient, fakeClientSet := FakeNew() | ||
fakeEventWatch := watch.NewRaceFreeFake() | ||
podSelector := fmt.Sprintf("deploymentconfig=%s", tt.podName) | ||
|
||
// Create a fake event status / watch reactor for faking the events we are collecting | ||
fakeEvent := fakeEventStatus(tt.podName, tt.eventWarningMessage, 10) | ||
go func(event *corev1.Event) { | ||
fakeEventWatch.Add(event) | ||
}(fakeEvent) | ||
|
||
fakeClientSet.Kubernetes.PrependWatchReactor("events", func(action ktesting.Action) (handled bool, ret watch.Interface, err error) { | ||
return true, fakeEventWatch, nil | ||
}) | ||
|
||
// Create a test spinner / variables / quit variable for the go channel | ||
spinner := log.Spinner("Test spinner") | ||
events := make(map[string]corev1.Event) | ||
quit := make(chan int) | ||
go fakeClient.CollectEvents(podSelector, events, spinner, quit) | ||
|
||
// Sleep in order to make sure we actually collect some events | ||
time.Sleep(2 * time.Second) | ||
close(quit) | ||
|
||
// We make sure to lock in order to prevent race conditions when retrieving the events (since they are a pointer | ||
// by default since we pass in a map) | ||
mu.Lock() | ||
if len(events) == 0 { | ||
t.Errorf("Expected events, got none") | ||
} | ||
mu.Unlock() | ||
|
||
// Collect the first event in the map | ||
var firstEvent corev1.Event | ||
for _, val := range events { | ||
firstEvent = val | ||
} | ||
|
||
if !strings.Contains(firstEvent.Reason, tt.eventWarningMessage) { | ||
t.Errorf("expected warning message: '%s' in event message: '%+v'", tt.eventWarningMessage, firstEvent.Reason) | ||
} | ||
|
||
}) | ||
} | ||
} |
Oops, something went wrong.