Skip to content

handle StatusCheck Events implementation logic #2929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ require (
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/fullstorydev/grpcurl v1.3.2 // indirect
github.com/ghodss/yaml v1.0.0
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/protobuf v1.3.2
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fullstorydev/grpcurl v1.3.2 h1:cJKWsBYMocdxXQvgbnhtLG810SL5MhKT4K7BagxRih8=
github.com/fullstorydev/grpcurl v1.3.2/go.mod h1:kvk8xPCXOrwVd9zYdjy+xSOT4YWm6kyth4Y9NMfBns4=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
Expand Down Expand Up @@ -240,6 +242,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jhump/protoreflect v1.5.0 h1:NgpVT+dX71c8hZnxHof2M7QDK7QtohIJ7DYycjnkyfc=
github.com/jhump/protoreflect v1.5.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
Expand Down Expand Up @@ -442,6 +446,7 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jK
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -548,6 +553,7 @@ google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.2 h1:j8RI1yW0SkI+paT6uGwMlrMI/6zwYA6/CFil8rxOzGI=
google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
Expand All @@ -559,11 +565,13 @@ google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.3/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
Expand Down
3 changes: 3 additions & 0 deletions pkg/skaffold/deploy/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ type Resource interface {

// CheckStatus checks resource status
CheckStatus(context.Context, *runcontext.RunContext)

// String represents the string representation of resource
String() string
}
104 changes: 104 additions & 0 deletions pkg/skaffold/event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const (
Complete = "Complete"
Failed = "Failed"
Info = "Information"
Started = "Started"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use "In Progress" instead of "Started" (since In Progress implies that a process has Started) and "Complete" instead of "Succeeded"? That way we have consistency with other events. WDYT?

Copy link
Contributor Author

@tejal29 tejal29 Sep 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I had it "completed" instead of "succeeded" befor to be consistent. But one of the comments from IDE team on the internal doc was to change it to "succeeded" so it goes well with "Failed"

We shd change "completed" to "succeeded" which I can do in another PR.

Regarding "started" to "in progress", there is a delay between when the status check startes and when we receive a first update. Hence I added Started for the first event and subsequent events are "in Progress" with a text update on how many resources are pending

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other alternative is to have a In progress with message "2/2 deployment are still pending" instead of strated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, could we open an issue to change "completed" to "succeeded"?

Personally I'm leaning towards having "In Progress" with the message you said above, just to match, but I don't feel super strongly about it.

Succeeded = "Succeeded"
)

var handler = &eventHandler{}
Expand Down Expand Up @@ -136,6 +138,10 @@ func emptyState(build latest.BuildConfig) proto.State {
DeployState: &proto.DeployState{
Status: NotStarted,
},
StatusCheckState: &proto.StatusCheckState{
Status: NotStarted,
Resources: map[string]string{},
},
ForwardedPorts: make(map[int32]*proto.PortEvent),
}
}
Expand All @@ -160,6 +166,56 @@ func DeployInfoEvent(err error) {
handler.handleDeployEvent(&proto.DeployEvent{Status: Info, Err: err.Error()})
}

func StatusCheckEventSucceeded() {
handler.handleStatusCheckEvent(&proto.StatusCheckEvent{
Status: Succeeded,
})
}

func StatusCheckEventFailed(err error) {
handler.handleStatusCheckEvent(&proto.StatusCheckEvent{
Status: Failed,
Err: err.Error(),
})
}

func StatusCheckEventStarted() {
handler.handleStatusCheckEvent(&proto.StatusCheckEvent{
Status: Started,
})
}

func StatusCheckEventInProgress(s string) {
handler.handleStatusCheckEvent(&proto.StatusCheckEvent{
Status: InProgress,
Message: s,
})
}

func ResourceStatusCheckEventSucceeded(r string) {
handler.handleResourceStatusCheckEvent(&proto.ResourceStatusCheckEvent{
Resource: r,
Status: Succeeded,
Message: Succeeded,
})
}

func ResourceStatusCheckEventFailed(r string, err error) {
handler.handleResourceStatusCheckEvent(&proto.ResourceStatusCheckEvent{
Resource: r,
Status: Failed,
Err: err.Error(),
})
}

func ResourceStatusCheckEventUpdated(r string, status string) {
handler.handleResourceStatusCheckEvent(&proto.ResourceStatusCheckEvent{
Resource: r,
Status: InProgress,
Message: status,
})
}

// DeployComplete notifies that a deployment has completed.
func DeployComplete() {
handler.handleDeployEvent(&proto.DeployEvent{Status: Complete})
Expand Down Expand Up @@ -212,6 +268,22 @@ func (ev *eventHandler) handleDeployEvent(e *proto.DeployEvent) {
})
}

func (ev *eventHandler) handleStatusCheckEvent(e *proto.StatusCheckEvent) {
go ev.handle(&proto.Event{
EventType: &proto.Event_StatusCheckEvent{
StatusCheckEvent: e,
},
})
}

