From 0c4009680cd5164ef809c93531c48725243d356a Mon Sep 17 00:00:00 2001 From: Kjeld Schouten Date: Sun, 20 Oct 2024 17:08:32 +0200 Subject: [PATCH] feat(spegel): BREAKING CHANGE move to custom spegel chart (#28077) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Description** Add our own Spegel chart **โš™๏ธ Type of change** - [x] โš™๏ธ Feature/App addition - [ ] ๐Ÿช› Bugfix - [x] โš ๏ธ Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] ๐Ÿ”ƒ Refactor of current code **๐Ÿงช How Has This Been Tested?** **๐Ÿ“ƒ Notes:** **โœ”๏ธ Checklist:** - [ ] โš–๏ธ My code follows the style guidelines of this project - [ ] ๐Ÿ‘€ I have performed a self-review of my own code - [ ] #๏ธโƒฃ I have commented my code, particularly in hard-to-understand areas - [ ] ๐Ÿ“„ I have made corresponding changes to the documentation - [ ] โš ๏ธ My changes generate no new warnings - [ ] ๐Ÿงช I have added tests to this description that prove my fix is effective or that my feature works - [ ] โฌ†๏ธ I increased versions for any altered app according to semantic versioning - [ ] I made sure the title starts with `feat(chart-name):`, `fix(chart-name):` or `chore(chart-name):` **โž• App addition** If this PR is an app addition please make sure you have done the following. - [ ] ๐Ÿ–ผ๏ธ I have added an icon in the Chart's root directory called `icon.png` --- _Please don't blindly check all the boxes. Read them and only check those that apply. Those checkboxes are there for the reviewer to see what is this all about and the status of this PR with a quick glance._ --- .github/workflows/charts-release.yaml | 24 +- .github/workflows/charts-test.yaml | 79 + .pre-commit-config.yaml | 5 +- charts/incubator/spegel/.helmignore | 32 + charts/incubator/spegel/Chart.yaml | 33 + charts/incubator/spegel/README.md | 61 + charts/incubator/spegel/ci/ci-values.yaml | 9 + charts/incubator/spegel/dashboard.json | 1280 +++++++++++++++++ charts/incubator/spegel/icon.webp | Bin 0 -> 3732 bytes charts/incubator/spegel/templates/NOTES.txt | 1 + charts/incubator/spegel/templates/_args.tpl | 54 + charts/incubator/spegel/templates/common.yaml | 13 + charts/incubator/spegel/values.yaml | 175 +++ .../embed/generic/base/clusterenv.yaml | 4 +- .../system/spegel/app/helm-release.yaml | 29 +- clustertool/pkg/initfiles/clusterenv.go | 2 +- clustertool/pkg/initfiles/initfiles.go | 145 +- 17 files changed, 1871 insertions(+), 75 deletions(-) create mode 100644 charts/incubator/spegel/.helmignore create mode 100644 charts/incubator/spegel/Chart.yaml create mode 100644 charts/incubator/spegel/README.md create mode 100644 charts/incubator/spegel/ci/ci-values.yaml create mode 100644 charts/incubator/spegel/dashboard.json create mode 100644 charts/incubator/spegel/icon.webp create mode 100644 charts/incubator/spegel/templates/NOTES.txt create mode 100644 charts/incubator/spegel/templates/_args.tpl create mode 100644 charts/incubator/spegel/templates/common.yaml create mode 100644 charts/incubator/spegel/values.yaml diff --git a/.github/workflows/charts-release.yaml b/.github/workflows/charts-release.yaml index 0e42a0acfc05..6d1050c2ae41 100644 --- a/.github/workflows/charts-release.yaml +++ b/.github/workflows/charts-release.yaml @@ -93,7 +93,7 @@ jobs: - name: Fix Pre-Commit issues shell: bash - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' run: | echo "Running pre-commit test-and-cleanup..." pre-commit run --all ||: @@ -101,7 +101,7 @@ jobs: find . -name '*.sh' | xargs chmod +x - name: Install Helm - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # tag=v3 with: version: v3.14.0 @@ -145,7 +145,7 @@ jobs: run: helm registry logout quay.io - name: Copy docs to website - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' shell: bash run: | #!/bin/bash @@ -196,7 +196,7 @@ jobs: - name: Prefetch contributor icons shell: bash - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' run: | #!/bin/bash @@ -221,7 +221,7 @@ jobs: #done < src/assets/contributors.json - name: Setup astro Cache - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4 with: # Cache for build and optimized images. @@ -230,7 +230,7 @@ jobs: restore-keys: astro- - name: Setup npm Cache - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4 with: # Cache for npm @@ -240,7 +240,7 @@ jobs: - name: Setup node_modules Cache id: modulescache - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4 with: # Cache for npm and optimized images. @@ -254,19 +254,19 @@ jobs: node-version-file: ./website/.nvmrc - name: Install Packages - if: steps.modulescache.outputs.cache-hit != 'true' && needs.check_changes.outputs.changes_detected == 'true' + if: steps.modulescache.outputs.cache-hit != 'true' && needs.check_changes.outputs.changes_detected == 'true' run: cd website && npm ci - name: Check - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' run: cd website && npm run check - name: Build - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' run: cd website && npm run build - name: Publish to Cloudflare Pages - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' id: cloudflare continue-on-error: true uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1 @@ -299,5 +299,5 @@ jobs: --- - name: Release-and-Website Completed - if: needs.check_changes.outputs.changes_detected == 'true' + if: needs.check_changes.outputs.changes_detected == 'true' run: echo "DONE" diff --git a/.github/workflows/charts-test.yaml b/.github/workflows/charts-test.yaml index 50106bd3a08b..d9c985ef2f02 100644 --- a/.github/workflows/charts-test.yaml +++ b/.github/workflows/charts-test.yaml @@ -151,6 +151,19 @@ jobs: - name: Set up chart-testing uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1 + - name: Update containerd config + if: contains(matrix.chart, 'Spegel') + run: | + sudo mkdir -p /var/lib/rancher/k3s/agent/etc/containerd/ + sudo tee /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl > /dev/null < /dev/null < /dev/null < /dev/null < /dev/null < /dev/null <=1.24.0-0' +maintainers: + - name: TrueCharts + email: info@truecharts.org + url: https://truecharts.org +name: spegel +sources: + - https://github.com/truecharts/charts/tree/master/charts/system/spegel +type: application +version: 2.0.0 diff --git a/charts/incubator/spegel/README.md b/charts/incubator/spegel/README.md new file mode 100644 index 000000000000..44bbdfa70d77 --- /dev/null +++ b/charts/incubator/spegel/README.md @@ -0,0 +1,61 @@ +--- +title: README +--- + +## General Info + +TrueCharts can be installed as both _normal_ Helm Charts or as TrueNAS SCALE Apps. +Both solutions are fully supported, but we heavily advice the use of normal Helm Charts where possible + +For more information about this Chart, please check the docs on the TrueCharts [website](https://truecharts.org/charts/system/spegel) + +**This chart is not maintained by the upstream project and any issues with the chart should be raised [here](https://github.com/truecharts/charts/issues/new/choose)** + +## Installation + +### Helm-Chart installation + +To install TrueCharts Helm charts using Helm, you can use our OCI Repository. + +`helm install mychart oci://tccr.io/truecharts/spegel` + +For more information on how to install TrueCharts Helm charts, checkout the [instructions on the website](/guides) + + +### TrueNAS SCALE Apps + +For more information on how to use TrueCharts as TrueNAS SCALE Apps, please checkout the [quick-start guides for TrueNAS SCALE](/deprecated/scale). + +## Chart Specific Guides and information + +All our charts have dedicated documentation pages. +The documentation for this chart can be found here: +https://truecharts.org/charts/system/spegel + +## Configuration Options + +Please note: For TrueNAS SCALE, only options available in the GUI are supported. +Hence most of these docs do not apply to TrueNAS SCALE + +To view the chart specific options, please view Values.yaml included in the chart. +The most recent version of which, is available here: https://github.com/truecharts/public/blob/master/charts/system/spegel/values.yaml + +All our Charts use a shared "common" library chart that contains most of the templating and options. +For the complete overview of all available options, please checkout the documentation for them on the [common docs on our website](/common) + +For information about the common chart and all defaults included with it, please review its values.yaml file available here: https://github.com/truecharts/public/blob/master/charts/library/common/values.yaml + +## Support + +- See the [Website](https://truecharts.org) +- Check our [Discord](https://discord.gg/tVsPTHWTtr) +- Open a [issue](https://github.com/truecharts/charts/issues/new/choose) + +--- + +## Sponsor TrueCharts + +TrueCharts can only exist due to the incredible effort of our staff. +Please consider making a [donation](/general/sponsor) or contributing back to the project any way you can! + +_All Rights Reserved - The TrueCharts Project_ diff --git a/charts/incubator/spegel/ci/ci-values.yaml b/charts/incubator/spegel/ci/ci-values.yaml new file mode 100644 index 000000000000..92bf13bb2b3d --- /dev/null +++ b/charts/incubator/spegel/ci/ci-values.yaml @@ -0,0 +1,9 @@ +spegel: + # -- Minimum log level to output. Value should be DEBUG, INFO, WARN, or ERROR. + logLevel: "INFO" + # -- Path to Containerd socket. + containerdSock: "/run/k3s/containerd/containerd.sock" + # -- Path to Containerd mirror configuration. + containerdRegistryConfigPath: "/var/lib/rancher/k3s/agent/etc/containerd/certs.d" + # -- Path to Containerd content store.. + containerdContentPath: "/var/lib/containerd/io.containerd.content.v1.content" diff --git a/charts/incubator/spegel/dashboard.json b/charts/incubator/spegel/dashboard.json new file mode 100644 index 000000000000..b0ea4cd529f5 --- /dev/null +++ b/charts/incubator/spegel/dashboard.json @@ -0,0 +1,1280 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "9.3.6" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + }, + { + "type": "panel", + "id": "text", + "name": "Text", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 24, + "panels": [], + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 11, + "options": { + "colorMode": "none", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "count(spegel_advertised_keys{instance=~\"$instance\"})", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Registry", + "transparent": true, + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 1 + }, + "id": 29, + "options": { + "colorMode": "none", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(kubelet_node_name{job=\"kubelet\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Running Nodes", + "transparent": true, + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 1 + }, + "id": 22, + "links": [], + "options": { + "colorMode": "none", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "editorMode": "code", + "expr": "sum(kubelet_running_containers)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "range": true, + "refId": "A" + } + ], + "title": "Running Containers", + "transparent": true, + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 1 + }, + "id": 20, + "options": { + "colorMode": "none", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(kubelet_running_pods)", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Running Pods", + "transparent": true, + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 12, + "y": 1 + }, + "id": 12, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(rate(http_request_duration_seconds_bucket{job=\"spegel\"}[$__interval]))", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Max Request Duration", + "transparent": true, + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 1 + }, + "id": 2, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "
\n\n\n", + "mode": "html" + }, + "pluginVersion": "9.3.6", + "title": "Github link", + "transparent": true, + "type": "text" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "id": 9, + "panels": [], + "repeat": "datasource", + "repeatDirection": "h", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "center", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "instance" + }, + "properties": [ + { + "id": "custom.width", + "value": 226 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "prometheus" + }, + "properties": [ + { + "id": "custom.width", + "value": 296 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 6 + }, + "id": 16, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "frameIndex": 0, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "spegel_advertised_images{job=~\"spegel\",instance=~\"$instance\"}", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "spegel_advertised_keys{job=~\"spegel\",instance=~\"$instance\"} ", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "B" + } + ], + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": [ + "pod", + "Value #A", + "Value #B" + ] + } + } + }, + { + "id": "merge", + "options": {} + }, + { + "id": "renameByRegex", + "options": { + "regex": "Value #A", + "renamePattern": "Container cache" + } + }, + { + "id": "renameByRegex", + "options": { + "regex": "Value #B", + "renamePattern": "Layers cache" + } + } + ], + "transparent": true, + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "series", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 2, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 6 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "spegel_advertised_images{job=~\"spegel\",instance=~\"$instance\"}", + "format": "time_series", + "instant": false, + "legendFormat": "{{ instance }}", + "range": true, + "refId": "A" + } + ], + "title": "Container Images Advertised ", + "transparent": true, + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "series", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 36, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#F2495C", + "mode": "fixed" + } + }, + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.stacking", + "value": { + "group": false, + "mode": "normal" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "limits" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#FF9830", + "mode": "fixed" + } + }, + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.stacking", + "value": { + "group": false, + "mode": "normal" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 13 + }, + "id": 28, + "interval": "1m", + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container=\"$container\"}) by (pod)", + "format": "time_series", + "instant": false, + "intervalFactor": 2, + "legendFormat": "{{ container }}", + "range": true, + "refId": "A", + "step": 10 + } + ], + "title": "CPU Usage", + "transparent": true, + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "series", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 2, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 13 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "spegel_advertised_keys{job=~\"spegel\",instance=~\"$instance\"} ", + "format": "time_series", + "instant": false, + "legendFormat": "{{ instance }}", + "range": true, + "refId": "A" + } + ], + "title": "Images Layer Advertised ", + "transparent": true, + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 35, + "panels": [], + "title": "Kubelet", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 6, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 31, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(kubelet_runtime_operations_total{job=\"kubelet\", metrics_path=\"/metrics\", operation_type=~\"list_images|pull_image|start_container|list_images|list_containers|version|exec_sync|create_container\"}[$__rate_interval])) by (operation_type)", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Kubelet Operation Rate", + "transparent": true, + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 33, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "editorMode": "code", + "expr": "sum(rate(kubelet_runtime_operations_errors_total{job=\"kubelet\", metrics_path=\"/metrics\",operation_type=~\"list_images|pull_image|start_container|list_images|list_containers|version|exec_sync|create_container\"}[$__rate_interval])) by (operation_type)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} {{operation_type}}", + "range": true, + "refId": "A" + } + ], + "title": "Kubelet Operation Error Rate", + "transparent": true, + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 37, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "Prometheus" + }, + "hide": 0, + "includeAll": false, + "label": "Data Source", + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": "registry", + "value": "registry" + }, + "description": "", + "hide": 2, + "includeAll": false, + "label": "container", + "multi": false, + "name": "container", + "options": [ + { + "selected": true, + "text": "registry", + "value": "registry" + } + ], + "query": "registry", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(spegel_advertised_images,pod)", + "description": "", + "hide": 2, + "includeAll": false, + "label": "pod", + "multi": false, + "name": "pod", + "options": [], + "query": { + "query": "label_values(spegel_advertised_images,pod)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(spegel_advertised_keys,instance) ", + "hide": 0, + "includeAll": true, + "label": "instance", + "multi": true, + "name": "instance", + "options": [], + "query": { + "query": "label_values(spegel_advertised_keys,instance) ", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Spegel stateless cluster local OCI registry mirror", + "uid": "1iY4QMJVk-psee", + "version": 1, + "weekStart": "", + "gnetId": 18089, + "description": "Spegel is a pull only OCI registry which runs locally on every Node in the Kubernetes cluster. Containerd is configured to use the local registry as a mirror, which would serve the image from within the cluster or from the source registry." + } diff --git a/charts/incubator/spegel/icon.webp b/charts/incubator/spegel/icon.webp new file mode 100644 index 0000000000000000000000000000000000000000..c876cb18cc1e1fee16a5b3bdc3384304d96955b6 GIT binary patch literal 3732 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 literal 0 HcmV?d00001 diff --git a/charts/incubator/spegel/templates/NOTES.txt b/charts/incubator/spegel/templates/NOTES.txt new file mode 100644 index 000000000000..efcb74cb7721 --- /dev/null +++ b/charts/incubator/spegel/templates/NOTES.txt @@ -0,0 +1 @@ +{{- include "tc.v1.common.lib.chart.notes" $ -}} diff --git a/charts/incubator/spegel/templates/_args.tpl b/charts/incubator/spegel/templates/_args.tpl new file mode 100644 index 000000000000..270403b447cb --- /dev/null +++ b/charts/incubator/spegel/templates/_args.tpl @@ -0,0 +1,54 @@ +{{/* Define the args */}} +{{- define "spegel.args.init" -}} + args: + - configuration + - --log-level={{ .Values.spegel.logLevel }} + - --containerd-registry-config-path={{ .Values.spegel.containerdRegistryConfigPath }} + {{- with .Values.spegel.registries }} + - --registries + {{- range . }} + - {{ . | quote }} + {{- end }} + {{- end }} + - --mirror-registries + - http://$(NODE_IP):{{ .Values.service.main.ports.main.hostPort }} + - http://$(NODE_IP):{{ .Values.service.main.ports.main.nodePort }} + - http://$(NODE_IP):{{ .Values.service.main.ports.main.port }} + {{- with .Values.spegel.additionalMirrorRegistries }} + {{- range . }} + - {{ . | quote }} + {{- end }} + {{- end }} + - --resolve-tags={{ .Values.spegel.resolveTags }} + - --append-mirrors={{ .Values.spegel.appendMirrors }} +{{- end -}} +{{- define "spegel.args.main" -}} + args: + - registry + - --log-level={{ .Values.spegel.logLevel }} + - --mirror-resolve-retries={{ .Values.spegel.mirrorResolveRetries }} + - --mirror-resolve-timeout={{ .Values.spegel.mirrorResolveTimeout }} + - --registry-addr=:{{ .Values.service.main.ports.main.port }} + - --router-addr=:{{ .Values.service.router.ports.router.port }} + - --metrics-addr=:{{ .Values.service.metrics.ports.metrics.port}} + {{- with .Values.spegel.registries }} + - --registries + {{- range . }} + - {{ . | quote }} + {{- end }} + {{- end }} + - --containerd-sock={{ .Values.spegel.containerdSock }} + - --containerd-namespace={{ .Values.spegel.containerdNamespace }} + - --containerd-registry-config-path={{ .Values.spegel.containerdRegistryConfigPath }} + - --bootstrap-kind=kubernetes + {{- with .Values.spegel.kubeconfigPath }} + - --kubeconfig-path={{ . }} + {{- end }} + - '--leader-election-namespace={{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $ "objectData" $.Values.workload.main.podSpec.containers.main "caller" "Deployment") }}' + - --leader-election-name={{ .Release.Name }}-leader-election + - --resolve-latest-tag={{ .Values.spegel.resolveLatestTag }} + - --local-addr=$(NODE_IP):{{ .Values.service.main.ports.main.hostPort }} + {{- with .Values.spegel.containerdContentPath }} + - --containerd-content-path={{ . }} + {{- end }} +{{- end -}} diff --git a/charts/incubator/spegel/templates/common.yaml b/charts/incubator/spegel/templates/common.yaml new file mode 100644 index 000000000000..1f966938937f --- /dev/null +++ b/charts/incubator/spegel/templates/common.yaml @@ -0,0 +1,13 @@ +{{/* Make sure all variables are set properly */}} +{{- include "tc.v1.common.loader.init" . }} +{{- $newArgsInit := (include "spegel.args.init" . | fromYaml) }} +{{- $_ := set .Values "newArgsInit" $newArgsInit -}} +{{- $mergedargsInit := concat $.Values.workload.main.podSpec.initContainers.configuration.args .Values.newArgsInit.args }} +{{- $_ := set $.Values.workload.main.podSpec.initContainers.configuration "args" $mergedargsInit -}} + +{{- $newArgs := (include "spegel.args.main" . | fromYaml) }} +{{- $_ := set .Values "newArgs" $newArgs -}} +{{- $mergedargs := concat $.Values.workload.main.podSpec.containers.main.args .Values.newArgs.args }} +{{- $_ := set $.Values.workload.main.podSpec.containers.main "args" $mergedargs -}} + +{{- include "tc.v1.common.loader.apply" . }} diff --git a/charts/incubator/spegel/values.yaml b/charts/incubator/spegel/values.yaml new file mode 100644 index 000000000000..29d94dcf2940 --- /dev/null +++ b/charts/incubator/spegel/values.yaml @@ -0,0 +1,175 @@ +image: + repository: ghcr.io/spegel-org/spegel + pullPolicy: IfNotPresent + tag: v0.0.27 + +securityContext: + container: + runAsUser: 0 + runAsGroup: 0 + readOnlyRootFilesystem: false + pod: + fsGroup: 0 + +service: + main: + ports: + main: + port: 5000 + targetPort: 5000 + hostPort: 30020 + nodePort: 30021 + router: + enabled: true + ports: + router: + enabled: true + port: 5001 + targetPort: 5001 + metrics: + enabled: true + ports: + metrics: + enabled: true + port: 9090 + targetPort: 9090 + +workload: + main: + podSpec: + type: DaemonSet + initContainers: + configuration: + enabled: true + type: init + args: [] + env: + NODE_IP: + fieldRef: + fieldPath: status.hostIP + containers: + main: + args: [] + env: + NODE_IP: + fieldRef: + fieldPath: status.hostIP + probes: + liveness: + path: /healthz + readiness: + path: /healthz + startup: + path: /healthz + +configmap: + dashboard: + enabled: true + labels: + grafana_dashboard: "1" + data: + traefik.json: >- + {{ .Files.Get "dashboard.json" | indent 8 }} + +podOptions: + automountServiceAccountToken: true + priorityClassName: "system-node-critical" + nodeSelector: + kubernetes.io/arch: "" + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + operator: Exists + - effect: NoSchedule + operator: Exists + +metrics: + main: + enabled: true + type: servicemonitor + endpoints: + - port: metrics + targetSelector: metrics + +portal: + open: + enabled: false + +persistence: + containerd-sock: + enabled: true + type: hostPath + mountPath: "{{ .Values.spegel.containerdSock }}" + hostPath: "{{ .Values.spegel.containerdSock }}" + hostPathType: Socket + containerd-content: + enabled: "{{ if .Values.spegel.containerdContentPath }}true{{else}}false{{end}}}}" + type: hostPath + mountPath: "{{ .Values.spegel.containerdContentPath }}" + hostPath: "{{ .Values.spegel.containerdContentPath }}" + hostPathType: Directory + readOnly: true + containerd-config: + enabled: "{{ if .Values.spegel.containerdMirrorAdd }}true{{else}}false{{end}}}}" + type: hostPath + mountPath: "{{ .Values.spegel.containerdRegistryConfigPath }}" + hostPath: "{{ .Values.spegel.containerdRegistryConfigPath }}" + hostPathType: DirectoryOrCreate + +spegel: + # -- Minimum log level to output. Value should be DEBUG, INFO, WARN, or ERROR. + logLevel: "INFO" + # -- Registries for which mirror configuration will be created. + registries: + - https://cgr.dev + - https://docker.io + - https://ghcr.io + - https://quay.io + - https://mcr.microsoft.com + - https://public.ecr.aws + - https://gcr.io + - https://registry.k8s.io + - https://k8s.gcr.io + - https://tccr.io + - https://factory.talos.dev + # -- Additional target mirror registries other than Spegel. + additionalMirrorRegistries: [] + # -- Max ammount of mirrors to attempt. + mirrorResolveRetries: 3 + # -- Max duration spent finding a mirror. + mirrorResolveTimeout: "20ms" + # -- Path to Containerd socket. + containerdSock: "/run/containerd/containerd.sock" + # -- Containerd namespace where images are stored. + containerdNamespace: "k8s.io" + # -- Path to Containerd mirror configuration. + containerdRegistryConfigPath: "/etc/cri/conf.d/hosts" + # -- Path to Containerd content store.. + containerdContentPath: "/var/lib/containerd/io.containerd.content.v1.content" + # -- If true Spegel will add mirror configuration to the node. + containerdMirrorAdd: true + # -- Path to Kubeconfig credentials, should only be set if Spegel is run in an environment without RBAC. + kubeconfigPath: "" + # -- When true Spegel will resolve tags to digests. + resolveTags: true + # -- When true latest tags will be resolved to digests. + resolveLatestTag: true + # -- When true existing mirror configuration will be appended to instead of replaced. + appendMirrors: false + +# -- Whether Role Based Access Control objects like roles and rolebindings should be created +rbac: + main: + enabled: true + primary: true + clusterWide: true + rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "list", "watch", "create", "update"] +# -- The service account the pods will use to interact with the Kubernetes API +serviceAccount: + main: + enabled: true + primary: true diff --git a/clustertool/embed/generic/base/clusterenv.yaml b/clustertool/embed/generic/base/clusterenv.yaml index f48b615ae06c..128c2c6a585e 100644 --- a/clustertool/embed/generic/base/clusterenv.yaml +++ b/clustertool/embed/generic/base/clusterenv.yaml @@ -7,8 +7,10 @@ MASTER1IP: 192.168.20.210 GATEWAY: 192.168.20.1 # Defines the ip range metallb is allowed to use METALLB_RANGE: 192.168.20.211-192.168.20.219 +# Sets the IP on which Spegel using loadbalancer is made available +SPEGEL_IP: 192.168.20.211 # Sets the Kubernetes Dashboard IP. Has to be within METALLB_RANGE and not in use -DASHBOARD_IP: 192.168.20.211 +DASHBOARD_IP: 192.168.20.212 # Used to automatically generate a sshkey-pair for FluxCD # Has to start with ssh:// GITHUB_REPOSITORY: "" diff --git a/clustertool/embed/generic/kubernetes/system/spegel/app/helm-release.yaml b/clustertool/embed/generic/kubernetes/system/spegel/app/helm-release.yaml index b3799acdc6b2..0dec4f5d0f64 100644 --- a/clustertool/embed/generic/kubernetes/system/spegel/app/helm-release.yaml +++ b/clustertool/embed/generic/kubernetes/system/spegel/app/helm-release.yaml @@ -10,10 +10,10 @@ spec: chart: spec: chart: spegel - version: v0.0.27 + version: 2.0.0 sourceRef: kind: HelmRepository - name: spegel + name: truecharts namespace: flux-system install: remediation: @@ -24,26 +24,7 @@ spec: strategy: rollback retries: 3 values: - grafanaDashboard: - enabled: true - serviceMonitor: - enabled: false - spegel: - containerdSock: /run/containerd/containerd.sock - containerdRegistryConfigPath: /etc/cri/conf.d/hosts - appendMirrors: true - registries: - - https://tccr.io - - https://cgr.dev - - https://docker.io - - https://ghcr.io - - https://quay.io - - https://mcr.microsoft.com - - https://public.ecr.aws - - https://gcr.io - - https://registry.k8s.io - - https://k8s.gcr.io - - https://lscr.io service: - registry: - hostPort: 29999 + main: + type: LoadBalancer + loadBalancerIP: ${SPEGEL_IP} diff --git a/clustertool/pkg/initfiles/clusterenv.go b/clustertool/pkg/initfiles/clusterenv.go index 97f21123afdc..95d8d382b72a 100644 --- a/clustertool/pkg/initfiles/clusterenv.go +++ b/clustertool/pkg/initfiles/clusterenv.go @@ -28,7 +28,7 @@ func LoadTalEnv() error { clusterName() PostProcessTalEnv() clusterEnvtoEnv() - log.Info().Msgf("ClusterEnv loaded successfully\n", ) + log.Info().Msgf("ClusterEnv loaded successfully\n") return nil } diff --git a/clustertool/pkg/initfiles/initfiles.go b/clustertool/pkg/initfiles/initfiles.go index 364b386c56e5..c40811942748 100644 --- a/clustertool/pkg/initfiles/initfiles.go +++ b/clustertool/pkg/initfiles/initfiles.go @@ -274,23 +274,54 @@ func GenPatches() error { log.Fatal().Err(err).Msg("Error: %s") } + setDocker() + + setSpegel() + + // Read the content of the talenv.yaml file + talenvContent, err := os.ReadFile(helper.ClusterPath + "/clusterenv.yaml") + if err != nil { + return err + } + + // Convert the file content to a string and split it into lines + talenvLines := strings.Split(string(talenvContent), "\n") + + // Add indentation to each line + for i, line := range talenvLines { + talenvLines[i] = " " + line + } + + // Join the indented lines back into a single string + indentedTalenvContent := strings.Join(talenvLines, "\n") + + helper.ReplaceInFile(filepath.Join(helper.ClusterPath, "/talos/patches", "sopssecret.yaml"), "REPLACEWITHTALENV", indentedTalenvContent) + // log.Info().Msg("test", filepath.Join(helper.ClusterPath, "/talos/patches", "sopssecret.yaml")) + if err != nil { + log.Fatal().Err(err).Msg("Error: %s") + } + + return nil +} + +func setDocker() { // Assuming this is part of your function if helper.TalEnv["DOCKERHUB_USER"] != "" && helper.TalEnv["DOCKERHUB_PASSWORD"] != "" { // Prepare the content to append configContent := fmt.Sprintf(`# Add Dockerhub Login -- operation: replace - path: /machine/registries/config/registry-1.docker.io - value: - auth: - username: %s - password: %s -- operation: replace - path: /machine/registries/config/docker.io - value: - auth: - username: %s - password: %s -`, helper.TalEnv["DOCKERHUB_USER"], helper.TalEnv["DOCKERHUB_PASSWORD"], helper.TalEnv["DOCKERHUB_USER"], helper.TalEnv["DOCKERHUB_PASSWORD"]) + - operation: replace + path: /machine/registries/config/registry-1.docker.io + value: + auth: + username: %s + password: %s + - operation: replace + path: /machine/registries/config/docker.io + value: + auth: + username: %s + password: %s + `, helper.TalEnv["DOCKERHUB_USER"], helper.TalEnv["DOCKERHUB_PASSWORD"], helper.TalEnv["DOCKERHUB_USER"], helper.TalEnv["DOCKERHUB_PASSWORD"]) // Open the file in append mode or create it if it doesn't exist file, err := os.OpenFile(filepath.Join(helper.ClusterPath+"/talos/patches", "all.yaml"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) @@ -306,7 +337,7 @@ func GenPatches() error { } else { // Optional: Append a note if the environment variables are not set emptyContent := `# No DockerHub credentials provided -` + ` file, err := os.OpenFile(filepath.Join(helper.ClusterPath+"/talos/patches", "all.yaml"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Fatal().Err(err).Msg("Error opening file: %s") @@ -317,31 +348,77 @@ func GenPatches() error { log.Fatal().Err(err).Msg("Error writing to file: %s") } } +} - // Read the content of the talenv.yaml file - talenvContent, err := os.ReadFile(helper.ClusterPath + "/clusterenv.yaml") - if err != nil { - return err - } - - // Convert the file content to a string and split it into lines - talenvLines := strings.Split(string(talenvContent), "\n") +func setSpegel() { + // Assuming this is part of your function + if helper.TalEnv["SPEGEL_IP"] != "" && helper.TalEnv["SPEGEL_IP"] != "" { + // Prepare the content to append + configContent := fmt.Sprintf(`# Add Dockerhub Login +- operation: replace + path: /machine/registries/mirrors/ + value: + cgr.dev: + endpoints: + - http://%s:5000 + docker.io: + endpoints: + - http://%s:5000 + ghcr.io: + endpoints: + - http://%s:5000 + quay.io: + endpoints: + - http://%s:5000 + mcr.microsoft.com: + endpoints: + - http://%s:5000 + public.ecr.aws: + endpoints: + - http://%s:5000 + gcr.io: + endpoints: + - http://%s:5000 + registry.k8s.io: + endpoints: + - http://%s:5000 + k8s.gcr.io: + endpoints: + - http://%s:5000 + tccr.io: + endpoints: + - http://%s:5000 + factory.talos.dev: + endpoints: + - http://%s:5000 + +`, helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"], helper.TalEnv["SPEGEL_IP"]) - // Add indentation to each line - for i, line := range talenvLines { - talenvLines[i] = " " + line - } + // Open the file in append mode or create it if it doesn't exist + file, err := os.OpenFile(filepath.Join(helper.ClusterPath+"/talos/patches", "all.yaml"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Fatal().Err(err).Msg("Error opening file: %s") + } + defer file.Close() - // Join the indented lines back into a single string - indentedTalenvContent := strings.Join(talenvLines, "\n") + // Write the content to the file + if _, err := file.Write([]byte(configContent)); err != nil { + log.Fatal().Err(err).Msg("Error writing to file: %s") + } + } else { + // Optional: Append a note if the environment variables are not set + emptyContent := `# No Spegel_IP provided +` + file, err := os.OpenFile(filepath.Join(helper.ClusterPath+"/talos/patches", "all.yaml"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Fatal().Err(err).Msg("Error opening file: %s") + } + defer file.Close() - helper.ReplaceInFile(filepath.Join(helper.ClusterPath, "/talos/patches", "sopssecret.yaml"), "REPLACEWITHTALENV", indentedTalenvContent) - // log.Info().Msg("test", filepath.Join(helper.ClusterPath, "/talos/patches", "sopssecret.yaml")) - if err != nil { - log.Fatal().Err(err).Msg("Error: %s") + if _, err := file.Write([]byte(emptyContent)); err != nil { + log.Fatal().Err(err).Msg("Error writing to file: %s") + } } - - return nil } func ageGen() error {