{"id":22481765,"url":"https://github.com/riotkit-org/git-clone-controller","last_synced_at":"2025-08-02T16:31:00.961Z","repository":{"id":36972397,"uuid":"480138771","full_name":"riotkit-org/git-clone-controller","owner":"riotkit-org","description":"Provisions Persistent Volumes from GIT","archived":false,"fork":false,"pushed_at":"2023-06-19T06:00:40.000Z","size":254,"stargazers_count":2,"open_issues_count":6,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-19T03:13:24.376Z","etag":null,"topics":["admission-webhook","anarchism","cloud-native","git","git-clone","git-clone-operator","git-operator","helm","jenkins-x","k3s","k8s","k8s-operator","k8s-webhook","kubernetes","openshift","riotkit","tekton"],"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/riotkit-org.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-10T20:59:59.000Z","updated_at":"2022-06-29T09:48:41.000Z","dependencies_parsed_at":"2024-06-19T18:59:55.734Z","dependency_job_id":"5aa66a9d-c870-4fbc-b02a-3de3f33fc13b","html_url":"https://github.com/riotkit-org/git-clone-controller","commit_stats":{"total_commits":99,"total_committers":4,"mean_commits":24.75,"dds":0.5353535353535354,"last_synced_commit":"06537aa3acabc830821343cd76eefad7185d06b2"},"previous_names":["riotkit-org/git-clone-operator"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riotkit-org%2Fgit-clone-controller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riotkit-org%2Fgit-clone-controller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riotkit-org%2Fgit-clone-controller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riotkit-org%2Fgit-clone-controller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/riotkit-org","download_url":"https://codeload.github.com/riotkit-org/git-clone-controller/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228491918,"owners_count":17928719,"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":["admission-webhook","anarchism","cloud-native","git","git-clone","git-clone-operator","git-operator","helm","jenkins-x","k3s","k8s","k8s-operator","k8s-webhook","kubernetes","openshift","riotkit","tekton"],"created_at":"2024-12-06T16:15:18.334Z","updated_at":"2024-12-06T16:15:19.036Z","avatar_url":"https://github.com/riotkit-org.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"GIT clone controller\n====================\n\nMutation webhook handler, injects initContainer with a properly configured `git` container that does a clone or checkout, taking care about permissions.\n\n\nUse cases\n--------\n\n### Mounting static user-data in official images\n\nWith this approach you can still use official application images like Wordpress image without having to maintain your own images\njust to inject a theme, plugins or some other custom files.\n\n### Simple administrative jobs without CI system\n\nSimply clone your scripts repository in your pod workspace, execute script and exit.\n\n### Git clone inside CI job\n\n`git-clone-controller checkout` is a CLI command that could be a replacement of `git clone` and `git checkout`. \nIts advantage is that it is designed to be running automatic: When repository does not exist, it gets cloned, when exists, then updated with remote.\n\n\nSetting up\n----------\n\nUse helm to install git-clone-controller. For helm values please take a look at [values reference](https://github.com/riotkit-org/git-clone-controller/blob/main/helm/git-clone-controller/values.yaml).\n\n```bash\nhelm repo add riotkit-org https://riotkit-org.github.io/helm-of-revolution/\nhelm install my-git-clone-controller riotkit-org/git-clone-controller\n```\n\nExample usage\n-------------\n\nEvery `Pod` labelled with `riotkit.org/git-clone-controller: \"true\"` will be processed by `git-clone-controller`.\n\n`Pod` annotations are the place, where `git-clone-controller` short specification is kept.\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n    name: \"tagged-pod\"\n    labels:\n        # required: only labelled Pods are processed\n        riotkit.org/git-clone-controller: \"true\"\n    annotations:\n        # required: commit/tag/branch\n        git-clone-controller/revision: main\n        # required: http/https url\n        git-clone-controller/url: \"https://github.com/jenkins-x/go-scm\"\n        # required: target path, where the repository should be cloned, should be placed on a shared Volume mount point with other containers in same Pod\n        git-clone-controller/path: /workspace/source\n        # optional: user id (will result in adding `securityContext`), in effect: running `git` as selected user and creating files as selected user\n        git-clone-controller/owner: \"1000\"\n        # optional: group id (will result in adding `securityContext`), same behavior as in \"git-clone-controller/owner\"\n        git-clone-controller/group: \"1000\"\n        # optional: `kind: Secret` name from same namespace as Pod is (if not specified, then global defaults from operator will be taken, or no authorization would be used)\n        git-clone-controller/secretName: git-secrets\n        # optional: entry name in `.data` section of selected `kind: Secret`\n        git-clone-controller/secretTokenKey: jenkins-x\n\n        # optional: entry name in `.data` section, describes the GIT username, defaults to __token__ if not specified\n        #git-clone-controller/secretUsernameKey: username\n\n        # optional: Disable cleaning up untracked and unstaged files (git clean + git reset)\n        # git-clone-controller/cleanWorkspace: \"false\"\nspec:\n    restartPolicy: Never\n    automountServiceAccountToken: false\n    containers:\n        - command:\n              - /bin/sh\n              - \"-c\"\n              - \"find /workspace/source; ls -la /workspace/source\"\n          image: busybox:latest\n          name: test\n          volumeMounts:\n              - mountPath: /workspace/source\n                name: workspace\n    volumes:\n        - name: workspace\n          emptyDir: {}\n          \n    # PERMISSIONS:\n    #  If `git-clone-controller/owner` and `git-clone-controller/group` specified, then `fsGroup` should have same value there\n    #  so the mounted volume would have proper permissions\n    securityContext:\n        fsGroup: 1000\n```\n\n**Running this example:**\n\n```bash\nkubectl delete -f docs/examples/pod-tagged.yaml; kubectl apply -f docs/examples/pod-tagged.yaml\n\n# observe checkout\nkubectl logs -f tagged-pod -c git-checkout\n\n# check the example command that will print list of files and permissions\nkubectl logs -f tagged-pod\n```\n\nBehavior\n--------\n\n| Circumstances                                                      | Behavior                                                              |\n|--------------------------------------------------------------------|-----------------------------------------------------------------------|\n| Pods NOT marked with `riotkit.org/git-clone-controller: \"true\"`    | Do Nothing                                                            |\n| Pods MARKED with `riotkit.org/git-clone-controller: \"true\"`        | Process                                                               |\n| Missing required annotation                                        | Do not schedule that `Pod`                                            |\n| `kind: Secret` was specified, but is invalid                       | Do not schedule that `Pod`                                            |\n| Unknown error while processing labelled `Pod`                      | Do not schedule that `Pod`                                            |\n| GIT credentials are invalid                                        | Fail inside initContainer and don't let Pod's containers to execute   |\n| Revision is invalid                                                | Fail inside initContainer and don't let Pod's containers to execute   |\n| Volume permissions are invalid                                     | Fail inside initContainer and don't let Pod's containers to execute   |\n| Unknown error while trying to checkout/clone inside initContainer  | Fail inside initContainer and don't let Pod's containers to execute   |\n| There are unknown files in GIT workspace                           | Perform `git reset` and `git clean` (can be disabled with annotation) | \n\nSecurity and reliability\n------------------------\n\n- Using [distroless](https://github.com/GoogleContainerTools/distroless/#why-should-i-use-distroless-images) **static image (No operating system, it does not contain even glibc)**\n- Static golang binary, without dynamic libraries, no dependency on libc\n- No dependency on `git` binary, thanks to [go-git](https://github.com/go-git/go-git)\n- Namespaced `kind: Secret` are used close to `kind: Pod`\n- Admission Webhooks are [limited in scope on API level](./helm/git-clone-controller/templates/mutatingwebhookconfiguration.yaml) - **only labelled Pods are touched**\n- Default Pod's securityContext runs as non-root, with high uid/gid, should work on OpenShift\n- API is using internally mutual TLS to talk with Kubernetes\n\nRoadmap\n-------\n\n### v1\n\n- [x] Injecting git-clone initContainers into labelled pods\n- [x] Support for Git over HTTPS\n- [x] Specifying user id (owner) of files in workspace\n- [x] CLI command `git-clone-controller clone ...` and single Dockerfile for both initContainer and operator\n- [x] Helm\n- [x] Add configurable security context - runAs and filesystem permissions\n\n### v2\n\n- [ ] Namespaced CRD `GitClonePermissions` to specify which GIT repositories are allowed, where are the clone keys\n- [ ] `chown user:group -R` as an alternative to `securityContext` in case, when somebody would have to run initContainer as root\n- [ ] Support for Git over SSH\n\n### v3\n\n- [ ] Possibly: Reacting on webhooks from Gitea and GitHub to update revision on existing pods - deleting marked pods maybe?\n\nThanks\n------\n\nSpecial thanks to [simple-kubernetes-webhook](https://github.com/slackhq/simple-kubernetes-webhook) fantastic project, without it such quick development of this project would not be possible.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friotkit-org%2Fgit-clone-controller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Friotkit-org%2Fgit-clone-controller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friotkit-org%2Fgit-clone-controller/lists"}