func (ev *eventHandler) handleResourceStatusCheckEvent(e *proto.ResourceStatusCheckEvent) {
go ev.handle(&proto.Event{
EventType: &proto.Event_ResourceStatusCheckEvent{
ResourceStatusCheckEvent: e,
},
})
}

func (ev *eventHandler) handleBuildEvent(e *proto.BuildEvent) {
go ev.handle(&proto.Event{
EventType: &proto.Event_BuildEvent{
Expand Down Expand Up @@ -276,6 +348,38 @@ func (ev *eventHandler) handle(event *proto.Event) {
ev.state.ForwardedPorts[pe.LocalPort] = pe
ev.stateLock.Unlock()
logEntry.Entry = fmt.Sprintf("Forwarding container %s to local port %d", pe.ContainerName, pe.LocalPort)
case *proto.Event_StatusCheckEvent:
se := e.StatusCheckEvent
ev.stateLock.Lock()
ev.state.StatusCheckState.Status = se.Status
ev.stateLock.Unlock()
switch se.Status {
case Started:
logEntry.Entry = "Status check started"
case InProgress:
logEntry.Entry = "Status check in progress"
case Succeeded:
logEntry.Entry = "Status check succeeded"
case Failed:
logEntry.Entry = "Status check failed"
default:
}
case *proto.Event_ResourceStatusCheckEvent:
rse := e.ResourceStatusCheckEvent
rseName := rse.Resource
ev.stateLock.Lock()
ev.state.StatusCheckState.Resources[rseName] = rse.Status
ev.stateLock.Unlock()
switch rse.Status {
case InProgress:
logEntry.Entry = fmt.Sprintf("Resource %s status updated to %s", rseName, rse.Status)
case Succeeded:
logEntry.Entry = fmt.Sprintf("Resource %s status completed successfully", rseName)
case Failed:
logEntry.Entry = fmt.Sprintf("Resource %s status failed with %s", rseName, rse.Err)
default:
}

default:
return
}
Expand Down
84 changes: 84 additions & 0 deletions pkg/skaffold/event/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,90 @@ func TestPortForwarded(t *testing.T) {
wait(t, func() bool { return handler.getState().ForwardedPorts[8080] != nil })
}

func TestStatusCheckEventStarted(t *testing.T) {
defer func() { handler = &eventHandler{} }()

handler = &eventHandler{
state: emptyState(latest.BuildConfig{}),
}

wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted })
StatusCheckEventStarted()
wait(t, func() bool { return handler.getState().StatusCheckState.Status == Started })
}

func TestStatusCheckEventInProgress(t *testing.T) {
defer func() { handler = &eventHandler{} }()

handler = &eventHandler{
state: emptyState(latest.BuildConfig{}),
}

wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted })
StatusCheckEventInProgress("[2/5 deployment(s) are still pending]")
wait(t, func() bool { return handler.getState().StatusCheckState.Status == InProgress })
}

func TestStatusCheckEventSucceeded(t *testing.T) {
defer func() { handler = &eventHandler{} }()

handler = &eventHandler{
state: emptyState(latest.BuildConfig{}),
}

wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted })
StatusCheckEventSucceeded()
wait(t, func() bool { return handler.getState().StatusCheckState.Status == Succeeded })
}

func TestStatusCheckEventFailed(t *testing.T) {
defer func() { handler = &eventHandler{} }()

handler = &eventHandler{
state: emptyState(latest.BuildConfig{}),
}

wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted })
StatusCheckEventFailed(errors.New("one or more deployments failed"))
wait(t, func() bool { return handler.getState().StatusCheckState.Status == Failed })
}

func TestResourceStatusCheckEventUpdated(t *testing.T) {
defer func() { handler = &eventHandler{} }()

handler = &eventHandler{
state: emptyState(latest.BuildConfig{}),
}

wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted })
ResourceStatusCheckEventUpdated("ns:pod/foo", "img pull error")
wait(t, func() bool { return handler.getState().StatusCheckState.Resources["ns:pod/foo"] == InProgress })
}

func TestResourceStatusCheckEventSucceeded(t *testing.T) {
defer func() { handler = &eventHandler{} }()

handler = &eventHandler{
state: emptyState(latest.BuildConfig{}),
}

wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted })
ResourceStatusCheckEventSucceeded("ns:pod/foo")
wait(t, func() bool { return handler.getState().StatusCheckState.Resources["ns:pod/foo"] == Succeeded })
}

func TestResourceStatusCheckEventFailed(t *testing.T) {
defer func() { handler = &eventHandler{} }()

handler = &eventHandler{
state: emptyState(latest.BuildConfig{}),
}

wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted })
ResourceStatusCheckEventFailed("ns:pod/foo", errors.New("one or more deployments failed"))
wait(t, func() bool { return handler.getState().StatusCheckState.Resources["ns:pod/foo"] == Failed })
}

func wait(t *testing.T, condition func() bool) {
ticker := time.NewTicker(10 * time.Millisecond)
defer ticker.Stop()
Expand Down
Loading