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

Rewrite whole files, and thereby deal with multidocs and Lists properly #1137

Merged
merged 3 commits into from
Jun 13, 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
4 changes: 2 additions & 2 deletions cluster/kubernetes/resource/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ func TestLoadSome(t *testing.T) {
if err != nil {
t.Error(err)
}
if len(objs) != len(testfiles.ServiceMap(dir)) {
t.Errorf("expected %d objects from %d files, got result:\n%#v", len(testfiles.ServiceMap(dir)), len(testfiles.Files), objs)
if len(objs) != len(testfiles.ResourceMap) {
t.Errorf("expected %d objects from %d files, got result:\n%#v", len(testfiles.ResourceMap), len(testfiles.Files), objs)
}
}

Expand Down
93 changes: 90 additions & 3 deletions cluster/kubernetes/testfiles/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,36 @@ func WriteTestFiles(dir string) error {

// ----- DATA

// ServiceMap ... given a base path, construct the map representing the services
// given in the test data.
// ResourceMap is the map of resource names to relative paths, which
// must correspond with `Files` below.
var ResourceMap = map[flux.ResourceID]string{
flux.MustParseResourceID("default:deployment/helloworld"): "helloworld-deploy.yaml",
flux.MustParseResourceID("default:deployment/locked-service"): "locked-service-deploy.yaml",
flux.MustParseResourceID("default:deployment/test-service"): "test/test-service-deploy.yaml",
flux.MustParseResourceID("default:deployment/multi-deploy"): "multi.yaml",
flux.MustParseResourceID("default:service/multi-service"): "multi.yaml",
flux.MustParseResourceID("default:deployment/list-deploy"): "list.yaml",
flux.MustParseResourceID("default:service/list-service"): "list.yaml",
}

// ServiceMap ... given a base path, construct the map representing
// the services given in the test data. Must be kept in sync with
// `Files` below. TODO(michael): derive from ResourceMap, or similar.
func ServiceMap(dir string) map[flux.ResourceID][]string {
return map[flux.ResourceID][]string{
flux.MustParseResourceID("default:deployment/helloworld"): []string{filepath.Join(dir, "helloworld-deploy.yaml")},
flux.MustParseResourceID("default:deployment/locked-service"): []string{filepath.Join(dir, "locked-service-deploy.yaml")},
flux.MustParseResourceID("default:deployment/test-service"): []string{filepath.Join(dir, "test/test-service-deploy.yaml")},
flux.MustParseResourceID("default:deployment/multi-deploy"): []string{filepath.Join(dir, "multi.yaml")},
flux.MustParseResourceID("default:deployment/list-deploy"): []string{filepath.Join(dir, "list.yaml")},
}
}

var Files = map[string]string{
"garbage": "This should just be ignored, since it is not YAML",
// Some genuine manifests
"helloworld-deploy.yaml": `apiVersion: extensions/v1beta1
"helloworld-deploy.yaml": `---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: helloworld
Expand Down Expand Up @@ -123,6 +139,77 @@ spec:
ports:
- containerPort: 80
`,
// A multidoc, since we support those now
"multi.yaml": `---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
annotations:
flux.weave.works/automated: "true"
name: multi-deploy
spec:
replicas: 1
template:
metadata:
labels:
app : multi-app
spec:
containers:
- name: hello
image: quay.io/weaveworks/helloworld:master-a000001
imagePullPolicy: Always
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: multi-service
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
selector:
app: multi-app
`,

// A List resource
"list.yaml": `---
apiVersion: v1
kind: List
items:
- apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: list-deploy
spec:
replicas: 1
template:
metadata:
labels:
app : list-app
spec:
containers:
- name: hello
image: quay.io/weaveworks/helloworld:master-a000001
imagePullPolicy: Always
ports:
- containerPort: 80
- apiVersion: v1
kind: Service
metadata:
labels:
app: list-app
name: list-service
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
selector:
app: list-app
`,

// A tricksy chart directory, which should be skipped entirely. Adapted from
// https://github.com/kubernetes/helm/tree/master/docs/examples
Expand Down
4 changes: 2 additions & 2 deletions daemon/daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@ func TestDaemon_NotifyChange(t *testing.T) {
t.Errorf("Sync was not called once, was called %d times", syncCalled)
} else if syncDef == nil {
t.Errorf("Sync was called with a nil syncDef")
} else if len(syncDef.Actions) != len(testfiles.ServiceMap("unimportant")) {
t.Errorf("Sync was not called with the %d actions, was called with: %d", len(testfiles.Files), len(syncDef.Actions))
} else if len(syncDef.Actions) != len(testfiles.ResourceMap) {
t.Errorf("Expected Sync called with %d actions (resources), was called with %d", len(testfiles.ResourceMap), len(syncDef.Actions))
}

// Check that history was written to
Expand Down
59 changes: 30 additions & 29 deletions daemon/loop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/weaveworks/flux/cluster"
"github.com/weaveworks/flux/cluster/kubernetes"
kresource "github.com/weaveworks/flux/cluster/kubernetes/resource"
"github.com/weaveworks/flux/cluster/kubernetes/testfiles"
"github.com/weaveworks/flux/event"
"github.com/weaveworks/flux/git"
"github.com/weaveworks/flux/git/gittest"
Expand Down Expand Up @@ -97,11 +98,11 @@ func TestPullAndSync_InitialSync(t *testing.T) {

syncCalled := 0
var syncDef *cluster.SyncDef
expectedServiceIDs := flux.ResourceIDs{
flux.MustParseResourceID("default:deployment/locked-service"),
flux.MustParseResourceID("default:deployment/test-service"),
flux.MustParseResourceID("default:deployment/helloworld")}
expectedServiceIDs.Sort()
expectedResourceIDs := flux.ResourceIDs{}
for id, _ := range testfiles.ResourceMap {
expectedResourceIDs = append(expectedResourceIDs, id)
}
expectedResourceIDs.Sort()
k8s.SyncFunc = func(def cluster.SyncDef) error {
syncCalled++
syncDef = &def
Expand All @@ -115,8 +116,8 @@ func TestPullAndSync_InitialSync(t *testing.T) {
t.Errorf("Sync was not called once, was called %d times", syncCalled)
} else if syncDef == nil {
t.Errorf("Sync was called with a nil syncDef")
} else if len(syncDef.Actions) != len(expectedServiceIDs) {
t.Errorf("Sync was not called with the %d actions, was called with: %d", len(expectedServiceIDs)*2, len(syncDef.Actions))
} else if len(syncDef.Actions) != len(expectedResourceIDs) {
t.Errorf("Sync was not called with %d actions (resources), was called with %d", len(expectedResourceIDs), len(syncDef.Actions))
}

// The emitted event has all service ids
Expand All @@ -128,10 +129,10 @@ func TestPullAndSync_InitialSync(t *testing.T) {
} else if es[0].Type != event.EventSync {
t.Errorf("Unexpected event type: %#v", es[0])
} else {
gotServiceIDs := es[0].ServiceIDs
flux.ResourceIDs(gotServiceIDs).Sort()
if !reflect.DeepEqual(gotServiceIDs, []flux.ResourceID(expectedServiceIDs)) {
t.Errorf("Unexpected event service ids: %#v, expected: %#v", gotServiceIDs, expectedServiceIDs)
gotResourceIDs := es[0].ServiceIDs
flux.ResourceIDs(gotResourceIDs).Sort()
if !reflect.DeepEqual(gotResourceIDs, []flux.ResourceID(expectedResourceIDs)) {
t.Errorf("Unexpected event service ids: %#v, expected: %#v", gotResourceIDs, expectedResourceIDs)
}
}
// It creates the tag at HEAD
Expand Down Expand Up @@ -166,11 +167,11 @@ func TestDoSync_NoNewCommits(t *testing.T) {

syncCalled := 0
var syncDef *cluster.SyncDef
expectedServiceIDs := flux.ResourceIDs{
flux.MustParseResourceID("default:deployment/locked-service"),
flux.MustParseResourceID("default:deployment/test-service"),
flux.MustParseResourceID("default:deployment/helloworld")}
expectedServiceIDs.Sort()
expectedResourceIDs := flux.ResourceIDs{}
for id, _ := range testfiles.ResourceMap {
expectedResourceIDs = append(expectedResourceIDs, id)
}
expectedResourceIDs.Sort()
k8s.SyncFunc = func(def cluster.SyncDef) error {
syncCalled++
syncDef = &def
Expand All @@ -186,8 +187,8 @@ func TestDoSync_NoNewCommits(t *testing.T) {
t.Errorf("Sync was not called once, was called %d times", syncCalled)
} else if syncDef == nil {
t.Errorf("Sync was called with a nil syncDef")
} else if len(syncDef.Actions) != len(expectedServiceIDs) {
t.Errorf("Sync was not called with the %d actions, was called with: %d", len(expectedServiceIDs)*2, len(syncDef.Actions))
} else if len(syncDef.Actions) != len(expectedResourceIDs) {
t.Errorf("Sync was not called with %d actions, was called with: %d", len(expectedResourceIDs), len(syncDef.Actions))
}

// The emitted event has no service ids
Expand Down Expand Up @@ -259,11 +260,11 @@ func TestDoSync_WithNewCommit(t *testing.T) {

syncCalled := 0
var syncDef *cluster.SyncDef
expectedServiceIDs := flux.ResourceIDs{
flux.MustParseResourceID("default:deployment/locked-service"),
flux.MustParseResourceID("default:deployment/test-service"),
flux.MustParseResourceID("default:deployment/helloworld")}
expectedServiceIDs.Sort()
expectedResourceIDs := flux.ResourceIDs{}
for id, _ := range testfiles.ResourceMap {
expectedResourceIDs = append(expectedResourceIDs, id)
}
expectedResourceIDs.Sort()
k8s.SyncFunc = func(def cluster.SyncDef) error {
syncCalled++
syncDef = &def
Expand All @@ -277,8 +278,8 @@ func TestDoSync_WithNewCommit(t *testing.T) {
t.Errorf("Sync was not called once, was called %d times", syncCalled)
} else if syncDef == nil {
t.Errorf("Sync was called with a nil syncDef")
} else if len(syncDef.Actions) != len(expectedServiceIDs) {
t.Errorf("Sync was not called with the %d actions, was called with: %d", len(expectedServiceIDs)*2, len(syncDef.Actions))
} else if len(syncDef.Actions) != len(expectedResourceIDs) {
t.Errorf("Sync was not called with %d actions, was called with %d", len(expectedResourceIDs), len(syncDef.Actions))
}

// The emitted event has no service ids
Expand All @@ -290,11 +291,11 @@ func TestDoSync_WithNewCommit(t *testing.T) {
} else if es[0].Type != event.EventSync {
t.Errorf("Unexpected event type: %#v", es[0])
} else {
gotServiceIDs := es[0].ServiceIDs
flux.ResourceIDs(gotServiceIDs).Sort()
gotResourceIDs := es[0].ServiceIDs
flux.ResourceIDs(gotResourceIDs).Sort()
// Event should only have changed service ids
if !reflect.DeepEqual(gotServiceIDs, []flux.ResourceID{flux.MustParseResourceID("default:deployment/helloworld")}) {
t.Errorf("Unexpected event service ids: %#v, expected: %#v", gotServiceIDs, []flux.ResourceID{flux.MustParseResourceID("default/helloworld")})
if !reflect.DeepEqual(gotResourceIDs, []flux.ResourceID{flux.MustParseResourceID("default:deployment/helloworld")}) {
t.Errorf("Unexpected event service ids: %#v, expected: %#v", gotResourceIDs, []flux.ResourceID{flux.MustParseResourceID("default:deployment/helloworld")})
}
}
// It moves the tag
Expand Down
17 changes: 11 additions & 6 deletions release/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,17 @@ func (rc *ReleaseContext) Manifests() cluster.Manifests {
func (rc *ReleaseContext) WriteUpdates(updates []*update.ControllerUpdate) error {
err := func() error {
for _, update := range updates {
fi, err := os.Stat(update.ManifestPath)
manifestBytes, err := ioutil.ReadFile(update.ManifestPath)
if err != nil {
return err
}
if err = ioutil.WriteFile(update.ManifestPath, update.ManifestBytes, fi.Mode()); err != nil {
for _, container := range update.Updates {
manifestBytes, err = rc.manifests.UpdateImage(manifestBytes, update.ResourceID, container.Container, container.Target)
if err != nil {
return err
}
}
if err = ioutil.WriteFile(update.ManifestPath, manifestBytes, os.FileMode(0600)); err != nil {
return err
}
}
Expand Down Expand Up @@ -129,10 +135,9 @@ func (rc *ReleaseContext) WorkloadsForUpdate() (map[flux.ResourceID]*update.Cont
for _, res := range resources {
if wl, ok := res.(resource.Workload); ok {
defined[res.ResourceID()] = &update.ControllerUpdate{
ResourceID: res.ResourceID(),
Resource: wl,
ManifestPath: filepath.Join(rc.repo.Dir(), res.Source()),
ManifestBytes: res.Bytes(),
ResourceID: res.ResourceID(),
Resource: wl,
ManifestPath: filepath.Join(rc.repo.Dir(), res.Source()),
}
}
}
Expand Down
Loading