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

Garbage collection dry run #2063

Merged
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
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
15 changes: 9 additions & 6 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 @@ -144,10 +145,12 @@ func (c *Cluster) collectGarbage(

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)
orphanedResources.stage("delete", res.ResourceID(), "<cluster>", res.IdentifyingBytes())
c.logger.Log("info", "cluster resource not in resources to be synced; deleting", "dry-run", dryRun, "resource", resourceID)
if !dryRun {
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)
c.logger.Log("warning", "resource to be synced has not been updated; skipping", "dry-run", dryRun, "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