From 329c058daa1295ce5038da8d3fe2eeb5e8bdeb38 Mon Sep 17 00:00:00 2001 From: filipsnetwork Date: Sat, 4 Oct 2025 12:49:01 +0200 Subject: [PATCH 01/10] Update readme.md \ are not showing up, added it into a code block so remediate the issue. --- Synapse/readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Synapse/readme.md b/Synapse/readme.md index 71d9b60..4a0f256 100644 --- a/Synapse/readme.md +++ b/Synapse/readme.md @@ -1,10 +1,12 @@ 1) Create a config file +``` sudo docker run -it --rm \ --mount type=volume,src=synapse-data,dst=/data \ -e SYNAPSE_SERVER_NAME=matrix.jimsgarage.co.uk \ -e SYNAPSE_REPORT_STATS=no \ matrixdotorg/synapse:latest generate +``` 2) become root and access the file From 29c14f58af093e454ec1c343a4390cb1e2971307 Mon Sep 17 00:00:00 2001 From: Spyros Gourvelos Date: Mon, 13 Oct 2025 20:35:00 +0300 Subject: [PATCH 02/10] docs: fix importdisk command --- Kubernetes/Cloud-Init/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kubernetes/Cloud-Init/readme.md b/Kubernetes/Cloud-Init/readme.md index e6b068c..d1410e2 100644 --- a/Kubernetes/Cloud-Init/readme.md +++ b/Kubernetes/Cloud-Init/readme.md @@ -4,7 +4,7 @@ qm create 5000 --memory 2048 --core 2 --name ubuntu-cloud --net0 virtio,bridge=vmbr0 cd /var/lib/vz/template/iso/ qm importdisk 5000 lunar-server-cloudimg-amd64-disk-kvm.img -qm set 5000 --scsihw virtio-scsi-pci --scsi0 :5000/vm-5000-disk-0.raw +qm set 5000 --scsihw virtio-scsi-pci --scsi0 /vm-5000-disk-0 qm set 5000 --ide2 :cloudinit qm set 5000 --boot c --bootdisk scsi0 qm set 5000 --serial0 socket --vga serial0 From cb6185374efb6fbda3f3a29c0f134345f9cc5bb1 Mon Sep 17 00:00:00 2001 From: Spyros Gourvelos Date: Mon, 13 Oct 2025 20:42:37 +0300 Subject: [PATCH 03/10] docs: fix typo in cloud-init readme file --- Kubernetes/Cloud-Init/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kubernetes/Cloud-Init/readme.md b/Kubernetes/Cloud-Init/readme.md index d1410e2..ecbccca 100644 --- a/Kubernetes/Cloud-Init/readme.md +++ b/Kubernetes/Cloud-Init/readme.md @@ -4,7 +4,7 @@ qm create 5000 --memory 2048 --core 2 --name ubuntu-cloud --net0 virtio,bridge=vmbr0 cd /var/lib/vz/template/iso/ qm importdisk 5000 lunar-server-cloudimg-amd64-disk-kvm.img -qm set 5000 --scsihw virtio-scsi-pci --scsi0 /vm-5000-disk-0 +qm set 5000 --scsihw virtio-scsi-pci --scsi0 :vm-5000-disk-0 qm set 5000 --ide2 :cloudinit qm set 5000 --boot c --bootdisk scsi0 qm set 5000 --serial0 socket --vga serial0 From fc18bfe3d779d40c3c45e696557c08418612d5f5 Mon Sep 17 00:00:00 2001 From: cyberops7 <18562612+cyberops7@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:33:06 -0600 Subject: [PATCH 04/10] fix: correct misspelled docker-compose filename in Tailscale-Client (#167) Rename docker-compose,yaml (comma) to docker-compose.yaml (dot) so the Tailscale client compose file follows the standard naming convention. Fixes #43 --- .../Tailscale-Client/{docker-compose,yaml => docker-compose.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Headscale/Tailscale-Client/{docker-compose,yaml => docker-compose.yaml} (100%) diff --git a/Headscale/Tailscale-Client/docker-compose,yaml b/Headscale/Tailscale-Client/docker-compose.yaml similarity index 100% rename from Headscale/Tailscale-Client/docker-compose,yaml rename to Headscale/Tailscale-Client/docker-compose.yaml From 8de07752828613f6317181cd4e34d7db8e305543 Mon Sep 17 00:00:00 2001 From: cyberops7 <18562612+cyberops7@users.noreply.github.com> Date: Thu, 2 Jul 2026 00:34:00 -0600 Subject: [PATCH 05/10] Fix RKE2 MetalLB L2Advertisement to honor custom lb_pool_name (#135) (#168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix RKE2 MetalLB L2Advertisement to honor custom lb_pool_name (#135) The apply-manifests role rendered the IPAddressPool from a template using lb_pool_name, but applied the L2Advertisement from a hardcoded remote file where the pool name was baked in as 'first-pool'. Setting lb_pool_name to anything else left the L2Advertisement pointing at a non-existent pool, so MetalLB assigned LoadBalancer IPs but never advertised them (services got an external IP but were unreachable). Template the L2Advertisement locally from lb_pool_name, mirroring the IPAddressPool pattern, so both manifests always reference the same pool. * Add explicit become: true to apply-manifests kubectl tasks These tasks set become_user without a task-level become, tripping ansible-lint's partial-become rule. become is already enabled globally via ansible_become in group_vars/all.yaml, so the tasks already escalate to the ansible user — but that is invisible to the linter (and to anyone reading the task in isolation). Make it explicit with become: true alongside become_user. Behavior-neutral: verified with ansible-playbook -vvv that the escalation target is unchanged (sudo -u ansible; chown ansible on the temp files), so kubectl still runs as the ansible user that owns ~/.kube/config. --- .../RKE2/roles/apply-manifests/tasks/main.yaml | 18 +++++++++++++++++- .../templates/metallb-l2advertisement.j2 | 8 ++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 Ansible/Playbooks/RKE2/roles/apply-manifests/templates/metallb-l2advertisement.j2 diff --git a/Ansible/Playbooks/RKE2/roles/apply-manifests/tasks/main.yaml b/Ansible/Playbooks/RKE2/roles/apply-manifests/tasks/main.yaml index bf5ea47..4a3bd28 100644 --- a/Ansible/Playbooks/RKE2/roles/apply-manifests/tasks/main.yaml +++ b/Ansible/Playbooks/RKE2/roles/apply-manifests/tasks/main.yaml @@ -6,6 +6,7 @@ retries: 120 delay: 10 changed_when: true + become: true become_user: "{{ ansible_user }}" when: inventory_hostname == groups['servers'][0] @@ -13,6 +14,7 @@ - name: Apply metallb namespace ansible.builtin.command: cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml + become: true become_user: "{{ ansible_user }}" changed_when: true when: inventory_hostname == groups['servers'][0] @@ -21,6 +23,7 @@ - name: Apply metallb manifest ansible.builtin.command: cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/{{ metallb_version }}/config/manifests/metallb-native.yaml + become: true become_user: "{{ ansible_user }}" changed_when: true when: inventory_hostname == groups['servers'][0] @@ -30,13 +33,25 @@ ansible.builtin.command: cmd: "kubectl wait --namespace metallb-system --for=condition=ready pod --selector=component=controller --timeout=1800s" changed_when: true + become: true become_user: "{{ ansible_user }}" when: inventory_hostname == groups['servers'][0] +# Deploy L2 Advertisement to Server 1 (templated so it matches lb_pool_name) +- name: Copy metallb L2 Advertisement to server 1 + ansible.builtin.template: + src: templates/metallb-l2advertisement.j2 + dest: /home/{{ ansible_user }}/l2advertisement.yaml + owner: "{{ ansible_user }}" + group: "{{ ansible_user }}" + mode: '0755' + when: inventory_hostname == groups['servers'][0] + # Apply L2 Advertisement for metallb - name: Apply metallb L2 Advertisement ansible.builtin.command: - cmd: kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/l2Advertisement.yaml + cmd: kubectl apply -f /home/{{ ansible_user }}/l2advertisement.yaml + become: true become_user: "{{ ansible_user }}" changed_when: true when: inventory_hostname == groups['servers'][0] @@ -55,6 +70,7 @@ - name: Apply metallb ipppool ansible.builtin.command: cmd: kubectl apply -f /home/{{ ansible_user }}/ippool.yaml + become: true become_user: "{{ ansible_user }}" changed_when: true when: inventory_hostname == groups['servers'][0] diff --git a/Ansible/Playbooks/RKE2/roles/apply-manifests/templates/metallb-l2advertisement.j2 b/Ansible/Playbooks/RKE2/roles/apply-manifests/templates/metallb-l2advertisement.j2 new file mode 100644 index 0000000..25458f0 --- /dev/null +++ b/Ansible/Playbooks/RKE2/roles/apply-manifests/templates/metallb-l2advertisement.j2 @@ -0,0 +1,8 @@ +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: example + namespace: metallb-system +spec: + ipAddressPools: + - {{ lb_pool_name }} From da22609f60ee3ba0b1cab0074dc3e7643f2ff1df Mon Sep 17 00:00:00 2001 From: DefNotJeffrey <127226280+DefNotJeffrey@users.noreply.github.com> Date: Sun, 5 Jul 2026 20:13:34 +0200 Subject: [PATCH 06/10] Komodo - overhaul for v2.x (#169) * Fix in image link + set fixed version * Change old version of Komodo to new Compose and Env * Small fix volume * Change to latest ( last change ) --- Komodo/.env | 137 +++++++++++++++++++++++-------------- Komodo/docker-compose.yaml | 76 ++++++++------------ 2 files changed, 115 insertions(+), 98 deletions(-) diff --git a/Komodo/.env b/Komodo/.env index 99282dd..3d7ccb6 100644 --- a/Komodo/.env +++ b/Komodo/.env @@ -1,5 +1,5 @@ #################################### -# 🦎 KOMODO COMPOSE - VARIABLES 🦎 # +# 🦎 KOMODO COMPOSE - VARIABLES 🦎 # #################################### ## These compose variables can be used with all Komodo deployment options. @@ -7,60 +7,73 @@ ## Additionally, they are passed to both Komodo Core and Komodo Periphery with `env_file: ./compose.env`, ## so you can pass any additional environment variables to Core / Periphery directly in this file as well. -## Stick to a specific version, or use `latest` -COMPOSE_KOMODO_IMAGE_TAG=latest +## Follows "major.minor.patch" semver. +COMPOSE_KOMODO_IMAGE_TAG="2.2.0" +## Store dated database backups on the host - https://komo.do/docs/setup/backup +COMPOSE_KOMODO_BACKUPS_PATH=/etc/komodo/backups -## Note: 🚨 Podman does NOT support local logging driver 🚨. See Podman options here: -## `https://docs.podman.io/en/v4.6.1/markdown/podman-run.1.html#log-driver-driver` -COMPOSE_LOGGING_DRIVER=local # Enable log rotation with the local driver. +## DB credentials +KOMODO_DATABASE_USERNAME=admin +KOMODO_DATABASE_PASSWORD=admin -## DB credentials - Ignored for Sqlite -DB_USERNAME=admin -DB_PASSWORD=admin - -## Configure a secure passkey to authenticate between Core / Periphery. -PASSKEY=a_random_passkey +## Set your time zone for schedules +## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +TZ=Etc/UTC #=-------------------------=# #= Komodo Core Environment =# #=-------------------------=# ## Full variable list + descriptions are available here: -## 🦎 https://github.com/mbecker20/komodo/blob/main/config/core.config.toml 🦎 +## 🦎 https://github.com/moghtech/komodo/blob/main/config/core.config.toml 🦎 ## Note. Secret variables also support `${VARIABLE}_FILE` syntax to pass docker compose secrets. ## Docs: https://docs.docker.com/compose/how-tos/use-secrets/#examples -## Used for Oauth / Webhook url suggestion / Caddy reverse proxy. -KOMODO_HOST=https://demo.komo.do +## Used for Oauth / Webhook url suggestion. +KOMODO_HOST=https://example.komodo.com ## Displayed in the browser tab. KOMODO_TITLE=Komodo -## Create a server matching this address as the "first server". -## Use `https://host.docker.internal:8120` when using systemd-managed Periphery. -KOMODO_FIRST_SERVER=https://periphery:8120 -## Make all buttons just double-click, rather than the full confirmation dialog. + +## Allow Periphery to connect via generated public key +KOMODO_PERIPHERY_PUBLIC_KEY=file:/config/keys/periphery.pub + +## Enable login with username + password. +KOMODO_LOCAL_AUTH=true +## Set the initial admin username created upon first launch. +## Comment out to disable initial user creation, +## and create first user using signup button. +KOMODO_INIT_ADMIN_USERNAME=admin +KOMODO_INIT_ADMIN_PASSWORD=changeme + +## Create a first Server with a custom name. +## Usually the system hostname is good. +KOMODO_FIRST_SERVER_NAME=Local + +## Make execute buttons just double-click, rather than the full confirmation dialog. KOMODO_DISABLE_CONFIRM_DIALOG=false -## Rate Komodo polls your servers for -## status / container status / system stats / alerting. -## Options: 1-sec, 5-sec, 15-sec, 1-min, 5-min. -## Default: 15-sec -KOMODO_MONITORING_INTERVAL="15-sec" -## Rate Komodo polls Resources for updates, -## like outdated commit hash. -## Options: 1-min, 5-min, 15-min, 30-min, 1-hr. -## Default: 5-min -KOMODO_RESOURCE_POLL_INTERVAL="5-min" +## Disable creating the default Procedures on first startup. +KOMODO_DISABLE_INIT_RESOURCES=false -## Used to auth against periphery. Alt: KOMODO_PASSKEY_FILE -KOMODO_PASSKEY=${PASSKEY} ## Used to auth incoming webhooks. Alt: KOMODO_WEBHOOK_SECRET_FILE KOMODO_WEBHOOK_SECRET=a_random_secret ## Used to generate jwt. Alt: KOMODO_JWT_SECRET_FILE KOMODO_JWT_SECRET=a_random_jwt_secret +## Time to live for jwt tokens. +## Options: 1-hr, 12-hr, 1-day, 3-day, 1-wk, 2-wk +KOMODO_JWT_TTL="1-day" + +## Rate Komodo polls your servers for +## status / container status / system stats / alerting. +## Options: 1-sec, 5-sec, 15-sec, 1-min, 5-min, 15-min +## Default: 15-sec +KOMODO_MONITORING_INTERVAL="15-sec" +## Interval at which to poll Resources for any updates / automated actions. +## Options: 5-min, 15-min, 1-hr, 2-hr, 6-hr, 12-hr, 1-day +## Default: 1-hr +KOMODO_RESOURCE_POLL_INTERVAL="1-hr" -## Enable login with username + password. -KOMODO_LOCAL_AUTH=true ## Disable new user signups. KOMODO_DISABLE_USER_REGISTRATION=false ## All new logins are auto enabled @@ -70,10 +83,6 @@ KOMODO_DISABLE_NON_ADMIN_CREATE=false ## Allows all users to have Read level access to all resources. KOMODO_TRANSPARENT_MODE=false -## Time to live for jwt tokens. -## Options: 1-hr, 12-hr, 1-day, 3-day, 1-wk, 2-wk -KOMODO_JWT_TTL="1-day" - ## OIDC Login KOMODO_OIDC_ENABLED=false ## Must reachable from Komodo Core container @@ -81,10 +90,13 @@ KOMODO_OIDC_ENABLED=false ## Change the host to one reachable be reachable by users (optional if it is the same as above). ## DO NOT include the `path` part of the URL. # KOMODO_OIDC_REDIRECT_HOST=https://oidc.provider.external -## Your client credentials +## Your OIDC client id # KOMODO_OIDC_CLIENT_ID= # Alt: KOMODO_OIDC_CLIENT_ID_FILE +## Your OIDC client secret. +## If your provider supports PKCE flow, this can be ommitted. # KOMODO_OIDC_CLIENT_SECRET= # Alt: KOMODO_OIDC_CLIENT_SECRET_FILE ## Make usernames the full email. +## Note. This does not work for all OIDC providers. # KOMODO_OIDC_USE_FULL_EMAIL=true ## Add additional trusted audiences for token claims verification. ## Supports comma separated list, and passing with _FILE (for compose secrets). @@ -100,31 +112,56 @@ KOMODO_GOOGLE_OAUTH_ENABLED=false # KOMODO_GOOGLE_OAUTH_ID= # Alt: KOMODO_GOOGLE_OAUTH_ID_FILE # KOMODO_GOOGLE_OAUTH_SECRET= # Alt: KOMODO_GOOGLE_OAUTH_SECRET_FILE -## Aws - Used to launch Builder instances and ServerTemplate instances. +## Aws - Used to launch Builder instances. KOMODO_AWS_ACCESS_KEY_ID= # Alt: KOMODO_AWS_ACCESS_KEY_ID_FILE KOMODO_AWS_SECRET_ACCESS_KEY= # Alt: KOMODO_AWS_SECRET_ACCESS_KEY_FILE -## Hetzner - Used to launch ServerTemplate instances -## Hetzner Builder not supported due to Hetzner pay-by-the-hour pricing model -KOMODO_HETZNER_TOKEN= # Alt: KOMODO_HETZNER_TOKEN_FILE +## Prettier logging with empty lines between logs +KOMODO_LOGGING_PRETTY=false +## More human readable logging of startup config (multi-line) +KOMODO_PRETTY_STARTUP_CONFIG=false #=------------------------------=# #= Komodo Periphery Environment =# #=------------------------------=# ## Full variable list + descriptions are available here: -## 🦎 https://github.com/mbecker20/komodo/blob/main/config/periphery.config.toml 🦎 +## 🦎 https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml 🦎 -## Periphery passkeys must include KOMODO_PASSKEY to authenticate -PERIPHERY_PASSKEYS=${PASSKEY} +## Point Periphery to Core for connection +PERIPHERY_CORE_ADDRESS=ws://core:9120 +## Use the same name as KOMODO_FIRST_SERVER_NAME to connect +PERIPHERY_CONNECT_AS=${KOMODO_FIRST_SERVER_NAME} +## Use the public key generated by Core. +PERIPHERY_CORE_PUBLIC_KEYS=file:/config/keys/core.pub -## Enable SSL using self signed certificates. -## Connect to Periphery at https://address:8120. -PERIPHERY_SSL_ENABLED=true +## Specify the root directory used by Periphery agent. +## All your compose files and repos need to be inside this directory +## for Periphery to interact with them. +## - ROOT_DIRECTORY (/etc/komodo) +## --- ./stacks +## ------ ./my_stack_1 +## ------ ./my_stack_2 +## --- ./repos +## ------ ./my_repo_1 +## --- ./builds +PERIPHERY_ROOT_DIRECTORY=/etc/komodo -## If the disk size is overreporting, can use one of these to +## Specify whether to disable the terminals feature +## and disallow remote shell access (inside the Periphery container). +PERIPHERY_DISABLE_TERMINALS=false +## Specify whether to disable the container exec / attach features +## and disallow remote container shell access. +PERIPHERY_DISABLE_CONTAINER_TERMINALS=false + +## If the disk size is overreporting, can use one of these to ## whitelist / blacklist the disks to filter them, whichever is easier. ## Accepts comma separated list of paths. ## Usually whitelisting just /etc/hostname gives correct size. PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname -# PERIPHERY_EXCLUDE_DISK_MOUNTS=/snap,/etc/repos \ No newline at end of file +# PERIPHERY_EXCLUDE_DISK_MOUNTS=/snap,/etc/repos + +## Prettier logging with empty lines between logs +PERIPHERY_LOGGING_PRETTY=false +## More human readable logging of startup config (multi-line) +PERIPHERY_PRETTY_STARTUP_CONFIG=false diff --git a/Komodo/docker-compose.yaml b/Komodo/docker-compose.yaml index dc924cd..504af18 100644 --- a/Komodo/docker-compose.yaml +++ b/Komodo/docker-compose.yaml @@ -1,5 +1,5 @@ ################################ -# 🦎 KOMODO COMPOSE - MONGO 🦎 # +# 🦎 KOMODO COMPOSE - MONGO 🦎 # ################################ ## This compose file will deploy: @@ -14,78 +14,63 @@ services: komodo.skip: # Prevent Komodo from stopping with StopAllContainers command: --quiet --wiredTigerCacheSizeGB 0.25 restart: unless-stopped - logging: - driver: ${COMPOSE_LOGGING_DRIVER:-local} - networks: - - default # ports: # - 27017:27017 volumes: - mongo-data:/data/db - mongo-config:/data/configdb environment: - MONGO_INITDB_ROOT_USERNAME: ${DB_USERNAME} - MONGO_INITDB_ROOT_PASSWORD: ${DB_PASSWORD} - + MONGO_INITDB_ROOT_USERNAME: ${KOMODO_DATABASE_USERNAME} + MONGO_INITDB_ROOT_PASSWORD: ${KOMODO_DATABASE_PASSWORD} + core: - image: ghcr.io/mbecker20/komodo:${COMPOSE_KOMODO_IMAGE_TAG:-latest} - labels: - komodo.skip: # Prevent Komodo from stopping with StopAllContainers + image: ghcr.io/moghtech/komodo-core:${COMPOSE_KOMODO_IMAGE_TAG:-2} + init: true restart: unless-stopped depends_on: - mongo - logging: - driver: ${COMPOSE_LOGGING_DRIVER:-local} - networks: - - default ports: - 9120:9120 env_file: .env environment: KOMODO_DATABASE_ADDRESS: mongo:27017 - KOMODO_DATABASE_USERNAME: ${DB_USERNAME} - KOMODO_DATABASE_PASSWORD: ${DB_PASSWORD} volumes: ## Core cache for repos for latest commit hash / contents - repo-cache:/repo-cache + ## Attach the Core / Periphery communication keys + - keys:/config/keys + ## Store dated backups of the database - https://komo.do/docs/setup/backup + - ${COMPOSE_KOMODO_BACKUPS_PATH}:/backups ## Store sync files on server # - /path/to/syncs:/syncs ## Optionally mount a custom core.config.toml # - /path/to/core.config.toml:/config/config.toml - ## Allows for systemd Periphery connection at - ## "http://host.docker.internal:8120" - # extra_hosts: - # - host.docker.internal:host-gateway ## Deploy Periphery container using this block, - ## or deploy the Periphery binary with systemd using - ## https://github.com/mbecker20/komodo/tree/main/scripts + ## or deploy the Periphery binary with systemd using + ## https://github.com/moghtech/komodo/tree/main/scripts periphery: - image: ghcr.io/mbecker20/periphery:${COMPOSE_KOMODO_IMAGE_TAG:-latest} - labels: - komodo.skip: # Prevent Komodo from stopping with StopAllContainers + image: ghcr.io/moghtech/komodo-periphery:${COMPOSE_KOMODO_IMAGE_TAG:-2} + init: true restart: unless-stopped - logging: - driver: ${COMPOSE_LOGGING_DRIVER:-local} - networks: - - default + depends_on: + - core env_file: .env volumes: + ## Attach the Core / Periphery communication keys + - keys:/config/keys ## Mount external docker socket - /var/run/docker.sock:/var/run/docker.sock ## Allow Periphery to see processes outside of container - /proc:/proc - ## use self signed certs in docker volume, - ## or mount your own signed certs. - - ssl-certs:/etc/komodo/ssl - ## manage repos in a docker volume, - ## or change it to an accessible host directory. - - repos:/etc/komodo/repos - ## manage stack files in a docker volume, - ## or change it to an accessible host directory. - - stacks:/etc/komodo/stacks - ## Optionally mount a path to store compose files - # - /path/to/compose:/host/compose + ## Specify the Periphery agent root directory. + ## All your configs / repos must be children of this directory for Periphery to be able to see it. + ## Must be the same inside and outside the container, + ## or docker will get confused. See https://github.com/moghtech/komodo/discussions/180. + ## Default: /etc/komodo. + - ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}:${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo} + ## Optionally mount a custom periphery.config.toml + # - /path/to/periphery.config.toml:/config/config.toml volumes: # Mongo @@ -93,10 +78,5 @@ volumes: mongo-config: # Core repo-cache: - # Periphery - ssl-certs: - repos: - stacks: - -networks: - default: {} \ No newline at end of file + # Core / Periphery + keys: From d5dadb5f4bc8219cac3ff53e0ea4787abd30c89d Mon Sep 17 00:00:00 2001 From: cyberops7 <18562612+cyberops7@users.noreply.github.com> Date: Tue, 30 Jun 2026 21:34:34 -0600 Subject: [PATCH 07/10] ci: lint and secret-scan pull requests Add a GitHub Actions workflow that runs the project's pre-commit hooks against the files changed in each PR, plus a gitleaks secret scan over the PR's commits. Both block on findings. Enrich the existing .pre-commit-config.yaml with general hygiene checks and four linters (shellcheck, yamllint, actionlint, gitleaks), add a lenient yamllint config tuned for the repo's existing YAML, and add a gitleaks config that keeps the full default ruleset while baselining the repo's pre-existing intentional dummy credentials. Linting is scoped to changed files, so the checks pass on the current tree and only hold new or edited files to standard. - .github/workflows/lint.yml: pull_request workflow, read-only token, two jobs (pre-commit on changed files + gitleaks on the commit range) - .pre-commit-config.yaml: keep existing hooks; add hygiene checks, shellcheck (--severity=warning), yamllint, actionlint, gitleaks - .yamllint.yaml: lenient ruleset - .gitleaks.toml: default rules + allowlist for .env/example placeholders - .gitleaksignore: baseline of pre-existing intentional dummy credentials --- .github/workflows/lint.yml | 56 ++++++++++++++++++++++++++++++++++++++ .gitleaks.toml | 49 +++++++++++++++++++++++++++++++++ .gitleaksignore | 41 ++++++++++++++++++++++++++++ .pre-commit-config.yaml | 29 +++++++++++++++++++- .yamllint.yaml | 21 ++++++++++++++ 5 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/lint.yml create mode 100644 .gitleaks.toml create mode 100644 .gitleaksignore create mode 100644 .yamllint.yaml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..9f8d869 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,56 @@ +--- +name: Lint + +on: + pull_request: + +# Read-only: this workflow only inspects code and reports status, so it works +# from fork PRs (which receive a read-only token and no secrets). +permissions: + contents: read + +concurrency: + group: lint-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + pre-commit: + name: pre-commit (changed files) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Run pre-commit on changed files + # gitleaks is handled by the dedicated job below (it scans git history, + # not a file list), so skip it here to avoid a redundant no-op run. + env: + SKIP: gitleaks + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + python -m pip install --upgrade pre-commit + pre-commit run \ + --from-ref "$BASE_SHA" \ + --to-ref "$HEAD_SHA" \ + --show-diff-on-failure + + gitleaks: + name: gitleaks (secret scan) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Scan PR commits for secrets + env: + GITLEAKS_VERSION: 8.30.1 + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \ + | tar -xz gitleaks + ./gitleaks git . --redact --no-banner --log-opts="${BASE_SHA}..${HEAD_SHA}" diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..2d4c385 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,49 @@ +# Gitleaks configuration for JimsGarage. +# +# These are homelab tutorial configs: many directories intentionally ship +# throwaway/dummy credentials so viewers can copy a working example (see +# issue #127). This config keeps the full default secret-detection ruleset +# but allowlists the paths and placeholder values that are dummy *by +# convention*, so the scanner only fires on something that looks like a +# genuine accidental leak. +# +# Tradeoff worth knowing: because `.env` files here are demo placeholders by +# design, they are allowlisted wholesale — gitleaks will NOT catch a real +# secret accidentally dropped into a `.env`. The scanner's value in this repo +# is catching real secrets pasted into scripts, compose files, and manifests. + +title = "JimsGarage gitleaks config" + +[extend] +# Inherit all of gitleaks' built-in rules (AWS keys, JWTs, private keys, +# provider tokens, high-entropy strings, etc.). +useDefault = true + +[[allowlists]] +description = "Intentional throwaway credentials in example/placeholder files" +# `paths` is matched against the file path of the candidate finding. +paths = [ + # Tracked .env files are demo placeholders by convention in this repo. + '''(^|/)\.env$''', + '''\.env$''', + # Files that are explicitly named as examples/samples/templates. + '''(^|/)[^/]*example[^/]*''', + '''(^|/)[^/]*sample[^/]*''', + '''\.(example|sample|dist|template|tmpl)$''', +] + +[[allowlists]] +description = "Common placeholder secret values" +# `regexes` is matched against the detected secret value itself, so a +# realistic-looking value anywhere still gets flagged — only obvious +# placeholders are exempted. +regexTarget = "match" +regexes = [ + '''(?i)changeme''', + '''(?i)your[-_].*(key|token|secret|password)''', + '''(?i)example[-_.]?(key|token|secret|password|value)?''', + '''(?i)supersecret''', + '''(?i)redacted''', + '''(?i)<[^>]+>''', # angle-bracket placeholders like + '''(?i)^(test|dummy|placeholder|password|secret)$''', +] diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 0000000..bd198ad --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,41 @@ +# gitleaks baseline — pre-existing intentional dummy credentials kept here +# instead of an inline `# gitleaks:allow` annotation. A finding is baselined +# (rather than annotated inline) when its file cannot or should not be edited: +# - JSON files have no comment syntax (e.g. Netbird/management.json) +# - multi-line PEM private-key blocks can't carry a reliable inline marker +# (Authelia/Authelia/configuration.yml) +# - files with pre-existing lint debt: editing them would pull that file into +# the changed-files lint scope and fail unrelated yamllint/hygiene checks. +# +# New intentional dummies in clean, comment-capable files should use an inline +# `# gitleaks:allow` instead of being added here. See CONTRIBUTING.md. + +Authelia/Authelia/configuration.yml:generic-api-key:19 +Authelia/Authelia/configuration.yml:generic-api-key:226 +Authelia/Authelia/configuration.yml:private-key:369 +Authelia/Authelia/configuration.yml:generic-api-key:681 +Authelia/Authelia/configuration.yml:private-key:790 +Authelia/Authelia/configuration.yml:generic-api-key:872 +Authelia/Authelia/configuration.yml:private-key:962 +Authelia/Authelia/configuration.yml:private-key:1068 +Authelia/Authelia/configuration.yml:private-key:1225 +Authelia/Authelia/configuration.yml:generic-api-key:1267 +Authelia/Authelia/configuration.yml:private-key:1314 +Grafana-Monitoring/Part-2/telegraf.conf:generic-api-key:398 +Home-Assistant/docker-compose.yaml:generic-api-key:43 +Netbird/docker-compose.yml:generic-api-key:15 +Netbird/docker-compose.yml:generic-api-key:16 +Netbird/management.json:generic-api-key:19 +Netbird/management.json:generic-api-key:30 +Netbird/management.json:generic-api-key:35 +Netbird/management.json:generic-api-key:52 +Paperless-ngx/docker-compose.yaml:generic-api-key:83 +Popup-Homelab/docker-compose.yaml:generic-api-key:87 +Pterodactyl/config.yml:generic-api-key:3 +Pterodactyl/config.yml:generic-api-key:4 +Synapse/docker-compose.yaml:generic-api-key:57 +Synapse/homeserver.yaml:generic-api-key:29 +Synapse/mautrix-discord-bridge/docker-compose.yaml:generic-api-key:36 +Terraform/providers.tf:generic-api-key:14 +Vikunja/docker-compose.yaml:generic-api-key:13 +Zitadel/docker-compose.yaml:generic-api-key:10 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 615bc75..4a1000e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,13 +1,40 @@ --- repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v5.0.0 hooks: + # Pre-existing checks - id: check-symlinks - id: destroyed-symlinks - id: detect-aws-credentials args: [--allow-missing-credentials] + # General hygiene + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-merge-conflict + - id: check-added-large-files + - id: mixed-line-ending + - id: check-yaml + args: [--allow-multiple-documents] - repo: https://github.com/IamTheFij/docker-pre-commit rev: v3.0.1 hooks: - id: docker-compose-check + - repo: https://github.com/koalaman/shellcheck-precommit + rev: v0.10.0 + hooks: + - id: shellcheck + # Block on real warnings/errors; skip style/info noise on legacy scripts. + args: [--severity=warning] + - repo: https://github.com/adrienverge/yamllint + rev: v1.35.1 + hooks: + - id: yamllint + - repo: https://github.com/rhysd/actionlint + rev: v1.7.7 + hooks: + - id: actionlint + - repo: https://github.com/gitleaks/gitleaks + rev: v8.30.1 + hooks: + - id: gitleaks diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 0000000..5fe29e9 --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,21 @@ +--- +# Lenient ruleset: this repo has a large body of pre-existing YAML (compose +# stacks, k8s manifests, Ansible). The goal is to catch real problems on +# changed files without drowning contributors in stylistic noise. +extends: default + +rules: + # Long lines are common and harmless in compose/k8s/Ansible YAML. + line-length: disable + # Many files intentionally omit the leading '---'. + document-start: disable + # compose/Ansible use yes/no/on/off as values, not just true/false. + truthy: + check-keys: false + # Indentation styles vary across the repo; only require internal consistency. + indentation: + spaces: consistent + indent-sequences: whatever + comments: + min-spaces-from-content: 1 + comments-indentation: disable From 6c94afa975ea78af0676450bb5d22199d8c1c72b Mon Sep 17 00:00:00 2001 From: cyberops7 <18562612+cyberops7@users.noreply.github.com> Date: Tue, 30 Jun 2026 21:34:52 -0600 Subject: [PATCH 08/10] docs: document dummy-credential convention; annotate examples Add CONTRIBUTING.md explaining the linting setup and how to mark the repo's intentional dummy credentials so gitleaks does not flag them: inline `# gitleaks:allow` for lint-clean, comment-capable files, and a .gitleaksignore baseline otherwise. Annotate the dummy credentials in four already-lint-clean example files inline, as the preferred convention going forward. - DIUN/docker-compose.yaml - Headscale/Tailscale-Client/docker-compose,yaml - Homepage/Homepage/services.yaml - Kubernetes/Traefik-PiHole/Helm/Traefik/Dashboard/secret-dashboard.yaml --- CONTRIBUTING.md | 72 +++++++++++++++++++ DIUN/docker-compose.yaml | 2 +- .../Tailscale-Client/docker-compose.yaml | 2 +- Homepage/Homepage/services.yaml | 4 +- .../Traefik/Dashboard/secret-dashboard.yaml | 2 +- 5 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..cd11318 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,72 @@ +# Contributing + +Thanks for contributing to JimsGarage! This guide covers the automated checks +that run on pull requests and — importantly for this repo — how to handle the +**dummy credentials** that many of these tutorials intentionally ship. + +## Linting + +A `pre-commit` configuration (`.pre-commit-config.yaml`) and a GitHub Actions +workflow (`.github/workflows/lint.yml`) run a set of checks. CI lints **only the +files changed in your PR**, so you are not responsible for pre-existing issues in +files you do not touch. + +To run the checks locally before pushing: + +```bash +pip install pre-commit +pre-commit install # optional: run automatically on every commit +pre-commit run --all-files # or scope to changed files (CI behavior) +``` + +The hooks include general hygiene (trailing whitespace, end-of-file newline), +`yamllint`, `shellcheck`, `actionlint`, and `gitleaks` (secret scanning). + +## Credentials and secrets + +**Never commit a real credential.** If you accidentally commit one, treat it as +compromised: rotate it, then remove it from history. + +Many tutorials here include **throwaway / dummy credentials** so a config works +out of the box when copied. That is fine — but because they live next to real +config, the `gitleaks` scanner cannot tell a deliberate dummy from a genuine +leak. You therefore need to mark intentional dummies explicitly. There are two +ways to do this; prefer the first. + +### 1. Inline annotation (preferred) + +For a dummy value in a **comment-capable file that is already lint-clean**, add a +trailing `# gitleaks:allow` on the offending line: + +```yaml +environment: + - "ADMIN_TOKEN=not-a-real-token-1234567890" # gitleaks:allow +``` + +This is self-documenting at the point of use and is the convention for any +**new** dummy credential you add. + +### 2. Baseline in `.gitleaksignore` + +Some findings cannot or should not be annotated inline. For these, add the +finding's fingerprint to `.gitleaksignore`. Use this when the file is: + +- **JSON** — it has no comment syntax (e.g. `Netbird/management.json`). +- A **multi-line PEM private-key block** — an inline marker is unreliable across + the block (e.g. `Authelia/Authelia/configuration.yml`). +- **Burdened with pre-existing lint debt** — editing it would pull the whole file + into the changed-files lint scope and fail unrelated `yamllint`/hygiene checks. + +To get a fingerprint, scan and copy the `Fingerprint` field for the finding: + +```bash +gitleaks dir . --report-format json --report-path /tmp/gitleaks.json +# copy the "Fingerprint" value into .gitleaksignore, with a brief comment +``` + +### Allowlisted paths + +`.gitleaks.toml` already allowlists conventional placeholder locations — tracked +`.env` files and `*example*` / `*sample*` files — since those are dummy by +convention in this repo. Secrets placed there are not scanned, so do not rely on +them to hold anything real. diff --git a/DIUN/docker-compose.yaml b/DIUN/docker-compose.yaml index 6c30657..9d86d9a 100644 --- a/DIUN/docker-compose.yaml +++ b/DIUN/docker-compose.yaml @@ -19,7 +19,7 @@ services: - "DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=true" - "DIUN_NOTIF_GOTIFY_ENDPOINT=https://gotify.jimsgarage.co.uk" - - "DIUN_NOTIF_GOTIFY_TOKEN=AYgfdfQaRk3Pb1x" # get your token from Gotify UI + - "DIUN_NOTIF_GOTIFY_TOKEN=AYgfdfQaRk3Pb1x" # get your token from Gotify UI # gitleaks:allow - "DIUN_NOTIF_GOTIFY_PRIORITY=1" - "DIUN_NOTIF_GOTIFY_TIMEOUT=10s" diff --git a/Headscale/Tailscale-Client/docker-compose.yaml b/Headscale/Tailscale-Client/docker-compose.yaml index 0691331..71d5b9b 100644 --- a/Headscale/Tailscale-Client/docker-compose.yaml +++ b/Headscale/Tailscale-Client/docker-compose.yaml @@ -14,5 +14,5 @@ services: - TS_STATE_DIR=/var/lib/tailscale - TS_EXTRA_ARGS=--login-server=https://headscale.jimsgarage.co.uk --advertise-exit-node --advertise-routes=192.168.0.0/16 --accept-dns=true - TS_NO_LOGS_NO_SUPPORT=true - # - TS_AUTHKEY=e6f46b99f2ddsfsf3easdf125590e415db007 # generate this key inside your headscale server container + # - TS_AUTHKEY=e6f46b99f2ddsfsf3easdf125590e415db007 # generate this key inside your headscale server container # gitleaks:allow restart: unless-stopped diff --git a/Homepage/Homepage/services.yaml b/Homepage/Homepage/services.yaml index 1bf065d..4c093f8 100644 --- a/Homepage/Homepage/services.yaml +++ b/Homepage/Homepage/services.yaml @@ -17,7 +17,7 @@ type: traefik url: https://traefik.jimsgarage.co.uk username: admin - password: gT8ni3iX6QkKreWfAdYKe4xqVsaMRUQ4GG7xn59Q + password: gT8ni3iX6QkKreWfAdYKe4xqVsaMRUQ4GG7xn59Q # gitleaks:allow - PiHole: icon: pi-hole.png @@ -28,7 +28,7 @@ widget: type: pihole url: http://192.168.8.2 - key: 73T8oBs9MFKLVAC3mAs2KQbWSsqA7oe2PN9r9H4TQWg2TXNAdq4ZPzvy8oEv + key: 73T8oBs9MFKLVAC3mAs2KQbWSsqA7oe2PN9r9H4TQWg2TXNAdq4ZPzvy8oEv # gitleaks:allow - My Second Group: - My Second Service: diff --git a/Kubernetes/Traefik-PiHole/Helm/Traefik/Dashboard/secret-dashboard.yaml b/Kubernetes/Traefik-PiHole/Helm/Traefik/Dashboard/secret-dashboard.yaml index 48f570c..86603e7 100644 --- a/Kubernetes/Traefik-PiHole/Helm/Traefik/Dashboard/secret-dashboard.yaml +++ b/Kubernetes/Traefik-PiHole/Helm/Traefik/Dashboard/secret-dashboard.yaml @@ -1,6 +1,6 @@ --- apiVersion: v1 -kind: Secret +kind: Secret # gitleaks:allow metadata: name: traefik-dashboard-auth namespace: traefik From 0cb8910004e91c521c0aacbc672b69f1d4fdabbd Mon Sep 17 00:00:00 2001 From: cyberops7 <18562612+cyberops7@users.noreply.github.com> Date: Wed, 8 Jul 2026 22:57:55 -0600 Subject: [PATCH 09/10] Fix rancher-lb LoadBalancer wait-loop in RKE2 scripts The wait-loop was missing '-o' before the jsonpath template, so 'jsonpath={...}' was parsed as a service name and the query errored to empty output, causing the loop to never wait. It also queried .status.conditions[Pending], a shape Services do not have. Poll the rancher-lb service and block until MetalLB assigns an external IP instead. --- Kubernetes/RKE2-Cilium/rke2.sh | 2 +- Kubernetes/RKE2/rke2.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Kubernetes/RKE2-Cilium/rke2.sh b/Kubernetes/RKE2-Cilium/rke2.sh index 5793dab..755269f 100644 --- a/Kubernetes/RKE2-Cilium/rke2.sh +++ b/Kubernetes/RKE2-Cilium/rke2.sh @@ -238,7 +238,7 @@ kubectl -n cattle-system get deploy rancher # Add Rancher LoadBalancer kubectl get svc -n cattle-system kubectl expose deployment rancher --name=rancher-lb --port=443 --type=LoadBalancer -n cattle-system -while [[ $(kubectl get svc -n cattle-system 'jsonpath={..status.conditions[?(@.type=="Pending")].status}') = "True" ]]; do +while [[ -z $(kubectl get svc rancher-lb -n cattle-system -o 'jsonpath={.status.loadBalancer.ingress[0].ip}' 2>/dev/null) ]]; do sleep 5 echo -e " \033[32;5mWaiting for LoadBalancer to come online\033[0m" done diff --git a/Kubernetes/RKE2/rke2.sh b/Kubernetes/RKE2/rke2.sh index 90998cf..eebfa57 100644 --- a/Kubernetes/RKE2/rke2.sh +++ b/Kubernetes/RKE2/rke2.sh @@ -256,7 +256,7 @@ kubectl -n cattle-system get deploy rancher # Add Rancher LoadBalancer kubectl get svc -n cattle-system kubectl expose deployment rancher --name=rancher-lb --port=443 --type=LoadBalancer -n cattle-system -while [[ $(kubectl get svc -n cattle-system 'jsonpath={..status.conditions[?(@.type=="Pending")].status}') = "True" ]]; do +while [[ -z $(kubectl get svc rancher-lb -n cattle-system -o 'jsonpath={.status.loadBalancer.ingress[0].ip}' 2>/dev/null) ]]; do sleep 5 echo -e " \033[32;5mWaiting for LoadBalancer to come online\033[0m" done From bbaf955ea59de68e66da397e54c0a5586ae5fcee Mon Sep 17 00:00:00 2001 From: cyberops7 <18562612+cyberops7@users.noreply.github.com> Date: Wed, 8 Jul 2026 23:32:34 -0600 Subject: [PATCH 10/10] Make RKE2 scripts pass shellcheck (severity=warning) and hygiene hooks The lint CI runs pre-commit on changed files, so touching these scripts surfaced pre-existing warnings. Address them without changing behavior: - Quote array elements (SC2206) and command substitutions (SC2046). - Disable SC2087 on the ssh heredocs (vars are intentionally expanded client-side) and SC1090 on 'source ~/.bashrc' (not followable). - Keep unused config knobs (KVVERSION, interface) with a targeted SC2034 disable; drop the genuinely-unused allnomaster1 array. - Strip trailing whitespace. Verified: shellcheck --severity=warning clean and pre-commit green (ShellCheck v0.10.0) on both files; bash -n syntax OK. --- Kubernetes/RKE2-Cilium/rke2.sh | 28 ++++++++++++++++------------ Kubernetes/RKE2/rke2.sh | 27 +++++++++++++++------------ 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Kubernetes/RKE2-Cilium/rke2.sh b/Kubernetes/RKE2-Cilium/rke2.sh index 755269f..128fd8e 100644 --- a/Kubernetes/RKE2-Cilium/rke2.sh +++ b/Kubernetes/RKE2-Cilium/rke2.sh @@ -21,6 +21,7 @@ echo -e " \033[32;5m \ ############################################# # Version of Kube-VIP to deploy +# shellcheck disable=SC2034 # kept as a documented config knob; not referenced in this script KVVERSION="v0.6.3" # Set the IP addresses of the admin, masters, and workers nodes @@ -35,25 +36,23 @@ worker2=192.168.3.25 user=ubuntu # Interface used on remotes +# shellcheck disable=SC2034 # kept as a documented config knob; not referenced in this script interface=eth0 # Set the virtual IP address (VIP) vip=192.168.3.50 # Array of all master nodes -allmasters=($master1 $master2 $master3) +allmasters=("$master1" "$master2" "$master3") # Array of master nodes -masters=($master2 $master3) +masters=("$master2" "$master3") # Array of worker nodes -workers=($worker1 $worker2) +workers=("$worker1" "$worker2") # Array of all -all=($master1 $master2 $master3 $worker1 $worker2) - -# Array of all minus master1 -allnomaster1=($master2 $master3 $worker1 $worker2) +all=("$master1" "$master2" "$master3" "$worker1" "$worker2") #Loadbalancer IP range - this is set to /27 in rke2-cilium-config.yaml lbrange=192.168.3.64 @@ -70,7 +69,7 @@ sudo timedatectl set-ntp on # Move SSH certs to ~/.ssh and change permissions cp /home/$user/{$certName,$certName.pub} /home/$user/.ssh -chmod 600 /home/$user/.ssh/$certName +chmod 600 /home/$user/.ssh/$certName chmod 644 /home/$user/.ssh/$certName.pub # Install Kubectl if not already present @@ -101,7 +100,7 @@ mkdir ~/.kube # create the rke2 config file sudo mkdir -p /etc/rancher/rke2 touch config.yaml -echo "tls-san:" >> config.yaml +echo "tls-san:" >> config.yaml echo " - $master1" >> config.yaml echo " - $master2" >> config.yaml echo " - $master3" >> config.yaml @@ -115,7 +114,9 @@ echo "disable-kube-proxy: \"true\"" >> config.yaml sudo cp ~/config.yaml /etc/rancher/rke2/config.yaml # update path with rke2-binaries -echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc ; echo 'export PATH=${PATH}:/var/lib/rancher/rke2/bin' >> ~/.bashrc ; echo 'alias k=kubectl' >> ~/.bashrc ; source ~/.bashrc ; +echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc ; echo 'export PATH=${PATH}:/var/lib/rancher/rke2/bin' >> ~/.bashrc ; echo 'alias k=kubectl' >> ~/.bashrc +# shellcheck disable=SC1090 # sourcing the user's ~/.bashrc, which shellcheck can't follow +source ~/.bashrc # Step 2: Copy kube-vip.yaml and certs to all masters for newnode in "${allmasters[@]}"; do @@ -125,6 +126,7 @@ for newnode in "${allmasters[@]}"; do done # Step 3: Connect to Master1 and move kube-vip.yaml and config.yaml. Then install RKE2, copy token back to admin machine. We then use the token to bootstrap additional masternodes +# shellcheck disable=SC2087 # heredoc vars are intentionally expanded client-side before being sent to the remote root shell ssh -tt $user@$master1 -i ~/.ssh/$certName sudo su < $HOME/.kube/config -sudo chown $(id -u):$(id -g) $HOME/.kube/config +sudo chown "$(id -u):$(id -g)" $HOME/.kube/config export KUBECONFIG=${HOME}/.kube/config sudo cp ~/.kube/config /etc/rancher/rke2/rke2.yaml kubectl get nodes # Step 6: Add other Masternodes, note we import the token we extracted from step 3 for newnode in "${masters[@]}"; do + # shellcheck disable=SC2087 # heredoc vars are intentionally expanded client-side before being sent to the remote root shell ssh -tt $user@$newnode -i ~/.ssh/$certName sudo su </dev/null) ]]; do sleep 5 - echo -e " \033[32;5mWaiting for LoadBalancer to come online\033[0m" + echo -e " \033[32;5mWaiting for LoadBalancer to come online\033[0m" done kubectl get svc -n cattle-system diff --git a/Kubernetes/RKE2/rke2.sh b/Kubernetes/RKE2/rke2.sh index eebfa57..906b923 100644 --- a/Kubernetes/RKE2/rke2.sh +++ b/Kubernetes/RKE2/rke2.sh @@ -21,6 +21,7 @@ echo -e " \033[32;5m \ ############################################# # Version of Kube-VIP to deploy +# shellcheck disable=SC2034 # kept as a documented config knob; not referenced in this script KVVERSION="v0.6.3" # Set the IP addresses of the admin, masters, and workers nodes @@ -41,19 +42,16 @@ interface=eth0 vip=192.168.3.50 # Array of all master nodes -allmasters=($master1 $master2 $master3) +allmasters=("$master1" "$master2" "$master3") # Array of master nodes -masters=($master2 $master3) +masters=("$master2" "$master3") # Array of worker nodes -workers=($worker1 $worker2) +workers=("$worker1" "$worker2") # Array of all -all=($master1 $master2 $master3 $worker1 $worker2) - -# Array of all minus master1 -allnomaster1=($master2 $master3 $worker1 $worker2) +all=("$master1" "$master2" "$master3" "$worker1" "$worker2") #Loadbalancer IP range lbrange=192.168.3.60-192.168.3.80 @@ -70,7 +68,7 @@ sudo timedatectl set-ntp on # Move SSH certs to ~/.ssh and change permissions cp /home/$user/{$certName,$certName.pub} /home/$user/.ssh -chmod 600 /home/$user/.ssh/$certName +chmod 600 /home/$user/.ssh/$certName chmod 644 /home/$user/.ssh/$certName.pub # Install Kubectl if not already present @@ -111,7 +109,7 @@ mkdir ~/.kube # create the rke2 config file sudo mkdir -p /etc/rancher/rke2 touch config.yaml -echo "tls-san:" >> config.yaml +echo "tls-san:" >> config.yaml echo " - $vip" >> config.yaml echo " - $master1" >> config.yaml echo " - $master2" >> config.yaml @@ -123,7 +121,9 @@ echo " - rke2-ingress-nginx" >> config.yaml sudo cp ~/config.yaml /etc/rancher/rke2/config.yaml # update path with rke2-binaries -echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc ; echo 'export PATH=${PATH}:/var/lib/rancher/rke2/bin' >> ~/.bashrc ; echo 'alias k=kubectl' >> ~/.bashrc ; source ~/.bashrc ; +echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc ; echo 'export PATH=${PATH}:/var/lib/rancher/rke2/bin' >> ~/.bashrc ; echo 'alias k=kubectl' >> ~/.bashrc +# shellcheck disable=SC1090 # sourcing the user's ~/.bashrc, which shellcheck can't follow +source ~/.bashrc # Step 2: Copy kube-vip.yaml and certs to all masters for newnode in "${allmasters[@]}"; do @@ -134,6 +134,7 @@ for newnode in "${allmasters[@]}"; do done # Step 3: Connect to Master1 and move kube-vip.yaml and config.yaml. Then install RKE2, copy token back to admin machine. We then use the token to bootstrap additional masternodes +# shellcheck disable=SC2087 # heredoc vars are intentionally expanded client-side before being sent to the remote root shell ssh -tt $user@$master1 -i ~/.ssh/$certName sudo su < $HOME/.kube/config -sudo chown $(id -u):$(id -g) $HOME/.kube/config +sudo chown "$(id -u):$(id -g)" $HOME/.kube/config export KUBECONFIG=${HOME}/.kube/config sudo cp ~/.kube/config /etc/rancher/rke2/rke2.yaml kubectl get nodes @@ -165,6 +166,7 @@ kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provi # Step 6: Add other Masternodes, note we import the token we extracted from step 3 for newnode in "${masters[@]}"; do + # shellcheck disable=SC2087 # heredoc vars are intentionally expanded client-side before being sent to the remote root shell ssh -tt $user@$newnode -i ~/.ssh/$certName sudo su </dev/null) ]]; do sleep 5 - echo -e " \033[32;5mWaiting for LoadBalancer to come online\033[0m" + echo -e " \033[32;5mWaiting for LoadBalancer to come online\033[0m" done kubectl get svc -n cattle-system