Skip to content

Commit

Permalink
Watch for Pebble Notices and send events to charm
Browse files Browse the repository at this point in the history
  • Loading branch information
benhoyt committed Oct 20, 2023
1 parent 6dd3be0 commit 7f047cb
Show file tree
Hide file tree
Showing 16 changed files with 727 additions and 324 deletions.
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ require (
github.com/im7mortal/kmutex v1.0.1
github.com/juju/ansiterm v1.0.0
github.com/juju/blobstore/v3 v3.0.2
github.com/juju/charm/v11 v11.0.2
github.com/juju/charm/v11 v11.1.0
github.com/juju/clock v1.0.3
github.com/juju/cmd/v3 v3.0.13
github.com/juju/collections v1.0.4
Expand Down Expand Up @@ -304,3 +304,5 @@ replace gopkg.in/yaml.v2 => github.com/juju/yaml/v2 v2.0.0
replace github.com/dustin/go-humanize v1.0.0 => github.com/dustin/go-humanize v0.0.0-20141228071148-145fabdb1ab7

replace github.com/hashicorp/raft-boltdb => github.com/juju/raft-boltdb v0.0.0-20200518034108-40b112c917c5

replace github.com/canonical/pebble => github.com/benhoyt/pebble v0.0.0-20231019035037-7b77eb81226d
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.21.5/go.mod h1:VC7JDqsqiwXukYEDjoHh9
github.com/aws/smithy-go v1.14.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ=
github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/benhoyt/pebble v0.0.0-20231019035037-7b77eb81226d h1:l7dzlieux856UJvrn/gnT3mzj1SvIgrw0L1kE9s9FVE=
github.com/benhoyt/pebble v0.0.0-20231019035037-7b77eb81226d/go.mod h1:bROzibw902Vastd13S/H48BrVAjEUKnlRXv3ZIoFcPE=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
Expand All @@ -216,8 +218,6 @@ github.com/canonical/go-flags v0.0.0-20230403090104-105d09a091b8 h1:zGaJEJI9qPVy
github.com/canonical/go-flags v0.0.0-20230403090104-105d09a091b8/go.mod h1:ZZFeR9K9iGgpwOaLYF9PdT44/+lfSJ9sQz3B+SsGsYU=
github.com/canonical/lxd v0.0.0-20230712132802-8d2a42545fd0 h1:1JfA4hOWjPoF18ebpKFWafOWFplCh0jvHhAethmLQFo=
github.com/canonical/lxd v0.0.0-20230712132802-8d2a42545fd0/go.mod h1:BAaklWDYuotKE0eQnwO6NArKc6rEwnTheuOPrtlLBYA=
github.com/canonical/pebble v1.4.0 h1:/NsAdS/vm0eChL9TEw8EUZYJnwLd+QHLa+bplUWe5s4=
github.com/canonical/pebble v1.4.0/go.mod h1:Ore8BG+F6AknKKT6EmtI6EUXISstdcKSwjO5NuXjV6Q=
github.com/canonical/x-go v0.0.0-20230522092633-7947a7587f5b h1:Da2fardddn+JDlVEYtrzBLTtyzoyU3nIS0Cf0GvjmwU=
github.com/canonical/x-go v0.0.0-20230522092633-7947a7587f5b/go.mod h1:upTK9n6rlqITN9rCN69hdreI37dRDFUk2thlGGD5Cg8=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
Expand Down Expand Up @@ -747,8 +747,8 @@ github.com/juju/ansiterm v1.0.0 h1:gmMvnZRq7JZJx6jkfSq9/+2LMrVEwGwt7UR6G+lmDEg=
github.com/juju/ansiterm v1.0.0/go.mod h1:PyXUpnI3olx3bsPcHt98FGPX/KCFZ1Fi+hw1XLI6384=
github.com/juju/blobstore/v3 v3.0.2 h1:roZ4YBuZYmWId6y/6ZLQSAMmNlHOclHD8PQAMOQer6E=
github.com/juju/blobstore/v3 v3.0.2/go.mod h1:NXEgMhrVH5744/zLfSkzsySlDQUpCgzvcNxjJJhICko=
github.com/juju/charm/v11 v11.0.2 h1:qVcrG9X5fTN++aBfM4QwzOQRd6h31degr3vD2fTgjxs=
github.com/juju/charm/v11 v11.0.2/go.mod h1:Mge5Ko3pPgocmk4v1pQgmBhF8BuBLGTCFu3jq83JvHk=
github.com/juju/charm/v11 v11.1.0 h1:YTvFRugIhRMAe4z6Vr7Acw9oKnJBNfpwN9yTOqJv3r0=
github.com/juju/charm/v11 v11.1.0/go.mod h1:Mge5Ko3pPgocmk4v1pQgmBhF8BuBLGTCFu3jq83JvHk=
github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA=
github.com/juju/clock v0.0.0-20220202072423-1b0f830854c4/go.mod h1:zDZCPSgCJQINeZtQwHx2/cFk4seaBC8Yiqe8V82xiP0=
github.com/juju/clock v0.0.0-20220203021603-d9deb868a28a/go.mod h1:GZ/FY8Cqw3KHG6DwRVPUKbSPTAwyrU28xFi5cqZnLsc=
Expand Down
38 changes: 27 additions & 11 deletions worker/uniter/container/workload.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,16 @@ type WorkloadEventType int
const (
// ReadyEvent is triggered when the container/pebble starts up.
ReadyEvent WorkloadEventType = iota
CustomNoticeEvent
)

// WorkloadEvent contains information about the event type and data associated with
// the event.
type WorkloadEvent struct {
Type WorkloadEventType
WorkloadName string
NoticeType string
NoticeKey string
}

// WorkloadEventCallback is the type used to callback when an event has been processed.
Expand Down Expand Up @@ -151,21 +154,21 @@ func (r *workloadHookResolver) NextOp(
) (operation.Operation, error) {
noOp := func() (operation.Operation, error) {
if localState.Kind == operation.RunHook &&
localState.Hook != nil &&
localState.Hook.Kind == hooks.PebbleReady {
localState.Hook != nil && localState.Hook.Kind.IsWorkload() {
// If we are resuming from an unexpected state, skip hook.
return opFactory.NewSkipHook(*localState.Hook)
}
return nil, resolver.ErrNoOperation
}

switch localState.Kind {
case operation.RunHook:
if localState.Step != operation.Pending ||
localState.Hook == nil ||
localState.Hook.Kind != hooks.PebbleReady {
localState.Hook == nil || !localState.Hook.Kind.IsWorkload() {
break
}
fallthrough

case operation.Continue:
for _, id := range remoteState.WorkloadEvents {
evt, cb, err := r.events.GetWorkloadEvent(id)
Expand All @@ -174,20 +177,32 @@ func (r *workloadHookResolver) NextOp(
} else if err != nil {
return nil, errors.Trace(err)
}
if evt.Type != ReadyEvent {
return nil, errors.NotValidf("workload event type %v", evt.Type)
}

done := func(err error) {
cb(err)
r.events.RemoveWorkloadEvent(id)
if r.eventCompleted != nil {
r.eventCompleted(id)
}
}
op, err := opFactory.NewRunHook(hook.Info{
Kind: hooks.PebbleReady,
WorkloadName: evt.WorkloadName,
})

var op operation.Operation
switch evt.Type {
case CustomNoticeEvent:
op, err = opFactory.NewRunHook(hook.Info{
Kind: hooks.PebbleCustomNotice,
WorkloadName: evt.WorkloadName,
NoticeType: evt.NoticeType,
NoticeKey: evt.NoticeKey,
})
case ReadyEvent:
op, err = opFactory.NewRunHook(hook.Info{
Kind: hooks.PebbleReady,
WorkloadName: evt.WorkloadName,
})
default:
return nil, errors.NotValidf("workload event type %v", evt.Type)
}
if err != nil {
done(err)
return nil, errors.Trace(err)
Expand All @@ -199,6 +214,7 @@ func (r *workloadHookResolver) NextOp(
}
return noOp()
}

return noOp()
}

Expand Down
41 changes: 41 additions & 0 deletions worker/uniter/container/workload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,44 @@ func (s *workloadSuite) TestWorkloadReadyHook(c *gc.C) {
WorkloadName: "test",
})
}

func (s *workloadSuite) TestWorkloadCustomNoticeHook(c *gc.C) {
events := container.NewWorkloadEvents()
expectedErr := errors.Errorf("expected error")
handler := func(err error) {
c.Assert(err, gc.Equals, expectedErr)
}
containerResolver := container.NewWorkloadHookResolver(
loggo.GetLogger("test"),
events,
events.RemoveWorkloadEvent)
localState := resolver.LocalState{
State: operation.State{
Kind: operation.Continue,
Step: operation.Pending,
},
}
remoteState := remotestate.Snapshot{
WorkloadEvents: []string{
events.AddWorkloadEvent(container.WorkloadEvent{
Type: container.CustomNoticeEvent,
WorkloadName: "test",
NoticeType: "custom",
NoticeKey: "example.com/foo",
}, handler),
},
}
opFactory := &mockOperations{}
op, err := containerResolver.NextOp(localState, remoteState, opFactory)
c.Assert(err, jc.ErrorIsNil)
c.Assert(op, gc.NotNil)
op = operation.Unwrap(op)
hookOp, ok := op.(*mockRunHookOp)
c.Assert(ok, jc.IsTrue)
c.Assert(hookOp.hookInfo, gc.DeepEquals, hook.Info{
Kind: "pebble-custom-notice",
WorkloadName: "test",
NoticeType: "custom",
NoticeKey: "example.com/foo",
})
}
14 changes: 14 additions & 0 deletions worker/uniter/hook/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ type Info struct {

// SecretLabel is the secret label to expose to the hook.
SecretLabel string `yaml:"secret-label,omitempty"`

// NoticeType is the Pebble notice type associated with the hook.
NoticeType string `yaml:"notice-type,omitempty"`

// NoticeKey is the Pebble notice key associated with the hook.
NoticeKey string `yaml:"notice-key,omitempty"`
}

// SecretHookRequiresRevision returns true if the hook context needs a secret revision.
Expand Down Expand Up @@ -83,6 +89,14 @@ func (hi Info) Validate() error {
return errors.Errorf("%q hook has a remote unit but no application", hi.Kind)
}
return nil
case hooks.PebbleCustomNotice:
if hi.WorkloadName == "" {
return errors.Errorf("%q hook requires a workload name", hi.Kind)
}
if hi.NoticeType == "" || hi.NoticeKey == "" {
return errors.Errorf("%q hook requires a notice type and key", hi.Kind)
}
return nil
case hooks.PebbleReady:
if hi.WorkloadName == "" {
return errors.Errorf("%q hook requires a workload name", hi.Kind)
Expand Down
6 changes: 6 additions & 0 deletions worker/uniter/hook/hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ var validateTests = []struct {
}, {
hook.Info{Kind: hooks.PebbleReady},
`"pebble-ready" hook requires a workload name`,
}, {
hook.Info{Kind: hooks.PebbleCustomNotice},
`"pebble-custom-notice" hook requires a workload name`,
}, {
hook.Info{Kind: hooks.PebbleCustomNotice, WorkloadName: "test"},
`"pebble-custom-notice" hook requires a notice type and key`,
}, {
hook.Info{Kind: hooks.PreSeriesUpgrade},
`"pre-series-upgrade" hook requires a target base`,
Expand Down
160 changes: 0 additions & 160 deletions worker/uniter/pebblepoller.go

This file was deleted.

Loading

0 comments on commit 7f047cb

Please sign in to comment.