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

Commit

Permalink
- added dry-run-garbage-collection arg
Browse files Browse the repository at this point in the history
- added .Values.syncGarbageCollection.dry
  • Loading branch information
Jan Schumacher committed May 24, 2019
1 parent 5e17cd5 commit 9f53771
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 17 deletions.
1 change: 1 addition & 0 deletions chart/flux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ The following tables lists the configurable parameters of the Weave Flux chart a
| `kube.config` | [See values.yaml](/chart/flux/values.yaml#L151-L165) | Override for kubectl default config in the Flux pod(s).
| `prometheus.enabled` | `false` | If enabled, adds prometheus annotations to Flux and helmOperator pod(s)
| `syncGarbageCollection.enabled` | `false` | If enabled, fluxd will delete resources that it created, but are no longer present in git (experimental, see [garbage collection](/site/garbagecollection.md))
| `syncGarbageCollection.dry` | `false` | If enabled, fluxd won't delete any resources, but log the garbage collection output (experimental, see [garbage collection](/site/garbagecollection.md))

Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example:

Expand Down
4 changes: 3 additions & 1 deletion chart/flux/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,10 @@ spec:
- --connect=wss://cloud.weave.works/api/flux
- --token={{ .Values.token }}
{{- end }}
{{- if .Values.syncGarbageCollection.enabled }}
{{- if and .Values.syncGarbageCollection.enabled (not .Values.syncGarbageCollection.dry) }}
- --sync-garbage-collection={{ .Values.syncGarbageCollection.enabled }}
{{- else if .Values.syncGarbageCollection.dry }}
- --sync-garbage-collection-dry={{ .Values.syncGarbageCollection.dry }}
{{- end }}
{{- if .Values.additionalArgs }}
{{ toYaml .Values.additionalArgs | indent 10 }}
Expand Down
1 change: 1 addition & 0 deletions chart/flux/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ prometheus:

syncGarbageCollection:
enabled: false
dry: false

# Add your own init container or uncomment and modify the given example.
initContainers: {}
Expand Down
2 changes: 2 additions & 0 deletions cluster/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ func isAddon(obj k8sObject) bool {
type Cluster struct {
// Do garbage collection when syncing resources
GC bool
// dry run garbage collection without syncing
DryGC bool

client ExtendedClient
applier Applier
Expand Down
20 changes: 13 additions & 7 deletions cluster/kubernetes/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ func (c *Cluster) Sync(syncSet cluster.SyncSet) error {
}
c.muSyncErrors.RUnlock()

if c.GC {
deleteErrs, gcFailure := c.collectGarbage(syncSet, checksums, logger)
if c.GC || c.DryGC {
deleteErrs, gcFailure := c.collectGarbage(syncSet, checksums, logger, c.DryGC)
if gcFailure != nil {
return gcFailure
}
Expand All @@ -129,7 +129,8 @@ func (c *Cluster) Sync(syncSet cluster.SyncSet) error {
func (c *Cluster) collectGarbage(
syncSet cluster.SyncSet,
checksums map[string]string,
logger log.Logger) (cluster.SyncError, error) {
logger log.Logger,
dryRun bool) (cluster.SyncError, error) {

orphanedResources := makeChangeSet()

Expand All @@ -142,12 +143,17 @@ func (c *Cluster) collectGarbage(
actual := res.GetChecksum()
expected, ok := checksums[resourceID]

collectGarbage := !ok && !dryRun
onlyLogging := !ok && dryRun
skipResource := actual != expected
switch {
case !ok: // was not recorded as having been staged for application
c.logger.Log("info", "cluster resource not in resources to be synced; deleting", "resource", resourceID)
case collectGarbage:
c.logger.Log("info", "Garbage-Collection: deleting resources; cluster resource not in resources to be synced", "resource", resourceID)
orphanedResources.stage("delete", res.ResourceID(), "<cluster>", res.IdentifyingBytes())
case actual != expected:
c.logger.Log("warning", "resource to be synced has not been updated; skipping", "resource", resourceID)
case onlyLogging: // was not recorded as having been staged for application
c.logger.Log("info", "Garbage-Collection: dry-run, no deletion; cluster resource not in resources to be synced", "resource", resourceID)
case skipResource:
c.logger.Log("warning", "Garbage-Collection: resource to be synced has not been updated; skipping", "resource", resourceID)
continue
default:
// The checksum is the same, indicating that it was
Expand Down
17 changes: 17 additions & 0 deletions cluster/kubernetes/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,23 @@ metadata:
test(t, kube, "", "", false)
})

t.Run("sync adds and GCs dry run", func(t *testing.T) {
kube, _, cancel := setup(t)
defer cancel()

// without GC on, resources persist if they are not mentioned in subsequent syncs.
test(t, kube, "", "", false)
test(t, kube, ns1+defs1, ns1+defs1, false)
test(t, kube, ns1+defs1+defs2, ns1+defs1+defs2, false)
test(t, kube, ns3+defs3, ns1+defs1+defs2+ns3+defs3, false)

// with GC dry run the collect garbage routine is running but only logging results with out collecting any resources
kube.DryGC = true
test(t, kube, ns1+defs2+ns3+defs3, ns1+defs1+defs2+ns3+defs3, false)
test(t, kube, ns1+defs1+defs2, ns1+defs1+defs2+ns3+defs3, false)
test(t, kube, "", ns1+defs1+defs2+ns3+defs3, false)
})

t.Run("sync won't incorrectly delete non-namespaced resources", func(t *testing.T) {
kube, _, cancel := setup(t)
defer cancel()
Expand Down
20 changes: 11 additions & 9 deletions cmd/fluxd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func main() {
// syncing
syncInterval = fs.Duration("sync-interval", 5*time.Minute, "apply config in git to cluster at least this often, even if there are no new commits")
syncGC = fs.Bool("sync-garbage-collection", false, "experimental; delete resources that were created by fluxd, but are no longer in the git repo")
dryGC = fs.Bool("sync-garbage-collection-dry", false, "experimental; only log what would be garbage collected, rather than deleting. Implies --sync-garbage-collection")

// registry
memcachedHostname = fs.String("memcached-hostname", "memcached", "hostname for memcached service.")
Expand Down Expand Up @@ -370,6 +371,7 @@ func main() {
allowedNamespaces := append(*k8sNamespaceWhitelist, *k8sAllowNamespace...)
k8sInst := kubernetes.NewCluster(client, kubectlApplier, sshKeyRing, logger, allowedNamespaces, *registryExcludeImage)
k8sInst.GC = *syncGC
k8sInst.DryGC = *dryGC

if err := k8sInst.Ping(); err != nil {
logger.Log("ping", err)
Expand Down Expand Up @@ -485,15 +487,15 @@ func main() {

gitRemote := git.Remote{URL: *gitURL}
gitConfig := git.Config{
Paths: *gitPath,
Branch: *gitBranch,
SyncTag: *gitSyncTag,
NotesRef: *gitNotesRef,
UserName: *gitUser,
UserEmail: *gitEmail,
SigningKey: *gitSigningKey,
SetAuthor: *gitSetAuthor,
SkipMessage: *gitSkipMessage,
Paths: *gitPath,
Branch: *gitBranch,
SyncTag: *gitSyncTag,
NotesRef: *gitNotesRef,
UserName: *gitUser,
UserEmail: *gitEmail,
SigningKey: *gitSigningKey,
SetAuthor: *gitSetAuthor,
SkipMessage: *gitSkipMessage,
}

repo := git.NewRepo(gitRemote, git.PollInterval(*gitPollInterval), git.Timeout(*gitTimeout), git.Branch(*gitBranch))
Expand Down

0 comments on commit 9f53771

Please sign in to comment.