Skip to content

Commit

Permalink
Merge pull request #2639 from andrew-leung/manifesteventlayers
Browse files Browse the repository at this point in the history
Add configurable layers in manifest events
  • Loading branch information
dmcgowan authored Aug 28, 2018
2 parents 059f301 + 5e4b81a commit b12bd40
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 18 deletions.
2 changes: 2 additions & 0 deletions cmd/registry/config-cache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ redis:
readtimeout: 10ms
writetimeout: 10ms
notifications:
events:
includereferences: true
endpoints:
- name: local-8082
url: http://localhost:5003/callback
Expand Down
2 changes: 2 additions & 0 deletions cmd/registry/config-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ redis:
readtimeout: 10ms
writetimeout: 10ms
notifications:
events:
includereferences: true
endpoints:
- name: local-5003
url: http://localhost:5003/callback
Expand Down
7 changes: 7 additions & 0 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,8 @@ func (auth Auth) MarshalYAML() (interface{}, error) {

// Notifications configures multiple http endpoints.
type Notifications struct {
// EventConfig is the configuration for the event format that is sent to each Endpoint.
EventConfig Events `yaml:"events,omitempty"`
// Endpoints is a list of http configurations for endpoints that
// respond to webhook notifications. In the future, we may allow other
// kinds of endpoints, such as external queues.
Expand All @@ -571,6 +573,11 @@ type Endpoint struct {
Ignore Ignore `yaml:"ignore"` // ignore event types
}

// Events configures notification events.
type Events struct {
IncludeReferences bool `yaml:"includereferences"` // include reference data in manifest events
}

//Ignore configures mediaTypes and actions of the event, that it won't be propagated
type Ignore struct {
MediaTypes []string `yaml:"mediatypes"` // target media types to ignore
Expand Down
11 changes: 11 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ http:
http2:
disabled: false
notifications:
events:
includereferences: true
endpoints:
- name: alistener
disabled: false
Expand Down Expand Up @@ -857,6 +859,8 @@ settings for the registry.

```none
notifications:
events:
includereferences: true
endpoints:
- name: alistener
disabled: false
Expand Down Expand Up @@ -900,6 +904,13 @@ accept event notifications.
| `mediatypes`|no| A list of target media types to ignore. Events with these target media types are not published to the endpoint. |
| `actions` |no| A list of actions to ignore. Events with these actions are not published to the endpoint. |

### `events`

The `events` structure configures the information provided in event notifications.

| Parameter | Required | Description |
|-----------|----------|-------------------------------------------------------|
| `includereferences` | no | If `true`, include reference information in manifest events. |

## `redis`

Expand Down
2 changes: 1 addition & 1 deletion manifest/schema2/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ type Manifest struct {
Layers []distribution.Descriptor `json:"layers"`
}

// References returnes the descriptors of this manifests references.
// References returns the descriptors of this manifests references.
func (m Manifest) References() []distribution.Descriptor {
references := make([]distribution.Descriptor, 0, 1+len(m.Layers))
references = append(references, m.Config)
Expand Down
29 changes: 17 additions & 12 deletions notifications/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import (
)

type bridge struct {
ub URLBuilder
actor ActorRecord
source SourceRecord
request RequestRecord
sink Sink
ub URLBuilder
includeReferences bool
actor ActorRecord
source SourceRecord
request RequestRecord
sink Sink
}

var _ Listener = &bridge{}
Expand All @@ -31,13 +32,14 @@ type URLBuilder interface {
// using the actor and source. Any urls populated in the events created by
// this bridge will be created using the URLBuilder.
// TODO(stevvooe): Update this to simply take a context.Context object.
func NewBridge(ub URLBuilder, source SourceRecord, actor ActorRecord, request RequestRecord, sink Sink) Listener {
func NewBridge(ub URLBuilder, source SourceRecord, actor ActorRecord, request RequestRecord, sink Sink, includeReferences bool) Listener {
return &bridge{
ub: ub,
actor: actor,
source: source,
request: request,
sink: sink,
ub: ub,
includeReferences: includeReferences,
actor: actor,
source: source,
request: request,
sink: sink,
}
}

Expand Down Expand Up @@ -150,7 +152,7 @@ func (b *bridge) createManifestEvent(action string, repo reference.Named, sm dis
}

// Ensure we have the canonical manifest descriptor here
_, desc, err := distribution.UnmarshalManifest(mt, p)
manifest, desc, err := distribution.UnmarshalManifest(mt, p)
if err != nil {
return nil, err
}
Expand All @@ -159,6 +161,9 @@ func (b *bridge) createManifestEvent(action string, repo reference.Named, sm dis
event.Target.Length = desc.Size
event.Target.Size = desc.Size
event.Target.Digest = desc.Digest
if b.includeReferences {
event.Target.References = append(event.Target.References, manifest.References()...)
}

ref, err := reference.WithDigest(repo, event.Target.Digest)
if err != nil {
Expand Down
26 changes: 22 additions & 4 deletions notifications/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,18 @@ var (
Name: "test",
}
request = RequestRecord{}
m = schema1.Manifest{
Name: repo,
Tag: "latest",
layers = []schema1.FSLayer{
{
BlobSum: "asdf",
},
{
BlobSum: "qwer",
},
}
m = schema1.Manifest{
Name: repo,
Tag: "latest",
FSLayers: layers,
}

sm *schema1.SignedManifest
Expand Down Expand Up @@ -150,7 +159,7 @@ func createTestEnv(t *testing.T, fn testSinkFn) Listener {
payload = sm.Canonical
dgst = digest.FromBytes(payload)

return NewBridge(ub, source, actor, request, fn)
return NewBridge(ub, source, actor, request, fn, true)
}

func checkDeleted(t *testing.T, action string, events ...Event) {
Expand Down Expand Up @@ -195,6 +204,15 @@ func checkCommonManifest(t *testing.T, action string, events ...Event) {
if event.Target.URL != u {
t.Fatalf("incorrect url passed: \n%q != \n%q", event.Target.URL, u)
}

if len(event.Target.References) != len(layers) {
t.Fatalf("unexpected number of references %v != %v", len(event.Target.References), len(layers))
}
for i, targetReference := range event.Target.References {
if targetReference.Digest != layers[i].BlobSum {
t.Fatalf("unexpected reference: %q != %q", targetReference.Digest, layers[i].BlobSum)
}
}
}

func checkCommon(t *testing.T, events ...Event) {
Expand Down
3 changes: 3 additions & 0 deletions notifications/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ type Event struct {

// Tag provides the tag
Tag string `json:"tag,omitempty"`

// References provides the references descriptors.
References []distribution.Descriptor `json:"references,omitempty"`
} `json:"target,omitempty"`

// Request covers the request that generated the event.
Expand Down
2 changes: 1 addition & 1 deletion registry/handlers/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ func (app *App) eventBridge(ctx *Context, r *http.Request) notifications.Listene
}
request := notifications.NewRequestRecord(dcontext.GetRequestID(ctx), r)

return notifications.NewBridge(ctx.urlBuilder, app.events.source, actor, request, app.events.sink)
return notifications.NewBridge(ctx.urlBuilder, app.events.source, actor, request, app.events.sink, app.Config.Notifications.EventConfig.IncludeReferences)
}

// nameRequired returns true if the route requires a name.
Expand Down

0 comments on commit b12bd40

Please sign in to comment.