Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Add events for container release #1472

Merged
merged 4 commits into from
Nov 8, 2018
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
6 changes: 3 additions & 3 deletions cmd/fluxctl/release_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (opts *controllerReleaseOpts) RunE(cmd *cobra.Command, args []string) error
}

ctx := context.Background()
spec := update.ReleaseSpec{
spec := update.ReleaseImageSpec{
ServiceSpecs: controllers,
ImageSpec: image,
Kind: kind,
Expand Down Expand Up @@ -182,10 +182,10 @@ func (opts *controllerReleaseOpts) RunE(cmd *cobra.Command, args []string) error
return await(ctx, cmd.OutOrStdout(), cmd.OutOrStderr(), opts.API, jobID, !opts.dryRun, opts.verbosity)
}

func promptSpec(out io.Writer, result job.Result, verbosity int) (update.ContainerSpecs, error) {
func promptSpec(out io.Writer, result job.Result, verbosity int) (update.ReleaseContainersSpec, error) {
menu := update.NewMenu(out, result.Result, verbosity)
containerSpecs, err := menu.Run()
return update.ContainerSpecs{
return update.ReleaseContainersSpec{
Kind: update.ReleaseKindExecute,
ContainerSpecs: containerSpecs,
SkipMismatches: false,
Expand Down
12 changes: 6 additions & 6 deletions cmd/fluxctl/release_cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,29 @@ import (
func TestReleaseCommand_CLIConversion(t *testing.T) {
for _, v := range []struct {
args []string
expectedSpec update.ReleaseSpec
expectedSpec update.ReleaseImageSpec
}{
{[]string{"--update-all-images", "--all"}, update.ReleaseSpec{
{[]string{"--update-all-images", "--all"}, update.ReleaseImageSpec{
ServiceSpecs: []update.ResourceSpec{update.ResourceSpecAll},
ImageSpec: update.ImageSpecLatest,
Kind: update.ReleaseKindExecute,
}},
{[]string{"--update-all-images", "--all", "--dry-run"}, update.ReleaseSpec{
{[]string{"--update-all-images", "--all", "--dry-run"}, update.ReleaseImageSpec{
ServiceSpecs: []update.ResourceSpec{update.ResourceSpecAll},
ImageSpec: update.ImageSpecLatest,
Kind: update.ReleaseKindPlan,
}},
{[]string{"--update-image=alpine:latest", "--all"}, update.ReleaseSpec{
{[]string{"--update-image=alpine:latest", "--all"}, update.ReleaseImageSpec{
ServiceSpecs: []update.ResourceSpec{update.ResourceSpecAll},
ImageSpec: "alpine:latest",
Kind: update.ReleaseKindExecute,
}},
{[]string{"--update-all-images", "--controller=deployment/flux"}, update.ReleaseSpec{
{[]string{"--update-all-images", "--controller=deployment/flux"}, update.ReleaseImageSpec{
ServiceSpecs: []update.ResourceSpec{"default:deployment/flux"},
ImageSpec: update.ImageSpecLatest,
Kind: update.ReleaseKindExecute,
}},
{[]string{"--update-all-images", "--all", "--exclude=deployment/test,deployment/yeah"}, update.ReleaseSpec{
{[]string{"--update-all-images", "--all", "--exclude=deployment/test,deployment/yeah"}, update.ReleaseImageSpec{
ServiceSpecs: []update.ResourceSpec{update.ResourceSpecAll},
ImageSpec: update.ImageSpecLatest,
Kind: update.ReleaseKindExecute,
Expand Down
11 changes: 5 additions & 6 deletions daemon/daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func TestDaemon_ListServicesWithOptions(t *testing.T) {

ctx := context.Background()

t.Run("no filter", func (t *testing.T) {
t.Run("no filter", func(t *testing.T) {
s, err := d.ListServicesWithOptions(ctx, v11.ListServicesOptions{})
if err != nil {
t.Fatalf("Error: %s", err.Error())
Expand All @@ -153,7 +153,7 @@ func TestDaemon_ListServicesWithOptions(t *testing.T) {
t.Fatalf("Expected %v but got %v", 2, len(s))
}
})
t.Run("filter id", func (t *testing.T) {
t.Run("filter id", func(t *testing.T) {
s, err := d.ListServicesWithOptions(ctx, v11.ListServicesOptions{
Namespace: "",
Services: []flux.ResourceID{flux.MustParseResourceID(svc)}})
Expand All @@ -165,7 +165,7 @@ func TestDaemon_ListServicesWithOptions(t *testing.T) {
}
})

t.Run("filter id and namespace", func (t *testing.T) {
t.Run("filter id and namespace", func(t *testing.T) {
_, err := d.ListServicesWithOptions(ctx, v11.ListServicesOptions{
Namespace: "foo",
Services: []flux.ResourceID{flux.MustParseResourceID(svc)}})
Expand All @@ -174,7 +174,7 @@ func TestDaemon_ListServicesWithOptions(t *testing.T) {
}
})

t.Run("filter unsupported id kind", func (t *testing.T) {
t.Run("filter unsupported id kind", func(t *testing.T) {
_, err := d.ListServicesWithOptions(ctx, v11.ListServicesOptions{
Namespace: "foo",
Services: []flux.ResourceID{flux.MustParseResourceID("default:unsupportedkind/goodbyeworld")}})
Expand All @@ -184,7 +184,6 @@ func TestDaemon_ListServicesWithOptions(t *testing.T) {
})
}


// When I call list images for a service, it should return images
func TestDaemon_ListImagesWithOptions(t *testing.T) {
d, start, clean, _, _, _ := mockDaemon(t)
Expand Down Expand Up @@ -848,7 +847,7 @@ func (w *wait) ForImageTag(t *testing.T, d *Daemon, service, container, tag stri
func updateImage(ctx context.Context, d *Daemon, t *testing.T) job.ID {
return updateManifest(ctx, t, d, update.Spec{
Type: update.Images,
Spec: update.ReleaseSpec{
Spec: update.ReleaseImageSpec{
Kind: update.ReleaseKindExecute,
ServiceSpecs: []update.ResourceSpec{update.ResourceSpecAll},
ImageSpec: newHelloImage,
Expand Down
29 changes: 27 additions & 2 deletions daemon/loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,30 @@ func (d *Daemon) doSync(logger log.Logger) (retErr error) {

// Interpret some notes as events to send to the upstream
switch n.Spec.Type {
case update.Containers:
spec := n.Spec.Spec.(update.ReleaseContainersSpec)
noteEvents = append(noteEvents, event.Event{
ServiceIDs: n.Result.AffectedResources(),
Type: event.EventRelease,
StartedAt: started,
EndedAt: time.Now().UTC(),
LogLevel: event.LogLevelInfo,
Metadata: &event.ReleaseEventMetadata{
ReleaseEventCommon: event.ReleaseEventCommon{
Revision: commits[i].Revision,
Result: n.Result,
Error: n.Result.Error(),
},
Spec: event.ReleaseSpec{
Type: event.ReleaseContainersSpecType,
ReleaseContainersSpec: &spec,
},
Cause: n.Spec.Cause,
},
})
includes[event.EventRelease] = true
case update.Images:
spec := n.Spec.Spec.(update.ReleaseSpec)
spec := n.Spec.Spec.(update.ReleaseImageSpec)
noteEvents = append(noteEvents, event.Event{
ServiceIDs: n.Result.AffectedResources(),
Type: event.EventRelease,
Expand All @@ -320,7 +342,10 @@ func (d *Daemon) doSync(logger log.Logger) (retErr error) {
Result: n.Result,
Error: n.Result.Error(),
},
Spec: spec,
Spec: event.ReleaseSpec{
Type: event.ReleaseImageSpecType,
ReleaseImageSpec: &spec,
},
Cause: n.Spec.Cause,
},
})
Expand Down
55 changes: 49 additions & 6 deletions event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ func (e Event) String() string {
if len(strImageIDs) == 0 {
strImageIDs = []string{"no image changes"}
}
for _, spec := range metadata.Spec.ServiceSpecs {
if spec == update.ResourceSpecAll {
strServiceIDs = []string{"all services"}
break
if metadata.Spec.Type == "" || metadata.Spec.Type == ReleaseImageSpecType {
for _, spec := range metadata.Spec.ReleaseImageSpec.ServiceSpecs {
if spec == update.ResourceSpecAll {
strServiceIDs = []string{"all services"}
break
}
}
}
if len(strServiceIDs) == 0 {
Expand Down Expand Up @@ -239,11 +241,52 @@ type ReleaseEventCommon struct {
Error string `json:"error,omitempty"`
}

const (
// ReleaseImageSpecType is a type of release spec when there are update.Images
ReleaseImageSpecType = "releaseImageSpecType"
// ReleaseContainersSpecType is a type of release spec when there are update.Containers
ReleaseContainersSpecType = "releaseContainersSpecType"
)

// ReleaseSpec is a spec for images and containers release
type ReleaseSpec struct {
// Type is ReleaseImageSpecType or ReleaseContainersSpecType
// if empty (for previous version), then use ReleaseImageSpecType
Type string
ReleaseImageSpec *update.ReleaseImageSpec
ReleaseContainersSpec *update.ReleaseContainersSpec
}

// UnmarshalJSON for old version of spec (update.ReleaseImageSpec) where Type is empty
func (s *ReleaseSpec) UnmarshalJSON(b []byte) error {
type T ReleaseSpec
t := (*T)(s)
if err := json.Unmarshal(b, t); err != nil {
return err
}

switch t.Type {
case "":
r := &update.ReleaseImageSpec{}
if err := json.Unmarshal(b, r); err != nil {
return err
}
s.Type = ReleaseImageSpecType
s.ReleaseImageSpec = r

case ReleaseImageSpecType, ReleaseContainersSpecType:
// all good
default:
return errors.New("unknown ReleaseSpec type")
}
return nil
}

// ReleaseEventMetadata is the metadata for when service(s) are released
type ReleaseEventMetadata struct {
ReleaseEventCommon
Spec update.ReleaseSpec `json:"spec"`
Cause update.Cause `json:"cause"`
Spec ReleaseSpec `json:"spec"`

This comment was marked as abuse.

Cause update.Cause `json:"cause"`
}

// AutoReleaseEventMetadata is for when service(s) are released
Expand Down
41 changes: 38 additions & 3 deletions event/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

var (
spec = update.ReleaseSpec{
spec = update.ReleaseImageSpec{
ImageSpec: update.ImageSpecLatest,
}
cause = update.Cause{
Expand All @@ -22,7 +22,10 @@ func TestEvent_ParseReleaseMetaData(t *testing.T) {
Type: EventRelease,
Metadata: &ReleaseEventMetadata{
Cause: cause,
Spec: spec,
Spec: ReleaseSpec{
Type: ReleaseImageSpecType,
ReleaseImageSpec: &spec,
},
},
}

Expand All @@ -35,7 +38,7 @@ func TestEvent_ParseReleaseMetaData(t *testing.T) {
}
switch r := e.Metadata.(type) {
case *ReleaseEventMetadata:
if r.Spec.ImageSpec != spec.ImageSpec ||
if r.Spec.ReleaseImageSpec.ImageSpec != spec.ImageSpec ||
r.Cause != cause {
t.Fatal("Release event wasn't marshalled/unmarshalled")
}
Expand All @@ -60,3 +63,35 @@ func TestEvent_ParseNoMetadata(t *testing.T) {
t.Fatal("Hasn't been unmarshalled properly")
}
}

// TestEvent_ParseOldReleaseMetaData makes sure the parsing code can
// handle the older format events recorded against commits.
func TestEvent_ParseOldReleaseMetaData(t *testing.T) {
// A minimal example of an old-style ReleaseEventMetadata. NB it
// must have at least an entry for "spec", since otherwise the
// JSON unmarshaller will not attempt to unparse the spec and
// thereby invoke the specialised UnmarshalJSON.
oldData := `
{
"spec": {
"serviceSpecs": ["<all>"]
}
}
`
var eventData ReleaseEventMetadata
if err := json.Unmarshal([]byte(oldData), &eventData); err != nil {
t.Fatal(err)
}
if eventData.Spec.Type != ReleaseImageSpecType {
t.Error("did not set spec type to ReleaseImageSpecType")
}
if eventData.Spec.ReleaseImageSpec == nil {
t.Error("did not set .ReleaseImageSpec as expected")
}
if eventData.Spec.ReleaseContainersSpec != nil {
t.Error("unexpectedly set .ReleaseContainersSpec")
}
if len(eventData.Spec.ReleaseImageSpec.ServiceSpecs) != 1 {
t.Error("expected service specs of len 1")
}
}
2 changes: 1 addition & 1 deletion http/daemon/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func (s HTTPServer) UpdateImages(w http.ResponseWriter, r *http.Request) {
excludes = append(excludes, s)
}

spec := update.ReleaseSpec{
spec := update.ReleaseImageSpec{
ServiceSpecs: serviceSpecs,
ImageSpec: imageSpec,
Kind: releaseKind,
Expand Down
Loading