{"id":27243457,"url":"https://github.com/dalee/fuse","last_synced_at":"2025-04-10T20:36:57.572Z","repository":{"id":57526944,"uuid":"73836418","full_name":"Dalee/fuse","owner":"Dalee","description":"⏛ - Kubernetes deploy and management tool (powerful wrapper around kubectl)","archived":false,"fork":false,"pushed_at":"2018-07-05T14:57:15.000Z","size":150,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-27T14:53:59.462Z","etag":null,"topics":["docker-distribution-cleanup","kubectl","kubernetes","kubernetes-deploy","kubernetes-rollback"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dalee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-15T17:05:47.000Z","updated_at":"2020-02-15T06:53:06.000Z","dependencies_parsed_at":"2022-09-07T05:31:04.071Z","dependency_job_id":null,"html_url":"https://github.com/Dalee/fuse","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dalee%2Ffuse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dalee%2Ffuse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dalee%2Ffuse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dalee%2Ffuse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dalee","download_url":"https://codeload.github.com/Dalee/fuse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248290460,"owners_count":21078992,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker-distribution-cleanup","kubectl","kubernetes","kubernetes-deploy","kubernetes-rollback"],"created_at":"2025-04-10T20:36:56.267Z","updated_at":"2025-04-10T20:36:57.564Z","avatar_url":"https://github.com/Dalee.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u0026#9179; — Kubernetes deploy tool\n\n[![Build Status](https://travis-ci.org/Dalee/fuse.svg?branch=master)](https://travis-ci.org/Dalee/fuse)\n[![Coverage](https://codecov.io/gh/Dalee/fuse/branch/master/graph/badge.svg)](https://codecov.io/gh/Dalee/fuse)\n[![Go Report Card](https://goreportcard.com/badge/github.com/Dalee/fuse)](https://goreportcard.com/report/github.com/Dalee/fuse)\n[![codebeat badge](https://codebeat.co/badges/acdf46b7-8265-42b6-96a4-c770969250ef)](https://codebeat.co/projects/github-com-dalee-fuse-master)\n\nSimple, but powerful tool, build around `kubectl` command, great for CI/CD environments.\n\nKey features:\n * `apply` — update cluster configuration with automated undo in case of error\n * `garbage-collect` — detect unused images for each deployment, remove unused images from \n Docker Distribution (Registry). \n \n## Configuration\n\nEnvironment variables:\n * `CLUSTER_CONTEXT` cluster context to use (default, no context, so `kubectl` will use default)\n\nFlags:\n * Cluster context variable can be overridden via global flag: `-c` or `--context`\n * Cluster rollout timeout can be set via `-t` or `--release-timeout` for `apply` command\n * For a `garbage-collect` command, cluster namespace can be changed via `-n, --namespace`, default is `\"default\"`.\n\n## Kubernetes Rollout\n\nApply new configuration to Kubernetes cluster and monitor release delivery.\n\nUsage:\n```\n$ fuse apply -f deployment.yml\n```\n\nHelp screen:\n```\n$ fuse help apply\nApply new configuration to Kubernetes cluster and monitor release delivery\n\nUsage:\n  fuse apply [flags]\n\nFlags:\n  -f, --configuration string       Rollout configuration spec file (yaml), mandatory\n  -t, --rollout-timeout duration   Rollout timeout (default 2m0s)\n\nGlobal Flags:\n  -c, --context string   Override CLUSTER_CONTEXT defined in environment (default \"\")\n```\n\n### What `apply` command do?\n\n  * `fuse` will get all deployments defined in configuration yml file\n  * command `kubectl apply -f deployment.yml` will be executed\n  * for each deployment, [deployment rollout status](https://kubernetes.io/docs/user-guide/deployments/#the-status-of-a-deployment) will be monitored \n  * if status is successful:\n    * fuse will display logs for each created pod for each deployment\n  * if timeout reached: \n    * fuse will display logs from pods attached to each deployment\n    * for each deployment `rollout undo` will be executed, but only if deployment undo history is present\n    \n### Sample output\n\n```\n[14:31:04][Step 4/5] Starting: /data/tc-agent/temp/agentTmp/custom_script427977640370952504\n[14:31:04][Step 4/5] in directory: /data/tc-agent/work/fa28ed608c5de3ce\n[14:31:04][Step 4/5] ===\u003e kubectl apply -f kubernetes.yml -o name\n[14:31:04][Step 4/5] service/example-staging\n[14:31:04][Step 4/5] deployment/example-staging\n[14:31:04][Step 4/5] \n[14:31:04][Step 4/5] ==\u003e Starting rollout monitoring, timeout is 2m0s seconds\n[14:31:09][Step 4/5] ===\u003e kubectl --namespace=default get deployment/example-staging -o yaml\n[14:31:09][Step 4/5] ===\u003e Deployment: default/example-staging, Ready: false, Generation: meta=84 observed=84, Replicas: s=1, u=1, a=1, na=1\n[14:31:14][Step 4/5] ===\u003e kubectl --namespace=default get deployment/example-staging -o yaml\n[14:31:15][Step 4/5] ===\u003e Deployment: default/example-staging, Ready: true, Generation: meta=84 observed=84, Replicas: s=1, u=1, a=1, na=0\n[14:31:15][Step 4/5] ==\u003e Rollout done!\n[14:31:15][Step 4/5] ==\u003e Fetching logs...\n[14:31:15][Step 4/5] ===\u003e kubectl --namespace=default get deployment/example-staging -o yaml\n[14:31:15][Step 4/5] ===\u003e kubectl --namespace=default get pods --selector=app=example-staging -o yaml\n[14:31:15][Step 4/5] ===\u003e kubectl --namespace=default logs --tail=100 example-staging-1567981747-4awvj\n[14:31:15][Step 4/5] ===\u003e Deployment: default/example-staging, Pod: default/example-staging-1567981747-4awvj:\n[14:31:15][Step 4/5] *** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...\n[14:31:15][Step 4/5] *** Running /etc/rc.local...\n[14:31:15][Step 4/5] *** Booting runit daemon...\n[14:31:15][Step 4/5] *** Runit started as PID 14\n[14:31:15][Step 4/5] 2017/03/09 14:31:05 [notice] 23#23: using the \"epoll\" event method\n[14:31:15][Step 4/5] 2017/03/09 14:31:05 [notice] 23#23: nginx/1.11.10\n[14:31:15][Step 4/5] 2017/03/09 14:31:05 [notice] 23#23: built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2) \n[14:31:15][Step 4/5] 2017/03/09 14:31:05 [notice] 23#23: OS: Linux 3.10.0-327.22.2.el7.x86_64\n[14:31:15][Step 4/5] 2017/03/09 14:31:05 [notice] 23#23: getrlimit(RLIMIT_NOFILE): 1048576:1048576\n[14:31:15][Step 4/5] 2017/03/09 14:31:05 [notice] 23#23: start worker processes\n[14:31:15][Step 4/5] 2017/03/09 14:31:05 [notice] 23#23: start worker process 35\n[14:31:15][Step 4/5] [Mar 9 14:31:06.712] info: server started: http://example-staging-1567981747-4awvj:3000\n[14:31:15][Step 4/5] [Mar 9 14:31:06.722] info: Redis connected\n[14:31:15][Step 4/5] [Mar 9 14:31:06.733] info: Redis ready\n[14:31:15][Step 4/5] [Mar 9 14:31:10.197] debug: HEAD http://127.0.0.1:3000/healthcheck\n[14:31:15][Step 4/5] [Mar 9 14:31:10.225] debug: HEAD http://127.0.0.1:3000/healthcheck\n[14:31:15][Step 4/5] [Mar 9 14:31:15.206] debug: HEAD http://127.0.0.1:3000/healthcheck\n[14:31:15][Step 4/5] [Mar 9 14:31:15.219] debug: HEAD http://127.0.0.1:3000/healthcheck\n[14:31:15][Step 4/5] \n[14:31:15][Step 4/5] Process exited with code 0\n```\n\n## Registry Garbage Collection\n\n\u003e Docker Registry access and manipulation is based on our another project [Hitman](https://github.com/Dalee/hitman).\n\nRemove tags from registry not registered within any Kubernetes ReplicaSet.\n\nUsage:\n```\n$ fuse garbage-collect --registry-url=https://registry.example.com:5000/\n```\n\nHelp screen:\n```\n$ fuse help garbage-collect\nRemove tags from registry not registered within Kubernetes ReplicaSet\n\nUsage:\n  fuse garbage-collect [flags]\n\nFlags:\n  -d, --dry-run               Do not execute destructive actions (default \"false\")\n  -i, --ignore-missing        Skip missing images in Registry (default \"false\")\n  -k, --keep-tag stringSlice  Keep tag in Registry, even if it not deployed (default none)\n  -n, --namespace string      Kubernetes namespace to use (default \"default\")\n  -r, --registry-url string   Registry URL (e.g. \"https://registry.example.com:5000/\")\n\nGlobal Flags:\n  -c, --context string   Override CLUSTER_CONTEXT defined in environment (default \"\")\n```\n\n\u003e `-k/--keep-tag` can be provided multiple times, best use case is keep `latest` tag\nin order to speed up build image time.\n\n\n### What `garbage-collect` command do?\n\n  * `fuse` will search all replica sets for given namespace (`default` is by default)\n  * For each replica set `Spec.Template.Spec.Containers[].Image` will be analyzed\n  * For each image repository, full list of tags and image digests will be fetched from provided `registry-url`\n  * If some of repositories absent, error will be thrown, unless `ignore-missing` flag is set\n  * All tags of image not registered within any `ReplicaSet` will be marked for deletion\n  * If `dry-run` is not set, images digests, marked for deletion, will be marked for deletion \n  in Docker Distribution (beware: Registry itself has own `garbage-collect` command)\n\n\u003e Do not forget to schedule [Registry garbage-collect](https://docs.docker.com/registry/garbage-collection/) command\nto perform actual cleanup of deleted images!\n\n### Sample output\n\n```\n[14:37:38][Step 2/5] Starting: /data/tc-agent/temp/agentTmp/custom_script5182791551931646628\n[14:37:38][Step 2/5] in directory: /data/tc-agent/work/2d12da58bb93314d\n[14:37:38][Step 2/5] ==\u003e Fetching repository info...\n[14:37:38][Step 2/5] ===\u003e kubectl --namespace=default get replicasets -o yaml\n[14:37:41][Step 2/5] ==\u003e Found 1 repositories\n[14:37:41][Step 2/5] ===\u003e Repository: acme/example-staging\n[14:37:41][Step 2/5] ===\u003e Deployed: [45 40 41 42 43 44]\n[14:37:41][Step 2/5] ===\u003e Detected as garbage: [34 35 36 37 38 39]\n[14:37:41][Step 2/5]\n[14:37:41][Step 2/5] ==\u003e Clearing up...\n[14:37:41][Step 2/5] ===\u003e Done: acme/example-staging\n[14:37:42][Step 2/5] Process exited with code 0\n```\n\n## Command execution\n\nFor each given selector, find all associated pods and execute provided command \nin each container of each pod.\n\n### Sample output\n\n```\n$ fuse exec --deployments app=acme-staging-wrk,app=acme-staging-adm --command date\n===\u003e kubectl --namespace=default get deployment --selector=app=acme-staging-wrk -o yaml\n===\u003e kubectl --namespace=default get deployment --selector=app=acme-staging-adm -o yaml\n===\u003e kubectl --namespace=default get pods --selector=app=acme-staging-wrk,project=acme-188825 -o yaml\n===\u003e kubectl --namespace=default get pods --selector=app=acme-staging-adm,project=acme-188825 -o yaml\n===\u003e kubectl --namespace=default exec acme-staging-wrk-2842908200-wwlxe --container=acme-staging-wrk date\n===\u003e Pod: default/acme-staging-wrk-2842908200-wwlxe, Container: acme-staging-wrk:\nTue Jul  4 18:49:11 MSK 2017\n\n===\u003e kubectl --namespace=default exec acme-staging-adm-3301714455-wwnu8 --container=acme-staging-adm date\n===\u003e Pod: default/acme-staging-adm-3301714455-wwnu8, Container: acme-staging-adm:\nTue Jul  4 18:49:11 MSK 2017\n```\n\n## Stability\n\nTool currently in pre-release stage, but, it is using heavily to deliver \nreleases to our staging/production cluster. Same applied to `garbage-collect`, \nclean up images is used both at production and staging cluster. \n\nAll interactions with kubectl is covered by tests, but scenarios (commands) are not.\nUse at your own risk.\n\nTool is tested with Kubernetes/kubectl `v1.2.0`\n\n## License\n\nFuse is licensed under the Apache License, Version 2.0. \nSee LICENSE for the full license text.\n\n\u003e [fuse v1.0.1](https://github.com/Dalee/fuse/tree/v1.0.1) is released under \n[Unlicense](http://unlicense.org/)\n\n## Development\n\n * Golang \u003e= 1.7.x\n * [golint](https://github.com/golang/lint)\n * [glide](https://github.com/Masterminds/glide)\n * [gover](https://github.com/modocache/gover)\n * make\n\n\nInstall developer dependencies:\n```\n$ go get -u github.com/modocache/gover \u0026\u0026 \\\ngo get -u github.com/golang/lint/golint \u0026\u0026 \\\ngo get -u github.com/Masterminds/glide \u0026\u0026 \\\ngo get -u github.com/gordonklaus/ineffassign \u0026\u0026 \\\ngo get -u github.com/client9/misspell/cmd/misspell\n```\n\nInstall project dependencies:\n```\n$ glide install\n```\n\nTest and Coverage:\n * `make test` — linting and testing\n * `make coverage` — display coverage information\n * `make format` — gofmt sources\n * `make coverage \u0026\u0026 go tool cover -html=coverage.txt` — see coverage\n\n\n## Useful links, Further reading\n\n* [Kubernetes official site](https://kubernetes.io/)\n* [Official way to deploy applications (helm)](https://github.com/kubernetes/helm)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdalee%2Ffuse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdalee%2Ffuse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdalee%2Ffuse/lists"}