mirror of
https://github.com/outbackdingo/cozystack.git
synced 2026-02-05 08:17:59 +00:00
Compare commits
56 Commits
release-0.
...
fix/intege
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94a6cbfe91 | ||
|
|
49b5b510ee | ||
|
|
3cf850c2c4 | ||
|
|
1fbbfcd063 | ||
|
|
de19450f44 | ||
|
|
09c94cc1a0 | ||
|
|
da301373fa | ||
|
|
1f558baa9b | ||
|
|
3c511023f3 | ||
|
|
d10a9ad4e6 | ||
|
|
9ff9f8f601 | ||
|
|
05a1099fd0 | ||
|
|
b2980afcd1 | ||
|
|
6980dc59c5 | ||
|
|
a9c8133fd4 | ||
|
|
065abdd95a | ||
|
|
cd8c6a8b9a | ||
|
|
459673f764 | ||
|
|
c795e4fb68 | ||
|
|
7c98248e45 | ||
|
|
16c771aa77 | ||
|
|
d971f2ff29 | ||
|
|
ead0cca5af | ||
|
|
47ff861f00 | ||
|
|
dbc1fb8a09 | ||
|
|
d9c6fb7625 | ||
|
|
cd23a30e76 | ||
|
|
f4fba7924b | ||
|
|
01b3a82ee2 | ||
|
|
0403f30cd6 | ||
|
|
116196b4d4 | ||
|
|
bdc3525c9b | ||
|
|
9a0f459655 | ||
|
|
59aac50ebd | ||
|
|
5f1b14ab53 | ||
|
|
5c900a7467 | ||
|
|
cc9abbc505 | ||
|
|
c66eb9f94c | ||
|
|
0045ddc757 | ||
|
|
209a3ef181 | ||
|
|
92e2173fa5 | ||
|
|
2d997a4f8d | ||
|
|
b1baaa7d98 | ||
|
|
869bd4f12c | ||
|
|
f6d4541db3 | ||
|
|
5729666e72 | ||
|
|
aa3a36831c | ||
|
|
1e03ba4a02 | ||
|
|
d12dd0e117 | ||
|
|
077045b094 | ||
|
|
85ec09b8de | ||
|
|
e0a63c32b0 | ||
|
|
a2af07d1dc | ||
|
|
0cb9e72f99 | ||
|
|
b4584b4d17 | ||
|
|
ea3b092128 |
96
.github/workflows/pull-requests-release.yaml
vendored
Normal file
96
.github/workflows/pull-requests-release.yaml
vendored
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
name: Releasing PR
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [labeled, opened, synchronize, reopened, closed]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
verify:
|
||||||
|
name: Test Release
|
||||||
|
runs-on: [self-hosted]
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
if: |
|
||||||
|
contains(github.event.pull_request.labels.*.name, 'ok-to-test') &&
|
||||||
|
contains(github.event.pull_request.labels.*.name, 'release') &&
|
||||||
|
github.event.action != 'closed'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
registry: ghcr.io
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: make test
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
name: Finalize Release
|
||||||
|
runs-on: [self-hosted]
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
if: |
|
||||||
|
github.event.pull_request.merged == true &&
|
||||||
|
contains(github.event.pull_request.labels.*.name, 'release')
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Extract tag from branch name
|
||||||
|
id: get_tag
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const branch = context.payload.pull_request.head.ref;
|
||||||
|
const match = branch.match(/^release-(v\d+\.\d+\.\d+(?:[-\w\.]+)?)$/);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
core.setFailed(`Branch '${branch}' does not match expected format 'release-vX.Y.Z[-suffix]'`);
|
||||||
|
} else {
|
||||||
|
const tag = match[1];
|
||||||
|
core.setOutput('tag', tag);
|
||||||
|
console.log(`✅ Extracted tag: ${tag}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Create tag on merged commit
|
||||||
|
run: |
|
||||||
|
git tag ${{ steps.get_tag.outputs.tag }} ${{ github.sha }}
|
||||||
|
git push origin ${{ steps.get_tag.outputs.tag }}
|
||||||
|
|
||||||
|
- name: Publish draft release
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const tag = '${{ steps.get_tag.outputs.tag }}';
|
||||||
|
const releases = await github.rest.repos.listReleases({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
});
|
||||||
|
|
||||||
|
const release = releases.data.find(r => r.tag_name === tag && r.draft);
|
||||||
|
if (!release) {
|
||||||
|
throw new Error(`Draft release with tag ${tag} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await github.rest.repos.updateRelease({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
release_id: release.id,
|
||||||
|
draft: false
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`✅ Published release for ${tag}`);
|
||||||
39
.github/workflows/pull-requests.yaml
vendored
Normal file
39
.github/workflows/pull-requests.yaml
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
name: Pull Request
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [labeled, opened, synchronize, reopened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
e2e:
|
||||||
|
name: Build and Test
|
||||||
|
runs-on: [self-hosted]
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
if: |
|
||||||
|
contains(github.event.pull_request.labels.*.name, 'ok-to-test') &&
|
||||||
|
!contains(github.event.pull_request.labels.*.name, 'release')
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
registry: ghcr.io
|
||||||
|
|
||||||
|
- name: make build
|
||||||
|
run: |
|
||||||
|
make build
|
||||||
|
|
||||||
|
- name: make test
|
||||||
|
run: |
|
||||||
|
make test
|
||||||
159
.github/workflows/tags.yaml
vendored
Normal file
159
.github/workflows/tags.yaml
vendored
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
name: Versioned Tag
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*.*.*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
prepare-release:
|
||||||
|
name: Prepare Release
|
||||||
|
runs-on: [self-hosted]
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check if release already exists
|
||||||
|
id: check_release
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const tag = context.ref.replace('refs/tags/', '');
|
||||||
|
const releases = await github.rest.repos.listReleases({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
});
|
||||||
|
|
||||||
|
const existing = releases.data.find(r => r.tag_name === tag && !r.draft);
|
||||||
|
if (existing) {
|
||||||
|
core.setOutput('skip', 'true');
|
||||||
|
} else {
|
||||||
|
core.setOutput('skip', 'false');
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Skip if release already exists
|
||||||
|
if: steps.check_release.outputs.skip == 'true'
|
||||||
|
run: echo "Release already exists, skipping workflow."
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
registry: ghcr.io
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
run: make build
|
||||||
|
|
||||||
|
- name: Commit release artifacts
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
env:
|
||||||
|
GIT_AUTHOR_NAME: ${{ github.actor }}
|
||||||
|
GIT_AUTHOR_EMAIL: ${{ github.actor }}@users.noreply.github.com
|
||||||
|
run: |
|
||||||
|
git config user.name "$GIT_AUTHOR_NAME"
|
||||||
|
git config user.email "$GIT_AUTHOR_EMAIL"
|
||||||
|
git add .
|
||||||
|
git commit -m "Prepare release ${GITHUB_REF#refs/tags/}" -s || echo "No changes to commit"
|
||||||
|
|
||||||
|
- name: Create release branch
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
run: |
|
||||||
|
BRANCH_NAME="release-${GITHUB_REF#refs/tags/v}"
|
||||||
|
git branch -f "$BRANCH_NAME"
|
||||||
|
git push origin "$BRANCH_NAME" --force
|
||||||
|
|
||||||
|
- name: Create pull request if not exists
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const version = context.ref.replace('refs/tags/v', '');
|
||||||
|
const branch = `release-${version}`;
|
||||||
|
const base = 'main';
|
||||||
|
|
||||||
|
const prs = await github.rest.pulls.list({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
head: `${context.repo.owner}:${branch}`,
|
||||||
|
base
|
||||||
|
});
|
||||||
|
|
||||||
|
if (prs.data.length === 0) {
|
||||||
|
const newPr = await github.rest.pulls.create({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
head: branch,
|
||||||
|
base: base,
|
||||||
|
title: `Release v${version}`,
|
||||||
|
body:
|
||||||
|
`This PR prepares the release \`v${version}\`.\n` +
|
||||||
|
`(Please merge it before releasing draft)`,
|
||||||
|
draft: false
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Created pull request #${newPr.data.number} from ${branch} to ${base}`);
|
||||||
|
|
||||||
|
await github.rest.issues.addLabels({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: newPr.data.number,
|
||||||
|
labels: ['release', 'ok-to-test']
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log(`Pull request already exists from ${branch} to ${base}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Create or reuse draft release
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
id: create_release
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const tag = context.ref.replace('refs/tags/', '');
|
||||||
|
const releases = await github.rest.repos.listReleases({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
});
|
||||||
|
|
||||||
|
let release = releases.data.find(r => r.tag_name === tag);
|
||||||
|
if (!release) {
|
||||||
|
release = await github.rest.repos.createRelease({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
tag_name: tag,
|
||||||
|
name: `${tag}`,
|
||||||
|
draft: true,
|
||||||
|
prerelease: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
core.setOutput('upload_url', release.upload_url);
|
||||||
|
|
||||||
|
- name: Build assets
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
run: make assets
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Upload assets
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
run: make upload_assets VERSION=${GITHUB_REF#refs/tags/}
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Delete pushed tag
|
||||||
|
if: steps.check_release.outputs.skip == 'false'
|
||||||
|
run: |
|
||||||
|
git push --delete origin ${GITHUB_REF#refs/tags/}
|
||||||
91
GOVERNANCE.md
Normal file
91
GOVERNANCE.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# Cozystack Governance
|
||||||
|
|
||||||
|
This document defines the governance structure of the Cozystack community, outlining how members collaborate to achieve shared goals.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
**Cozystack**, a Cloud Native Computing Foundation (CNCF) project, is committed
|
||||||
|
to building an open, inclusive, productive, and self-governing open source
|
||||||
|
community focused on building a high-quality open source PaaS and framework for building clouds.
|
||||||
|
|
||||||
|
## Code Repositories
|
||||||
|
|
||||||
|
The following code repositories are governed by the Cozystack community and
|
||||||
|
maintained under the `cozystack` namespace:
|
||||||
|
|
||||||
|
* **[Cozystack](https://github.com/cozystack/cozystack):** Main Cozystack codebase
|
||||||
|
* **[website](https://github.com/cozystack/website):** Cozystack website and documentation sources
|
||||||
|
* **[Talm](https://github.com/cozystack/talm):** Tool for managing Talos Linux the GitOps way
|
||||||
|
* **[cozy-proxy](https://github.com/cozystack/cozy-proxy):** A simple kube-proxy addon for 1:1 NAT services in Kubernetes with NFT backend
|
||||||
|
* **[cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server):** Cozystack telemetry
|
||||||
|
* **[talos-bootstrap](https://github.com/cozystack/talos-bootstrap):** An interactive Talos Linux installer
|
||||||
|
* **[talos-meta-tool](https://github.com/cozystack/talos-meta-tool):** Tool for writing network metadata into META partition
|
||||||
|
|
||||||
|
## Community Roles
|
||||||
|
|
||||||
|
* **Users:** Members that engage with the Cozystack community via any medium, including Slack, Telegram, GitHub, and mailing lists.
|
||||||
|
* **Contributors:** Members contributing to the projects by contributing and reviewing code, writing documentation,
|
||||||
|
responding to issues, participating in proposal discussions, and so on.
|
||||||
|
* **Directors:** Non-technical project leaders.
|
||||||
|
* **Maintainers**: Technical project leaders.
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
Cozystack is for everyone. Anyone can become a Cozystack contributor simply by
|
||||||
|
contributing to the project, whether through code, documentation, blog posts,
|
||||||
|
community management, or other means.
|
||||||
|
As with all Cozystack community members, contributors are expected to follow the
|
||||||
|
[Cozystack Code of Conduct](https://github.com/cozystack/cozystack/blob/main/CODE_OF_CONDUCT.md).
|
||||||
|
|
||||||
|
All contributions to Cozystack code, documentation, or other components in the
|
||||||
|
Cozystack GitHub organisation must follow the
|
||||||
|
[contributing guidelines](https://github.com/cozystack/cozystack/blob/main/CONTRIBUTING.md).
|
||||||
|
Whether these contributions are merged into the project is the prerogative of the maintainers.
|
||||||
|
|
||||||
|
## Directors
|
||||||
|
|
||||||
|
Directors are responsible for non-technical leadership functions within the project.
|
||||||
|
This includes representing Cozystack and its maintainers to the community, to the press,
|
||||||
|
and to the outside world; interfacing with CNCF and other governance entities;
|
||||||
|
and participating in project decision-making processes when appropriate.
|
||||||
|
|
||||||
|
Directors are elected by a majority vote of the maintainers.
|
||||||
|
|
||||||
|
## Maintainers
|
||||||
|
|
||||||
|
Maintainers have the right to merge code into the project.
|
||||||
|
Anyone can become a Cozystack maintainer (see "Becoming a maintainer" below).
|
||||||
|
|
||||||
|
### Expectations
|
||||||
|
|
||||||
|
Cozystack maintainers are expected to:
|
||||||
|
|
||||||
|
* Review pull requests, triage issues, and fix bugs in their areas of
|
||||||
|
expertise, ensuring that all changes go through the project's code review
|
||||||
|
and integration processes.
|
||||||
|
* Monitor cncf-cozystack-* emails, the Cozystack Slack channels in Kubernetes
|
||||||
|
and CNCF Slack workspaces, Telegram groups, and help out when possible.
|
||||||
|
* Rapidly respond to any time-sensitive security release processes.
|
||||||
|
* Attend Cozystack community meetings.
|
||||||
|
|
||||||
|
If a maintainer is no longer interested in or cannot perform the duties
|
||||||
|
listed above, they should move themselves to emeritus status.
|
||||||
|
If necessary, this can also occur through the decision-making process outlined below.
|
||||||
|
|
||||||
|
### Becoming a Maintainer
|
||||||
|
|
||||||
|
Anyone can become a Cozystack maintainer. Maintainers should be extremely
|
||||||
|
proficient in cloud native technologies and/or Go; have relevant domain expertise;
|
||||||
|
have the time and ability to meet the maintainer's expectations above;
|
||||||
|
and demonstrate the ability to work with the existing maintainers and project processes.
|
||||||
|
|
||||||
|
To become a maintainer, start by expressing interest to existing maintainers.
|
||||||
|
Existing maintainers will then ask you to demonstrate the qualifications above
|
||||||
|
by contributing PRs, doing code reviews, and other such tasks under their guidance.
|
||||||
|
After several months of working together, maintainers will decide whether to grant maintainer status.
|
||||||
|
|
||||||
|
## Project Decision-making Process
|
||||||
|
|
||||||
|
Ideally, all project decisions are resolved by consensus of maintainers and directors.
|
||||||
|
If this is not possible, a vote will be called.
|
||||||
|
The voting process is a simple majority in which each maintainer and director receives one vote.
|
||||||
24
Makefile
24
Makefile
@@ -1,6 +1,13 @@
|
|||||||
.PHONY: manifests repos assets
|
.PHONY: manifests repos assets
|
||||||
|
|
||||||
build:
|
build-deps:
|
||||||
|
@command -V find docker skopeo jq gh helm > /dev/null
|
||||||
|
@yq --version | grep -q "mikefarah" || (echo "mikefarah/yq is required" && exit 1)
|
||||||
|
@tar --version | grep -q GNU || (echo "GNU tar is required" && exit 1)
|
||||||
|
@sed --version | grep -q GNU || (echo "GNU sed is required" && exit 1)
|
||||||
|
@awk --version | grep -q GNU || (echo "GNU awk is required" && exit 1)
|
||||||
|
|
||||||
|
build: build-deps
|
||||||
make -C packages/apps/http-cache image
|
make -C packages/apps/http-cache image
|
||||||
make -C packages/apps/postgres image
|
make -C packages/apps/postgres image
|
||||||
make -C packages/apps/mysql image
|
make -C packages/apps/mysql image
|
||||||
@@ -19,10 +26,6 @@ build:
|
|||||||
make -C packages/core/installer image
|
make -C packages/core/installer image
|
||||||
make manifests
|
make manifests
|
||||||
|
|
||||||
manifests:
|
|
||||||
(cd packages/core/installer/; helm template -n cozy-installer installer .) > manifests/cozystack-installer.yaml
|
|
||||||
sed -i 's|@sha256:[^"]\+||' manifests/cozystack-installer.yaml
|
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
rm -rf _out
|
rm -rf _out
|
||||||
make -C packages/apps check-version-map
|
make -C packages/apps check-version-map
|
||||||
@@ -33,14 +36,21 @@ repos:
|
|||||||
mkdir -p _out/logos
|
mkdir -p _out/logos
|
||||||
cp ./packages/apps/*/logos/*.svg ./packages/extra/*/logos/*.svg _out/logos/
|
cp ./packages/apps/*/logos/*.svg ./packages/extra/*/logos/*.svg _out/logos/
|
||||||
|
|
||||||
|
|
||||||
|
manifests:
|
||||||
|
mkdir -p _out/assets
|
||||||
|
(cd packages/core/installer/; helm template -n cozy-installer installer .) > _out/assets/cozystack-installer.yaml
|
||||||
|
|
||||||
assets:
|
assets:
|
||||||
make -C packages/core/installer/ assets
|
make -C packages/core/installer/ assets
|
||||||
|
|
||||||
test:
|
test:
|
||||||
test -f _out/assets/nocloud-amd64.raw.xz || make -C packages/core/installer talos-nocloud
|
|
||||||
make -C packages/core/testing apply
|
make -C packages/core/testing apply
|
||||||
make -C packages/core/testing test
|
make -C packages/core/testing test
|
||||||
make -C packages/core/testing test-applications
|
#make -C packages/core/testing test-applications
|
||||||
|
|
||||||
generate:
|
generate:
|
||||||
hack/update-codegen.sh
|
hack/update-codegen.sh
|
||||||
|
|
||||||
|
upload_assets: manifests
|
||||||
|
hack/upload-assets.sh
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ done
|
|||||||
|
|
||||||
# Start VMs
|
# Start VMs
|
||||||
for i in 1 2 3; do
|
for i in 1 2 3; do
|
||||||
qemu-system-x86_64 -machine type=pc,accel=kvm -cpu host -smp 4 -m 8192 \
|
qemu-system-x86_64 -machine type=pc,accel=kvm -cpu host -smp 8 -m 16384 \
|
||||||
-device virtio-net,netdev=net0,mac=52:54:00:12:34:5$i -netdev tap,id=net0,ifname=cozy-srv$i,script=no,downscript=no \
|
-device virtio-net,netdev=net0,mac=52:54:00:12:34:5$i -netdev tap,id=net0,ifname=cozy-srv$i,script=no,downscript=no \
|
||||||
-drive file=srv$i/system.img,if=virtio,format=raw \
|
-drive file=srv$i/system.img,if=virtio,format=raw \
|
||||||
-drive file=srv$i/seed.img,if=virtio,format=raw \
|
-drive file=srv$i/seed.img,if=virtio,format=raw \
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
file=versions_map
|
file=versions_map
|
||||||
|
|
||||||
charts=$(find . -mindepth 2 -maxdepth 2 -name Chart.yaml | awk 'sub("/Chart.yaml", "")')
|
charts=$(find . -mindepth 2 -maxdepth 2 -name Chart.yaml | awk 'sub("/Chart.yaml", "")')
|
||||||
|
|
||||||
# <chart> <version> <commit>
|
|
||||||
new_map=$(
|
new_map=$(
|
||||||
for chart in $charts; do
|
for chart in $charts; do
|
||||||
awk '/^name:/ {chart=$2} /^version:/ {version=$2} END{printf "%s %s %s\n", chart, version, "HEAD"}' $chart/Chart.yaml
|
awk '/^name:/ {chart=$2} /^version:/ {version=$2} END{printf "%s %s %s\n", chart, version, "HEAD"}' "$chart/Chart.yaml"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,47 +16,48 @@ if [ ! -f "$file" ] || [ ! -s "$file" ]; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
miss_map=$(echo "$new_map" | awk 'NR==FNR { new_map[$1 " " $2] = $3; next } { if (!($1 " " $2 in new_map)) print $1, $2, $3}' - $file)
|
miss_map=$(echo "$new_map" | awk 'NR==FNR { nm[$1 " " $2] = $3; next } { if (!($1 " " $2 in nm)) print $1, $2, $3}' - "$file")
|
||||||
|
|
||||||
|
# search accross all tags sorted by version
|
||||||
|
search_commits=$(git ls-remote --tags origin | grep 'refs/tags/v' | sort -k2,2 -rV | awk '{print $1}')
|
||||||
|
# add latest main commit to search
|
||||||
|
search_commits="${search_commits} $(git rev-parse "origin/main")"
|
||||||
|
|
||||||
resolved_miss_map=$(
|
resolved_miss_map=$(
|
||||||
echo "$miss_map" | while read chart version commit; do
|
echo "$miss_map" | while read -r chart version commit; do
|
||||||
if [ "$commit" = HEAD ]; then
|
# if version is found in HEAD, it's HEAD
|
||||||
line=$(awk '/^version:/ {print NR; exit}' "./$chart/Chart.yaml")
|
if grep -q "^version: $version$" ./${chart}/Chart.yaml; then
|
||||||
change_commit=$(git --no-pager blame -L"$line",+1 -- "$chart/Chart.yaml" | awk '{print $1}')
|
echo "$chart $version HEAD"
|
||||||
|
continue
|
||||||
if [ "$change_commit" = "00000000" ]; then
|
fi
|
||||||
# Not committed yet, use previous commit
|
|
||||||
line=$(git show HEAD:"./$chart/Chart.yaml" | awk '/^version:/ {print NR; exit}')
|
# if commit is not HEAD, check if it's valid
|
||||||
commit=$(git --no-pager blame -L"$line",+1 HEAD -- "$chart/Chart.yaml" | awk '{print $1}')
|
if [ $commit != "HEAD" ]; then
|
||||||
if [ $(echo $commit | cut -c1) = "^" ]; then
|
if ! git show "${commit}:./${chart}/Chart.yaml" 2>/dev/null | grep -q "^version: $version$"; then
|
||||||
# Previous commit not exists
|
echo "Commit $commit for $chart $version is not valid" >&2
|
||||||
commit=$(echo $commit | cut -c2-)
|
exit 1
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Committed, but version_map wasn't updated
|
|
||||||
line=$(git show HEAD:"./$chart/Chart.yaml" | awk '/^version:/ {print NR; exit}')
|
|
||||||
change_commit=$(git --no-pager blame -L"$line",+1 HEAD -- "$chart/Chart.yaml" | awk '{print $1}')
|
|
||||||
if [ $(echo $change_commit | cut -c1) = "^" ]; then
|
|
||||||
# Previous commit not exists
|
|
||||||
commit=$(echo $change_commit | cut -c2-)
|
|
||||||
else
|
|
||||||
commit=$(git describe --always "$change_commit~1")
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if the commit belongs to the main branch
|
commit=$(git rev-parse --short "$commit")
|
||||||
if ! git merge-base --is-ancestor "$commit" main; then
|
echo "$chart $version $commit"
|
||||||
# Find the closest parent commit that belongs to main
|
continue
|
||||||
commit_in_main=$(git log --pretty=format:"%h" main -- "$chart" | head -n 1)
|
|
||||||
if [ -n "$commit_in_main" ]; then
|
|
||||||
commit="$commit_in_main"
|
|
||||||
else
|
|
||||||
# No valid commit found in main branch for $chart, skipping..."
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
echo "$chart $version $commit"
|
|
||||||
|
# if commit is HEAD, but version is not found in HEAD, check all tags
|
||||||
|
found_tag=""
|
||||||
|
for tag in $search_commits; do
|
||||||
|
if git show "${tag}:./${chart}/Chart.yaml" 2>/dev/null | grep -q "^version: $version$"; then
|
||||||
|
found_tag=$(git rev-parse --short "${tag}")
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$found_tag" ]; then
|
||||||
|
echo "Can't find $chart $version in any version tag or in the latest main commit" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$chart $version $found_tag"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
9
hack/upload-assets.sh
Executable file
9
hack/upload-assets.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
version=${VERSION:-$(git describe --tags)}
|
||||||
|
|
||||||
|
gh release upload --clobber $version _out/assets/cozystack-installer.yaml
|
||||||
|
gh release upload --clobber $version _out/assets/metal-amd64.iso
|
||||||
|
gh release upload --clobber $version _out/assets/metal-amd64.raw.xz
|
||||||
|
gh release upload --clobber $version _out/assets/nocloud-amd64.raw.xz
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
---
|
|
||||||
# Source: cozy-installer/templates/cozystack.yaml
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: cozy-system
|
|
||||||
labels:
|
|
||||||
cozystack.io/system: "true"
|
|
||||||
pod-security.kubernetes.io/enforce: privileged
|
|
||||||
---
|
|
||||||
# Source: cozy-installer/templates/cozystack.yaml
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: cozystack
|
|
||||||
namespace: cozy-system
|
|
||||||
---
|
|
||||||
# Source: cozy-installer/templates/cozystack.yaml
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: cozystack
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: cozystack
|
|
||||||
namespace: cozy-system
|
|
||||||
roleRef:
|
|
||||||
kind: ClusterRole
|
|
||||||
name: cluster-admin
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
---
|
|
||||||
# Source: cozy-installer/templates/cozystack.yaml
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: cozystack
|
|
||||||
namespace: cozy-system
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
port: 80
|
|
||||||
targetPort: 8123
|
|
||||||
selector:
|
|
||||||
app: cozystack
|
|
||||||
type: ClusterIP
|
|
||||||
---
|
|
||||||
# Source: cozy-installer/templates/cozystack.yaml
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: cozystack
|
|
||||||
namespace: cozy-system
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: cozystack
|
|
||||||
strategy:
|
|
||||||
type: RollingUpdate
|
|
||||||
rollingUpdate:
|
|
||||||
maxSurge: 0
|
|
||||||
maxUnavailable: 1
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: cozystack
|
|
||||||
spec:
|
|
||||||
hostNetwork: true
|
|
||||||
serviceAccountName: cozystack
|
|
||||||
containers:
|
|
||||||
- name: cozystack
|
|
||||||
image: "ghcr.io/cozystack/cozystack/installer:v0.28.0"
|
|
||||||
env:
|
|
||||||
- name: KUBERNETES_SERVICE_HOST
|
|
||||||
value: localhost
|
|
||||||
- name: KUBERNETES_SERVICE_PORT
|
|
||||||
value: "7445"
|
|
||||||
- name: K8S_AWAIT_ELECTION_ENABLED
|
|
||||||
value: "1"
|
|
||||||
- name: K8S_AWAIT_ELECTION_NAME
|
|
||||||
value: cozystack
|
|
||||||
- name: K8S_AWAIT_ELECTION_LOCK_NAME
|
|
||||||
value: cozystack
|
|
||||||
- name: K8S_AWAIT_ELECTION_LOCK_NAMESPACE
|
|
||||||
value: cozy-system
|
|
||||||
- name: K8S_AWAIT_ELECTION_IDENTITY
|
|
||||||
valueFrom:
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: metadata.name
|
|
||||||
- name: assets
|
|
||||||
image: "ghcr.io/cozystack/cozystack/installer:v0.28.0"
|
|
||||||
command:
|
|
||||||
- /usr/bin/cozystack-assets-server
|
|
||||||
- "-dir=/cozystack/assets"
|
|
||||||
- "-address=:8123"
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
containerPort: 8123
|
|
||||||
tolerations:
|
|
||||||
- key: "node.kubernetes.io/not-ready"
|
|
||||||
operator: "Exists"
|
|
||||||
effect: "NoSchedule"
|
|
||||||
- key: "node.cilium.io/agent-not-ready"
|
|
||||||
operator: "Exists"
|
|
||||||
effect: "NoSchedule"
|
|
||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.6.2
|
version: 0.7.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -36,13 +36,15 @@ more details:
|
|||||||
|
|
||||||
### Backup parameters
|
### Backup parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| ------------------------ | ---------------------------------------------- | ------------------------------------------------------ |
|
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
||||||
| `backup.enabled` | Enable pereiodic backups | `false` |
|
| `backup.enabled` | Enable pereiodic backups | `false` |
|
||||||
| `backup.s3Region` | The AWS S3 region where backups are stored | `us-east-1` |
|
| `backup.s3Region` | The AWS S3 region where backups are stored | `us-east-1` |
|
||||||
| `backup.s3Bucket` | The S3 bucket used for storing backups | `s3.example.org/clickhouse-backups` |
|
| `backup.s3Bucket` | The S3 bucket used for storing backups | `s3.example.org/clickhouse-backups` |
|
||||||
| `backup.schedule` | Cron schedule for automated backups | `0 2 * * *` |
|
| `backup.schedule` | Cron schedule for automated backups | `0 2 * * *` |
|
||||||
| `backup.cleanupStrategy` | The strategy for cleaning up old backups | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
| `backup.cleanupStrategy` | The strategy for cleaning up old backups | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
||||||
| `backup.s3AccessKey` | The access key for S3, used for authentication | `oobaiRus9pah8PhohL1ThaeTa4UVa7gu` |
|
| `backup.s3AccessKey` | The access key for S3, used for authentication | `oobaiRus9pah8PhohL1ThaeTa4UVa7gu` |
|
||||||
| `backup.s3SecretKey` | The secret key for S3, used for authentication | `ju3eum4dekeich9ahM1te8waeGai0oog` |
|
| `backup.s3SecretKey` | The secret key for S3, used for authentication | `ju3eum4dekeich9ahM1te8waeGai0oog` |
|
||||||
| `backup.resticPassword` | The password for Restic backup encryption | `ChaXoveekoh6eigh4siesheeda2quai0` |
|
| `backup.resticPassword` | The password for Restic backup encryption | `ChaXoveekoh6eigh4siesheeda2quai0` |
|
||||||
|
| `resources` | Resources | `{}` |
|
||||||
|
| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/clickhouse-backup:0.6.2@sha256:67dd53efa86b704fc5cb876aca055fef294b31ab67899b683a4821ea12582ea7
|
ghcr.io/cozystack/cozystack/clickhouse-backup:0.7.0@sha256:3faf7a4cebf390b9053763107482de175aa0fdb88c1e77424fd81100b1c3a205
|
||||||
|
|||||||
50
packages/apps/clickhouse/templates/_resources.tpl
Normal file
50
packages/apps/clickhouse/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -121,6 +121,11 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: clickhouse
|
- name: clickhouse
|
||||||
image: clickhouse/clickhouse-server:24.9.2.42
|
image: clickhouse/clickhouse-server:24.9.2.42
|
||||||
|
{{- if .Values.resources }}
|
||||||
|
resources: {{- toYaml .Values.resources | nindent 16 }}
|
||||||
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 16 }}
|
||||||
|
{{- end }}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: data-volume-template
|
- name: data-volume-template
|
||||||
mountPath: /var/lib/clickhouse
|
mountPath: /var/lib/clickhouse
|
||||||
|
|||||||
@@ -76,6 +76,16 @@
|
|||||||
"default": "ChaXoveekoh6eigh4siesheeda2quai0"
|
"default": "ChaXoveekoh6eigh4siesheeda2quai0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,3 +46,16 @@ backup:
|
|||||||
s3AccessKey: oobaiRus9pah8PhohL1ThaeTa4UVa7gu
|
s3AccessKey: oobaiRus9pah8PhohL1ThaeTa4UVa7gu
|
||||||
s3SecretKey: ju3eum4dekeich9ahM1te8waeGai0oog
|
s3SecretKey: ju3eum4dekeich9ahM1te8waeGai0oog
|
||||||
resticPassword: ChaXoveekoh6eigh4siesheeda2quai0
|
resticPassword: ChaXoveekoh6eigh4siesheeda2quai0
|
||||||
|
|
||||||
|
## @param resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.4.2
|
version: 0.5.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -21,15 +21,17 @@
|
|||||||
|
|
||||||
### Backup parameters
|
### Backup parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| ------------------------ | ---------------------------------------------- | ------------------------------------------------------ |
|
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
||||||
| `backup.enabled` | Enable pereiodic backups | `false` |
|
| `backup.enabled` | Enable pereiodic backups | `false` |
|
||||||
| `backup.s3Region` | The AWS S3 region where backups are stored | `us-east-1` |
|
| `backup.s3Region` | The AWS S3 region where backups are stored | `us-east-1` |
|
||||||
| `backup.s3Bucket` | The S3 bucket used for storing backups | `s3.example.org/postgres-backups` |
|
| `backup.s3Bucket` | The S3 bucket used for storing backups | `s3.example.org/postgres-backups` |
|
||||||
| `backup.schedule` | Cron schedule for automated backups | `0 2 * * *` |
|
| `backup.schedule` | Cron schedule for automated backups | `0 2 * * *` |
|
||||||
| `backup.cleanupStrategy` | The strategy for cleaning up old backups | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
| `backup.cleanupStrategy` | The strategy for cleaning up old backups | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
||||||
| `backup.s3AccessKey` | The access key for S3, used for authentication | `oobaiRus9pah8PhohL1ThaeTa4UVa7gu` |
|
| `backup.s3AccessKey` | The access key for S3, used for authentication | `oobaiRus9pah8PhohL1ThaeTa4UVa7gu` |
|
||||||
| `backup.s3SecretKey` | The secret key for S3, used for authentication | `ju3eum4dekeich9ahM1te8waeGai0oog` |
|
| `backup.s3SecretKey` | The secret key for S3, used for authentication | `ju3eum4dekeich9ahM1te8waeGai0oog` |
|
||||||
| `backup.resticPassword` | The password for Restic backup encryption | `ChaXoveekoh6eigh4siesheeda2quai0` |
|
| `backup.resticPassword` | The password for Restic backup encryption | `ChaXoveekoh6eigh4siesheeda2quai0` |
|
||||||
|
| `resources` | Resources | `{}` |
|
||||||
|
| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/postgres-backup:0.9.0@sha256:2b6ba87f5688a439bd2ac12835a5ab9e601feb15c0c44ed0d9ca48cec7c52521
|
ghcr.io/cozystack/cozystack/postgres-backup:0.10.0@sha256:10179ed56457460d95cd5708db2a00130901255fa30c4dd76c65d2ef5622b61f
|
||||||
|
|||||||
50
packages/apps/ferretdb/templates/_resources.tpl
Normal file
50
packages/apps/ferretdb/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -15,7 +15,11 @@ spec:
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
minSyncReplicas: {{ .Values.quorum.minSyncReplicas }}
|
minSyncReplicas: {{ .Values.quorum.minSyncReplicas }}
|
||||||
maxSyncReplicas: {{ .Values.quorum.maxSyncReplicas }}
|
maxSyncReplicas: {{ .Values.quorum.maxSyncReplicas }}
|
||||||
|
{{- if .Values.resources }}
|
||||||
|
resources: {{- toYaml .Values.resources | nindent 4 }}
|
||||||
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
monitoring:
|
monitoring:
|
||||||
enablePodMonitor: true
|
enablePodMonitor: true
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,16 @@
|
|||||||
"default": "ChaXoveekoh6eigh4siesheeda2quai0"
|
"default": "ChaXoveekoh6eigh4siesheeda2quai0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,3 +48,16 @@ backup:
|
|||||||
s3AccessKey: oobaiRus9pah8PhohL1ThaeTa4UVa7gu
|
s3AccessKey: oobaiRus9pah8PhohL1ThaeTa4UVa7gu
|
||||||
s3SecretKey: ju3eum4dekeich9ahM1te8waeGai0oog
|
s3SecretKey: ju3eum4dekeich9ahM1te8waeGai0oog
|
||||||
resticPassword: ChaXoveekoh6eigh4siesheeda2quai0
|
resticPassword: ChaXoveekoh6eigh4siesheeda2quai0
|
||||||
|
|
||||||
|
## @param resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.3.1
|
version: 0.4.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -60,13 +60,17 @@ VTS module shows wrong upstream resonse time
|
|||||||
|
|
||||||
### Common parameters
|
### Common parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| ------------------ | ----------------------------------------------- | ------- |
|
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||||
| `external` | Enable external access from outside the cluster | `false` |
|
| `external` | Enable external access from outside the cluster | `false` |
|
||||||
| `size` | Persistent Volume size | `10Gi` |
|
| `size` | Persistent Volume size | `10Gi` |
|
||||||
| `storageClass` | StorageClass used to store the data | `""` |
|
| `storageClass` | StorageClass used to store the data | `""` |
|
||||||
| `haproxy.replicas` | Number of HAProxy replicas | `2` |
|
| `haproxy.replicas` | Number of HAProxy replicas | `2` |
|
||||||
| `nginx.replicas` | Number of Nginx replicas | `2` |
|
| `nginx.replicas` | Number of Nginx replicas | `2` |
|
||||||
|
| `haproxy.resources` | Resources | `{}` |
|
||||||
|
| `haproxy.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
| `nginx.resources` | Resources | `{}` |
|
||||||
|
| `nginx.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|
||||||
### Configuration parameters
|
### Configuration parameters
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/nginx-cache:0.3.1@sha256:2b82eae28239ca0f9968602c69bbb752cd2a5818e64934ccd06cb91d95d019c7
|
ghcr.io/cozystack/cozystack/nginx-cache:0.4.0@sha256:0f4d8e6863ed074e90f8a7a8390ccd98dae0220119346aba19e85054bb902e2f
|
||||||
|
|||||||
50
packages/apps/http-cache/templates/_resources.tpl
Normal file
50
packages/apps/http-cache/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -33,6 +33,11 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- image: haproxy:latest
|
- image: haproxy:latest
|
||||||
name: haproxy
|
name: haproxy
|
||||||
|
{{- if .Values.haproxy.resources }}
|
||||||
|
resources: {{- toYaml .Values.haproxy.resources | nindent 10 }}
|
||||||
|
{{- else if ne .Values.haproxy.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.haproxy.resourcesPreset "Release" .Release) | nindent 10 }}
|
||||||
|
{{- end }}
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
name: http
|
name: http
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ spec:
|
|||||||
shareProcessNamespace: true
|
shareProcessNamespace: true
|
||||||
containers:
|
containers:
|
||||||
- name: nginx
|
- name: nginx
|
||||||
|
{{- if $.Values.nginx.resources }}
|
||||||
|
resources: {{- toYaml $.Values.nginx.resources | nindent 10 }}
|
||||||
|
{{- else if ne $.Values.nginx.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" $.Values.nginx.resourcesPreset "Release" $.Release) | nindent 10 }}
|
||||||
|
{{- end }}
|
||||||
image: "{{ $.Files.Get "images/nginx-cache.tag" | trim }}"
|
image: "{{ $.Files.Get "images/nginx-cache.tag" | trim }}"
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
@@ -83,6 +88,13 @@ spec:
|
|||||||
- name: reloader
|
- name: reloader
|
||||||
image: "{{ $.Files.Get "images/nginx-cache.tag" | trim }}"
|
image: "{{ $.Files.Get "images/nginx-cache.tag" | trim }}"
|
||||||
command: ["/usr/bin/nginx-reloader.sh"]
|
command: ["/usr/bin/nginx-reloader.sh"]
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 50Mi
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 50Mi
|
||||||
#command: ["sleep", "infinity"]
|
#command: ["sleep", "infinity"]
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /etc/nginx/nginx.conf
|
- mountPath: /etc/nginx/nginx.conf
|
||||||
|
|||||||
@@ -24,6 +24,16 @@
|
|||||||
"type": "number",
|
"type": "number",
|
||||||
"description": "Number of HAProxy replicas",
|
"description": "Number of HAProxy replicas",
|
||||||
"default": 2
|
"default": 2
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -34,6 +44,16 @@
|
|||||||
"type": "number",
|
"type": "number",
|
||||||
"description": "Number of Nginx replicas",
|
"description": "Number of Nginx replicas",
|
||||||
"default": 2
|
"default": 2
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,8 +12,32 @@ size: 10Gi
|
|||||||
storageClass: ""
|
storageClass: ""
|
||||||
haproxy:
|
haproxy:
|
||||||
replicas: 2
|
replicas: 2
|
||||||
|
## @param haproxy.resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param haproxy.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
nginx:
|
nginx:
|
||||||
replicas: 2
|
replicas: 2
|
||||||
|
## @param nginx.resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param nginx.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|
||||||
## @section Configuration parameters
|
## @section Configuration parameters
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.3.3
|
version: 0.5.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -4,15 +4,19 @@
|
|||||||
|
|
||||||
### Common parameters
|
### Common parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| ------------------------ | ----------------------------------------------- | ------- |
|
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||||
| `external` | Enable external access from outside the cluster | `false` |
|
| `external` | Enable external access from outside the cluster | `false` |
|
||||||
| `kafka.size` | Persistent Volume size for Kafka | `10Gi` |
|
| `kafka.size` | Persistent Volume size for Kafka | `10Gi` |
|
||||||
| `kafka.replicas` | Number of Kafka replicas | `3` |
|
| `kafka.replicas` | Number of Kafka replicas | `3` |
|
||||||
| `kafka.storageClass` | StorageClass used to store the Kafka data | `""` |
|
| `kafka.storageClass` | StorageClass used to store the Kafka data | `""` |
|
||||||
| `zookeeper.size` | Persistent Volume size for ZooKeeper | `5Gi` |
|
| `zookeeper.size` | Persistent Volume size for ZooKeeper | `5Gi` |
|
||||||
| `zookeeper.replicas` | Number of ZooKeeper replicas | `3` |
|
| `zookeeper.replicas` | Number of ZooKeeper replicas | `3` |
|
||||||
| `zookeeper.storageClass` | StorageClass used to store the ZooKeeper data | `""` |
|
| `zookeeper.storageClass` | StorageClass used to store the ZooKeeper data | `""` |
|
||||||
|
| `kafka.resources` | Resources | `{}` |
|
||||||
|
| `kafka.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
| `zookeeper.resources` | Resources | `{}` |
|
||||||
|
| `zookeeper.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|
||||||
### Configuration parameters
|
### Configuration parameters
|
||||||
|
|
||||||
|
|||||||
50
packages/apps/kafka/templates/_resources.tpl
Normal file
50
packages/apps/kafka/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -8,6 +8,11 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
kafka:
|
kafka:
|
||||||
replicas: {{ .Values.kafka.replicas }}
|
replicas: {{ .Values.kafka.replicas }}
|
||||||
|
{{- if .Values.kafka.resources }}
|
||||||
|
resources: {{- toYaml .Values.kafka.resources | nindent 6 }}
|
||||||
|
{{- else if ne .Values.kafka.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.kafka.resourcesPreset "Release" .Release) | nindent 6 }}
|
||||||
|
{{- end }}
|
||||||
listeners:
|
listeners:
|
||||||
- name: plain
|
- name: plain
|
||||||
port: 9092
|
port: 9092
|
||||||
@@ -65,6 +70,11 @@ spec:
|
|||||||
key: kafka-metrics-config.yml
|
key: kafka-metrics-config.yml
|
||||||
zookeeper:
|
zookeeper:
|
||||||
replicas: {{ .Values.zookeeper.replicas }}
|
replicas: {{ .Values.zookeeper.replicas }}
|
||||||
|
{{- if .Values.zookeeper.resources }}
|
||||||
|
resources: {{- toYaml .Values.zookeeper.resources | nindent 6 }}
|
||||||
|
{{- else if ne .Values.zookeeper.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.zookeeper.resourcesPreset "Release" .Release) | nindent 6 }}
|
||||||
|
{{- end }}
|
||||||
storage:
|
storage:
|
||||||
type: persistent-claim
|
type: persistent-claim
|
||||||
{{- with .Values.zookeeper.size }}
|
{{- with .Values.zookeeper.size }}
|
||||||
|
|||||||
@@ -24,6 +24,16 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "StorageClass used to store the Kafka data",
|
"description": "StorageClass used to store the Kafka data",
|
||||||
"default": ""
|
"default": ""
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -44,6 +54,16 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "StorageClass used to store the ZooKeeper data",
|
"description": "StorageClass used to store the ZooKeeper data",
|
||||||
"default": ""
|
"default": ""
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,10 +14,35 @@ kafka:
|
|||||||
size: 10Gi
|
size: 10Gi
|
||||||
replicas: 3
|
replicas: 3
|
||||||
storageClass: ""
|
storageClass: ""
|
||||||
|
## @param kafka.resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param kafka.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|
||||||
zookeeper:
|
zookeeper:
|
||||||
size: 5Gi
|
size: 5Gi
|
||||||
replicas: 3
|
replicas: 3
|
||||||
storageClass: ""
|
storageClass: ""
|
||||||
|
## @param zookeeper.resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param zookeeper.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|
||||||
## @section Configuration parameters
|
## @section Configuration parameters
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.15.2
|
version: 0.17.1
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/cluster-autoscaler:0.15.2@sha256:967e51702102d0dbd97f9847de4159d62681b31eb606322d2c29755393c2236e
|
ghcr.io/cozystack/cozystack/cluster-autoscaler:0.17.0@sha256:85371c6aabf5a7fea2214556deac930c600e362f92673464fe2443784e2869c3
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/kubevirt-cloud-provider:0.15.2@sha256:5e054eae6274963b6e84f87bf3330c94325103c6407b08bfb1189da721333b5c
|
ghcr.io/cozystack/cozystack/kubevirt-cloud-provider:0.17.0@sha256:53f4734109799da8b27f35a3b1afdb4746b5992f1d7b9d1c132ea6242cdd8cf0
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ FROM --platform=linux/amd64 golang:1.20.6 AS builder
|
|||||||
|
|
||||||
RUN git clone https://github.com/kubevirt/cloud-provider-kubevirt /go/src/kubevirt.io/cloud-provider-kubevirt \
|
RUN git clone https://github.com/kubevirt/cloud-provider-kubevirt /go/src/kubevirt.io/cloud-provider-kubevirt \
|
||||||
&& cd /go/src/kubevirt.io/cloud-provider-kubevirt \
|
&& cd /go/src/kubevirt.io/cloud-provider-kubevirt \
|
||||||
&& git checkout da9e0cf
|
&& git checkout 443a1fe
|
||||||
|
|
||||||
WORKDIR /go/src/kubevirt.io/cloud-provider-kubevirt
|
WORKDIR /go/src/kubevirt.io/cloud-provider-kubevirt
|
||||||
|
|
||||||
# see: https://github.com/kubevirt/cloud-provider-kubevirt/pull/335
|
# see: https://github.com/kubevirt/cloud-provider-kubevirt/pull/335
|
||||||
# see: https://github.com/kubevirt/cloud-provider-kubevirt/pull/336
|
|
||||||
ADD patches /patches
|
ADD patches /patches
|
||||||
RUN git apply /patches/*.diff
|
RUN git apply /patches/*.diff
|
||||||
RUN go get 'k8s.io/endpointslice/util@v0.28' 'k8s.io/apiserver@v0.28'
|
RUN go get 'k8s.io/endpointslice/util@v0.28' 'k8s.io/apiserver@v0.28'
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
diff --git a/pkg/controller/kubevirteps/kubevirteps_controller.go b/pkg/controller/kubevirteps/kubevirteps_controller.go
|
|
||||||
index a3c1aa33..95c31438 100644
|
|
||||||
--- a/pkg/controller/kubevirteps/kubevirteps_controller.go
|
|
||||||
+++ b/pkg/controller/kubevirteps/kubevirteps_controller.go
|
|
||||||
@@ -412,11 +412,11 @@ func (c *Controller) reconcileByAddressType(service *v1.Service, tenantSlices []
|
|
||||||
// Create the desired port configuration
|
|
||||||
var desiredPorts []discovery.EndpointPort
|
|
||||||
|
|
||||||
- for _, port := range service.Spec.Ports {
|
|
||||||
+ for i := range service.Spec.Ports {
|
|
||||||
desiredPorts = append(desiredPorts, discovery.EndpointPort{
|
|
||||||
- Port: &port.TargetPort.IntVal,
|
|
||||||
- Protocol: &port.Protocol,
|
|
||||||
- Name: &port.Name,
|
|
||||||
+ Port: &service.Spec.Ports[i].TargetPort.IntVal,
|
|
||||||
+ Protocol: &service.Spec.Ports[i].Protocol,
|
|
||||||
+ Name: &service.Spec.Ports[i].Name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
diff --git a/pkg/controller/kubevirteps/kubevirteps_controller.go b/pkg/controller/kubevirteps/kubevirteps_controller.go
|
|
||||||
index a3c1aa33..6f6e3d32 100644
|
|
||||||
--- a/pkg/controller/kubevirteps/kubevirteps_controller.go
|
|
||||||
+++ b/pkg/controller/kubevirteps/kubevirteps_controller.go
|
|
||||||
@@ -108,32 +108,24 @@ func newRequest(reqType ReqType, obj interface{}, oldObj interface{}) *Request {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Controller) Init() error {
|
|
||||||
-
|
|
||||||
- // Act on events from Services on the infra cluster. These are created by the EnsureLoadBalancer function.
|
|
||||||
- // We need to watch for these events so that we can update the EndpointSlices in the infra cluster accordingly.
|
|
||||||
+ // Existing Service event handlers...
|
|
||||||
_, err := c.infraFactory.Core().V1().Services().Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
|
||||||
AddFunc: func(obj interface{}) {
|
|
||||||
- // cast obj to Service
|
|
||||||
svc := obj.(*v1.Service)
|
|
||||||
- // Only act on Services of type LoadBalancer
|
|
||||||
if svc.Spec.Type == v1.ServiceTypeLoadBalancer {
|
|
||||||
klog.Infof("Service added: %v/%v", svc.Namespace, svc.Name)
|
|
||||||
c.queue.Add(newRequest(AddReq, obj, nil))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
UpdateFunc: func(oldObj, newObj interface{}) {
|
|
||||||
- // cast obj to Service
|
|
||||||
newSvc := newObj.(*v1.Service)
|
|
||||||
- // Only act on Services of type LoadBalancer
|
|
||||||
if newSvc.Spec.Type == v1.ServiceTypeLoadBalancer {
|
|
||||||
klog.Infof("Service updated: %v/%v", newSvc.Namespace, newSvc.Name)
|
|
||||||
c.queue.Add(newRequest(UpdateReq, newObj, oldObj))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DeleteFunc: func(obj interface{}) {
|
|
||||||
- // cast obj to Service
|
|
||||||
svc := obj.(*v1.Service)
|
|
||||||
- // Only act on Services of type LoadBalancer
|
|
||||||
if svc.Spec.Type == v1.ServiceTypeLoadBalancer {
|
|
||||||
klog.Infof("Service deleted: %v/%v", svc.Namespace, svc.Name)
|
|
||||||
c.queue.Add(newRequest(DeleteReq, obj, nil))
|
|
||||||
@@ -144,7 +136,7 @@ func (c *Controller) Init() error {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
- // Monitor endpoint slices that we are interested in based on known services in the infra cluster
|
|
||||||
+ // Existing EndpointSlice event handlers in tenant cluster...
|
|
||||||
_, err = c.tenantFactory.Discovery().V1().EndpointSlices().Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
|
||||||
AddFunc: func(obj interface{}) {
|
|
||||||
eps := obj.(*discovery.EndpointSlice)
|
|
||||||
@@ -194,10 +186,80 @@ func (c *Controller) Init() error {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
- //TODO: Add informer for EndpointSlices in the infra cluster to watch for (unwanted) changes
|
|
||||||
+ // Add an informer for EndpointSlices in the infra cluster
|
|
||||||
+ _, err = c.infraFactory.Discovery().V1().EndpointSlices().Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
|
||||||
+ AddFunc: func(obj interface{}) {
|
|
||||||
+ eps := obj.(*discovery.EndpointSlice)
|
|
||||||
+ if c.managedByController(eps) {
|
|
||||||
+ svc, svcErr := c.getInfraServiceForEPS(context.TODO(), eps)
|
|
||||||
+ if svcErr != nil {
|
|
||||||
+ klog.Errorf("Failed to get infra Service for EndpointSlice %s/%s: %v", eps.Namespace, eps.Name, svcErr)
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+ if svc != nil {
|
|
||||||
+ klog.Infof("Infra EndpointSlice added: %v/%v, requeuing Service: %v/%v", eps.Namespace, eps.Name, svc.Namespace, svc.Name)
|
|
||||||
+ c.queue.Add(newRequest(AddReq, svc, nil))
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ UpdateFunc: func(oldObj, newObj interface{}) {
|
|
||||||
+ eps := newObj.(*discovery.EndpointSlice)
|
|
||||||
+ if c.managedByController(eps) {
|
|
||||||
+ svc, svcErr := c.getInfraServiceForEPS(context.TODO(), eps)
|
|
||||||
+ if svcErr != nil {
|
|
||||||
+ klog.Errorf("Failed to get infra Service for EndpointSlice %s/%s: %v", eps.Namespace, eps.Name, svcErr)
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+ if svc != nil {
|
|
||||||
+ klog.Infof("Infra EndpointSlice updated: %v/%v, requeuing Service: %v/%v", eps.Namespace, eps.Name, svc.Namespace, svc.Name)
|
|
||||||
+ c.queue.Add(newRequest(UpdateReq, svc, nil))
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ DeleteFunc: func(obj interface{}) {
|
|
||||||
+ eps := obj.(*discovery.EndpointSlice)
|
|
||||||
+ if c.managedByController(eps) {
|
|
||||||
+ svc, svcErr := c.getInfraServiceForEPS(context.TODO(), eps)
|
|
||||||
+ if svcErr != nil {
|
|
||||||
+ klog.Errorf("Failed to get infra Service for EndpointSlice %s/%s on delete: %v", eps.Namespace, eps.Name, svcErr)
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+ if svc != nil {
|
|
||||||
+ klog.Infof("Infra EndpointSlice deleted: %v/%v, requeuing Service: %v/%v", eps.Namespace, eps.Name, svc.Namespace, svc.Name)
|
|
||||||
+ c.queue.Add(newRequest(DeleteReq, svc, nil))
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ })
|
|
||||||
+ if err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
+// getInfraServiceForEPS returns the Service in the infra cluster associated with the given EndpointSlice.
|
|
||||||
+// It does this by reading the "kubernetes.io/service-name" label from the EndpointSlice, which should correspond
|
|
||||||
+// to the Service name. If not found or if the Service doesn't exist, it returns nil.
|
|
||||||
+func (c *Controller) getInfraServiceForEPS(ctx context.Context, eps *discovery.EndpointSlice) (*v1.Service, error) {
|
|
||||||
+ svcName := eps.Labels[discovery.LabelServiceName]
|
|
||||||
+ if svcName == "" {
|
|
||||||
+ // No service name label found, can't determine infra service.
|
|
||||||
+ return nil, nil
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ svc, err := c.infraClient.CoreV1().Services(c.infraNamespace).Get(ctx, svcName, metav1.GetOptions{})
|
|
||||||
+ if err != nil {
|
|
||||||
+ if k8serrors.IsNotFound(err) {
|
|
||||||
+ // Service doesn't exist
|
|
||||||
+ return nil, nil
|
|
||||||
+ }
|
|
||||||
+ return nil, err
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return svc, nil
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
// Run starts an asynchronous loop that monitors and updates GKENetworkParamSet in the cluster.
|
|
||||||
func (c *Controller) Run(numWorkers int, stopCh <-chan struct{}, controllerManagerMetrics *controllersmetrics.ControllerManagerMetrics) {
|
|
||||||
defer utilruntime.HandleCrash()
|
|
||||||
@@ -0,0 +1,689 @@
|
|||||||
|
diff --git a/.golangci.yml b/.golangci.yml
|
||||||
|
index cf72a41a2..1c9237e83 100644
|
||||||
|
--- a/.golangci.yml
|
||||||
|
+++ b/.golangci.yml
|
||||||
|
@@ -122,3 +122,9 @@ linters:
|
||||||
|
# - testpackage
|
||||||
|
# - revive
|
||||||
|
# - wsl
|
||||||
|
+issues:
|
||||||
|
+ exclude-rules:
|
||||||
|
+ - filename: "kubevirteps_controller_test.go"
|
||||||
|
+ linters:
|
||||||
|
+ - govet
|
||||||
|
+ text: "declaration of \"err\" shadows"
|
||||||
|
diff --git a/cmd/kubevirt-cloud-controller-manager/kubevirteps.go b/cmd/kubevirt-cloud-controller-manager/kubevirteps.go
|
||||||
|
index 74166b5d9..4e744f8de 100644
|
||||||
|
--- a/cmd/kubevirt-cloud-controller-manager/kubevirteps.go
|
||||||
|
+++ b/cmd/kubevirt-cloud-controller-manager/kubevirteps.go
|
||||||
|
@@ -101,7 +101,18 @@ func startKubevirtCloudController(
|
||||||
|
|
||||||
|
klog.Infof("Setting up kubevirtEPSController")
|
||||||
|
|
||||||
|
- kubevirtEPSController := kubevirteps.NewKubevirtEPSController(tenantClient, infraClient, infraDynamic, kubevirtCloud.Namespace())
|
||||||
|
+ clusterName := ccmConfig.ComponentConfig.KubeCloudShared.ClusterName
|
||||||
|
+ if clusterName == "" {
|
||||||
|
+ klog.Fatalf("Required flag --cluster-name is missing")
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kubevirtEPSController := kubevirteps.NewKubevirtEPSController(
|
||||||
|
+ tenantClient,
|
||||||
|
+ infraClient,
|
||||||
|
+ infraDynamic,
|
||||||
|
+ kubevirtCloud.Namespace(),
|
||||||
|
+ clusterName,
|
||||||
|
+ )
|
||||||
|
|
||||||
|
klog.Infof("Initializing kubevirtEPSController")
|
||||||
|
|
||||||
|
diff --git a/pkg/controller/kubevirteps/kubevirteps_controller.go b/pkg/controller/kubevirteps/kubevirteps_controller.go
|
||||||
|
index 6f6e3d322..b56882c12 100644
|
||||||
|
--- a/pkg/controller/kubevirteps/kubevirteps_controller.go
|
||||||
|
+++ b/pkg/controller/kubevirteps/kubevirteps_controller.go
|
||||||
|
@@ -54,10 +54,10 @@ type Controller struct {
|
||||||
|
infraDynamic dynamic.Interface
|
||||||
|
infraFactory informers.SharedInformerFactory
|
||||||
|
|
||||||
|
- infraNamespace string
|
||||||
|
- queue workqueue.RateLimitingInterface
|
||||||
|
- maxRetries int
|
||||||
|
-
|
||||||
|
+ infraNamespace string
|
||||||
|
+ clusterName string
|
||||||
|
+ queue workqueue.RateLimitingInterface
|
||||||
|
+ maxRetries int
|
||||||
|
maxEndPointsPerSlice int
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -65,8 +65,9 @@ func NewKubevirtEPSController(
|
||||||
|
tenantClient kubernetes.Interface,
|
||||||
|
infraClient kubernetes.Interface,
|
||||||
|
infraDynamic dynamic.Interface,
|
||||||
|
- infraNamespace string) *Controller {
|
||||||
|
-
|
||||||
|
+ infraNamespace string,
|
||||||
|
+ clusterName string,
|
||||||
|
+) *Controller {
|
||||||
|
tenantFactory := informers.NewSharedInformerFactory(tenantClient, 0)
|
||||||
|
infraFactory := informers.NewSharedInformerFactoryWithOptions(infraClient, 0, informers.WithNamespace(infraNamespace))
|
||||||
|
queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
|
||||||
|
@@ -79,6 +80,7 @@ func NewKubevirtEPSController(
|
||||||
|
infraDynamic: infraDynamic,
|
||||||
|
infraFactory: infraFactory,
|
||||||
|
infraNamespace: infraNamespace,
|
||||||
|
+ clusterName: clusterName,
|
||||||
|
queue: queue,
|
||||||
|
maxRetries: 25,
|
||||||
|
maxEndPointsPerSlice: 100,
|
||||||
|
@@ -320,22 +322,30 @@ func (c *Controller) processNextItem(ctx context.Context) bool {
|
||||||
|
|
||||||
|
// getInfraServiceFromTenantEPS returns the Service in the infra cluster that is associated with the given tenant endpoint slice.
|
||||||
|
func (c *Controller) getInfraServiceFromTenantEPS(ctx context.Context, slice *discovery.EndpointSlice) (*v1.Service, error) {
|
||||||
|
- infraServices, err := c.infraClient.CoreV1().Services(c.infraNamespace).List(ctx,
|
||||||
|
- metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s,%s=%s", kubevirt.TenantServiceNameLabelKey, slice.Labels["kubernetes.io/service-name"],
|
||||||
|
- kubevirt.TenantServiceNamespaceLabelKey, slice.Namespace)})
|
||||||
|
+ tenantServiceName := slice.Labels[discovery.LabelServiceName]
|
||||||
|
+ tenantServiceNamespace := slice.Namespace
|
||||||
|
+
|
||||||
|
+ labelSelector := fmt.Sprintf(
|
||||||
|
+ "%s=%s,%s=%s,%s=%s",
|
||||||
|
+ kubevirt.TenantServiceNameLabelKey, tenantServiceName,
|
||||||
|
+ kubevirt.TenantServiceNamespaceLabelKey, tenantServiceNamespace,
|
||||||
|
+ kubevirt.TenantClusterNameLabelKey, c.clusterName,
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ svcList, err := c.infraClient.CoreV1().Services(c.infraNamespace).List(ctx, metav1.ListOptions{
|
||||||
|
+ LabelSelector: labelSelector,
|
||||||
|
+ })
|
||||||
|
if err != nil {
|
||||||
|
- klog.Errorf("Failed to get Service in Infra for EndpointSlice %s in namespace %s: %v", slice.Name, slice.Namespace, err)
|
||||||
|
+ klog.Errorf("Failed to get Service in Infra for EndpointSlice %s in namespace %s: %v", slice.Name, tenantServiceNamespace, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
- if len(infraServices.Items) > 1 {
|
||||||
|
- // This should never be possible, only one service should exist for a given tenant endpoint slice
|
||||||
|
- klog.Errorf("Multiple services found for tenant endpoint slice %s in namespace %s", slice.Name, slice.Namespace)
|
||||||
|
+ if len(svcList.Items) > 1 {
|
||||||
|
+ klog.Errorf("Multiple services found for tenant endpoint slice %s in namespace %s", slice.Name, tenantServiceNamespace)
|
||||||
|
return nil, errors.New("multiple services found for tenant endpoint slice")
|
||||||
|
}
|
||||||
|
- if len(infraServices.Items) == 1 {
|
||||||
|
- return &infraServices.Items[0], nil
|
||||||
|
+ if len(svcList.Items) == 1 {
|
||||||
|
+ return &svcList.Items[0], nil
|
||||||
|
}
|
||||||
|
- // No service found, possible if service is deleted.
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -363,16 +373,27 @@ func (c *Controller) getTenantEPSFromInfraService(ctx context.Context, svc *v1.S
|
||||||
|
// getInfraEPSFromInfraService returns the EndpointSlices in the infra cluster that are associated with the given infra service.
|
||||||
|
func (c *Controller) getInfraEPSFromInfraService(ctx context.Context, svc *v1.Service) ([]*discovery.EndpointSlice, error) {
|
||||||
|
var infraEPSSlices []*discovery.EndpointSlice
|
||||||
|
- klog.Infof("Searching for endpoints on infra cluster for service %s in namespace %s.", svc.Name, svc.Namespace)
|
||||||
|
- result, err := c.infraClient.DiscoveryV1().EndpointSlices(svc.Namespace).List(ctx,
|
||||||
|
- metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", discovery.LabelServiceName, svc.Name)})
|
||||||
|
+
|
||||||
|
+ klog.Infof("Searching for EndpointSlices in infra cluster for service %s/%s", svc.Namespace, svc.Name)
|
||||||
|
+
|
||||||
|
+ labelSelector := fmt.Sprintf(
|
||||||
|
+ "%s=%s,%s=%s",
|
||||||
|
+ discovery.LabelServiceName, svc.Name,
|
||||||
|
+ kubevirt.TenantClusterNameLabelKey, c.clusterName,
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ result, err := c.infraClient.DiscoveryV1().EndpointSlices(svc.Namespace).List(ctx, metav1.ListOptions{
|
||||||
|
+ LabelSelector: labelSelector,
|
||||||
|
+ })
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Failed to get EndpointSlices for Service %s in namespace %s: %v", svc.Name, svc.Namespace, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
+
|
||||||
|
for _, eps := range result.Items {
|
||||||
|
infraEPSSlices = append(infraEPSSlices, &eps)
|
||||||
|
}
|
||||||
|
+
|
||||||
|
return infraEPSSlices, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -382,74 +403,117 @@ func (c *Controller) reconcile(ctx context.Context, r *Request) error {
|
||||||
|
return errors.New("could not cast object to service")
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Skip services not managed by this controller (missing required labels)
|
||||||
|
if service.Labels[kubevirt.TenantServiceNameLabelKey] == "" ||
|
||||||
|
service.Labels[kubevirt.TenantServiceNamespaceLabelKey] == "" ||
|
||||||
|
service.Labels[kubevirt.TenantClusterNameLabelKey] == "" {
|
||||||
|
- klog.Infof("This LoadBalancer Service: %s is not managed by the %s. Skipping.", service.Name, ControllerName)
|
||||||
|
+ klog.Infof("Service %s is not managed by this controller. Skipping.", service.Name)
|
||||||
|
+ return nil
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Skip services for other clusters
|
||||||
|
+ if service.Labels[kubevirt.TenantClusterNameLabelKey] != c.clusterName {
|
||||||
|
+ klog.Infof("Skipping Service %s: cluster label %q doesn't match our clusterName %q", service.Name, service.Labels[kubevirt.TenantClusterNameLabelKey], c.clusterName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
+
|
||||||
|
klog.Infof("Reconciling: %v", service.Name)
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ 1) Check if Service in the infra cluster is actually present.
|
||||||
|
+ If it's not found, mark it as 'deleted' so that we don't create new slices.
|
||||||
|
+ */
|
||||||
|
serviceDeleted := false
|
||||||
|
- svc, err := c.infraFactory.Core().V1().Services().Lister().Services(c.infraNamespace).Get(service.Name)
|
||||||
|
+ infraSvc, err := c.infraFactory.Core().V1().Services().Lister().Services(c.infraNamespace).Get(service.Name)
|
||||||
|
if err != nil {
|
||||||
|
- klog.Infof("Service %s in namespace %s is deleted.", service.Name, service.Namespace)
|
||||||
|
+ // The Service is not present in the infra lister => treat as deleted
|
||||||
|
+ klog.Infof("Service %s in namespace %s is deleted (or not found).", service.Name, service.Namespace)
|
||||||
|
serviceDeleted = true
|
||||||
|
} else {
|
||||||
|
- service = svc
|
||||||
|
+ // Use the actual object from the lister, so we have the latest state
|
||||||
|
+ service = infraSvc
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ 2) Get all existing EndpointSlices in the infra cluster that belong to this LB Service.
|
||||||
|
+ We'll decide which of them should be updated or deleted.
|
||||||
|
+ */
|
||||||
|
infraExistingEpSlices, err := c.getInfraEPSFromInfraService(ctx, service)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
- // At this point we have the current state of the 3 main objects we are interested in:
|
||||||
|
- // 1. The Service in the infra cluster, the one created by the KubevirtCloudController.
|
||||||
|
- // 2. The EndpointSlices in the tenant cluster, created for the tenant cluster's Service.
|
||||||
|
- // 3. The EndpointSlices in the infra cluster, managed by this controller.
|
||||||
|
-
|
||||||
|
slicesToDelete := []*discovery.EndpointSlice{}
|
||||||
|
slicesByAddressType := make(map[discovery.AddressType][]*discovery.EndpointSlice)
|
||||||
|
|
||||||
|
+ // For example, if the service is single-stack IPv4 => only AddressTypeIPv4
|
||||||
|
+ // or if dual-stack => IPv4 and IPv6, etc.
|
||||||
|
serviceSupportedAddressesTypes := getAddressTypesForService(service)
|
||||||
|
- // If the services switched to a different address type, we need to delete the old ones, because it's immutable.
|
||||||
|
- // If the services switched to a different externalTrafficPolicy, we need to delete the old ones.
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ 3) Determine which slices to delete, and which to pass on to the normal
|
||||||
|
+ "reconcileByAddressType" logic.
|
||||||
|
+
|
||||||
|
+ - If 'serviceDeleted' is true OR service.Spec.Selector != nil, we remove them.
|
||||||
|
+ - Also, if the slice's address type is unsupported by the Service, we remove it.
|
||||||
|
+ */
|
||||||
|
for _, eps := range infraExistingEpSlices {
|
||||||
|
- if service.Spec.Selector != nil || serviceDeleted {
|
||||||
|
- klog.Infof("Added for deletion EndpointSlice %s in namespace %s because it has a selector", eps.Name, eps.Namespace)
|
||||||
|
- // to be sure we don't delete any slice that is not managed by us
|
||||||
|
+ // If service is deleted or has a non-nil selector => remove slices
|
||||||
|
+ if serviceDeleted || service.Spec.Selector != nil {
|
||||||
|
+ /*
|
||||||
|
+ Only remove if it is clearly labeled as managed by us:
|
||||||
|
+ we do not want to accidentally remove slices that are not
|
||||||
|
+ created by this controller.
|
||||||
|
+ */
|
||||||
|
if c.managedByController(eps) {
|
||||||
|
+ klog.Infof("Added for deletion EndpointSlice %s in namespace %s because service is deleted or has a selector",
|
||||||
|
+ eps.Name, eps.Namespace)
|
||||||
|
slicesToDelete = append(slicesToDelete, eps)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // If the Service does not support this slice's AddressType => remove
|
||||||
|
if !serviceSupportedAddressesTypes.Has(eps.AddressType) {
|
||||||
|
- klog.Infof("Added for deletion EndpointSlice %s in namespace %s because it has an unsupported address type: %v", eps.Name, eps.Namespace, eps.AddressType)
|
||||||
|
+ klog.Infof("Added for deletion EndpointSlice %s in namespace %s because it has an unsupported address type: %v",
|
||||||
|
+ eps.Name, eps.Namespace, eps.AddressType)
|
||||||
|
slicesToDelete = append(slicesToDelete, eps)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ Otherwise, this slice is potentially still valid for the given AddressType,
|
||||||
|
+ we'll send it to reconcileByAddressType for final merging and updates.
|
||||||
|
+ */
|
||||||
|
slicesByAddressType[eps.AddressType] = append(slicesByAddressType[eps.AddressType], eps)
|
||||||
|
}
|
||||||
|
|
||||||
|
- if !serviceDeleted {
|
||||||
|
- // Get tenant's endpoint slices for this service
|
||||||
|
+ /*
|
||||||
|
+ 4) If the Service was NOT deleted and has NO selector (i.e., it's a "no-selector" LB Service),
|
||||||
|
+ we proceed to handle creation and updates. That means:
|
||||||
|
+ - Gather Tenant's EndpointSlices
|
||||||
|
+ - Reconcile them by each AddressType
|
||||||
|
+ */
|
||||||
|
+ if !serviceDeleted && service.Spec.Selector == nil {
|
||||||
|
tenantEpSlices, err := c.getTenantEPSFromInfraService(ctx, service)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Reconcile the EndpointSlices for each address type e.g. ipv4, ipv6
|
||||||
|
+ // For each addressType (ipv4, ipv6, etc.) reconcile the infra slices
|
||||||
|
for addressType := range serviceSupportedAddressesTypes {
|
||||||
|
existingSlices := slicesByAddressType[addressType]
|
||||||
|
- err := c.reconcileByAddressType(service, tenantEpSlices, existingSlices, addressType)
|
||||||
|
- if err != nil {
|
||||||
|
+ if err := c.reconcileByAddressType(service, tenantEpSlices, existingSlices, addressType); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Delete the EndpointSlices that are no longer needed
|
||||||
|
+ /*
|
||||||
|
+ 5) Perform the actual deletion of all slices we flagged.
|
||||||
|
+ In many cases (serviceDeleted or .Spec.Selector != nil),
|
||||||
|
+ we end up with only "delete" actions and no new slice creation.
|
||||||
|
+ */
|
||||||
|
for _, eps := range slicesToDelete {
|
||||||
|
err := c.infraClient.DiscoveryV1().EndpointSlices(eps.Namespace).Delete(context.TODO(), eps.Name, metav1.DeleteOptions{})
|
||||||
|
if err != nil {
|
||||||
|
@@ -474,11 +538,11 @@ func (c *Controller) reconcileByAddressType(service *v1.Service, tenantSlices []
|
||||||
|
// Create the desired port configuration
|
||||||
|
var desiredPorts []discovery.EndpointPort
|
||||||
|
|
||||||
|
- for _, port := range service.Spec.Ports {
|
||||||
|
+ for i := range service.Spec.Ports {
|
||||||
|
desiredPorts = append(desiredPorts, discovery.EndpointPort{
|
||||||
|
- Port: &port.TargetPort.IntVal,
|
||||||
|
- Protocol: &port.Protocol,
|
||||||
|
- Name: &port.Name,
|
||||||
|
+ Port: &service.Spec.Ports[i].TargetPort.IntVal,
|
||||||
|
+ Protocol: &service.Spec.Ports[i].Protocol,
|
||||||
|
+ Name: &service.Spec.Ports[i].Name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -588,55 +652,114 @@ func ownedBy(endpointSlice *discovery.EndpointSlice, svc *v1.Service) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
-func (c *Controller) finalize(service *v1.Service, slicesToCreate []*discovery.EndpointSlice, slicesToUpdate []*discovery.EndpointSlice, slicesToDelete []*discovery.EndpointSlice) error {
|
||||||
|
- // If there are slices to delete and slices to create, make them as update
|
||||||
|
- for i := 0; i < len(slicesToDelete); {
|
||||||
|
+func (c *Controller) finalize(
|
||||||
|
+ service *v1.Service,
|
||||||
|
+ slicesToCreate []*discovery.EndpointSlice,
|
||||||
|
+ slicesToUpdate []*discovery.EndpointSlice,
|
||||||
|
+ slicesToDelete []*discovery.EndpointSlice,
|
||||||
|
+) error {
|
||||||
|
+ /*
|
||||||
|
+ We try to turn a "delete + create" pair into a single "update" operation
|
||||||
|
+ if the original slice (slicesToDelete[i]) has the same address type as
|
||||||
|
+ the first slice in slicesToCreate, and is owned by the same Service.
|
||||||
|
+
|
||||||
|
+ However, we must re-check the lengths of slicesToDelete and slicesToCreate
|
||||||
|
+ within the loop to avoid an out-of-bounds index in slicesToCreate.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ i := 0
|
||||||
|
+ for i < len(slicesToDelete) {
|
||||||
|
+ // If there is nothing to create, break early
|
||||||
|
if len(slicesToCreate) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
- if slicesToDelete[i].AddressType == slicesToCreate[0].AddressType && ownedBy(slicesToDelete[i], service) {
|
||||||
|
- slicesToCreate[0].Name = slicesToDelete[i].Name
|
||||||
|
+
|
||||||
|
+ sd := slicesToDelete[i]
|
||||||
|
+ sc := slicesToCreate[0] // We can safely do this now, because len(slicesToCreate) > 0
|
||||||
|
+
|
||||||
|
+ // If the address type matches, and the slice is owned by the same Service,
|
||||||
|
+ // then instead of deleting sd and creating sc, we'll transform it into an update:
|
||||||
|
+ // we rename sc with sd's name, remove sd from the delete list, remove sc from the create list,
|
||||||
|
+ // and add sc to the update list.
|
||||||
|
+ if sd.AddressType == sc.AddressType && ownedBy(sd, service) {
|
||||||
|
+ sliceToUpdate := sc
|
||||||
|
+ sliceToUpdate.Name = sd.Name
|
||||||
|
+
|
||||||
|
+ // Remove the first element from slicesToCreate
|
||||||
|
slicesToCreate = slicesToCreate[1:]
|
||||||
|
- slicesToUpdate = append(slicesToUpdate, slicesToCreate[0])
|
||||||
|
+
|
||||||
|
+ // Remove the slice from slicesToDelete
|
||||||
|
slicesToDelete = append(slicesToDelete[:i], slicesToDelete[i+1:]...)
|
||||||
|
+
|
||||||
|
+ // Now add the renamed slice to the list of slices we want to update
|
||||||
|
+ slicesToUpdate = append(slicesToUpdate, sliceToUpdate)
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ Do not increment i here, because we've just removed an element from
|
||||||
|
+ slicesToDelete. The next slice to examine is now at the same index i.
|
||||||
|
+ */
|
||||||
|
} else {
|
||||||
|
+ // If they don't match, move on to the next slice in slicesToDelete.
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Create the new slices if service is not marked for deletion
|
||||||
|
+ /*
|
||||||
|
+ If the Service is not being deleted, create all remaining slices in slicesToCreate.
|
||||||
|
+ (If the Service has a DeletionTimestamp, it means it is going away, so we do not
|
||||||
|
+ want to create new EndpointSlices.)
|
||||||
|
+ */
|
||||||
|
if service.DeletionTimestamp == nil {
|
||||||
|
for _, slice := range slicesToCreate {
|
||||||
|
- createdSlice, err := c.infraClient.DiscoveryV1().EndpointSlices(slice.Namespace).Create(context.TODO(), slice, metav1.CreateOptions{})
|
||||||
|
+ createdSlice, err := c.infraClient.DiscoveryV1().EndpointSlices(slice.Namespace).Create(
|
||||||
|
+ context.TODO(),
|
||||||
|
+ slice,
|
||||||
|
+ metav1.CreateOptions{},
|
||||||
|
+ )
|
||||||
|
if err != nil {
|
||||||
|
- klog.Errorf("Failed to create EndpointSlice %s in namespace %s: %v", slice.Name, slice.Namespace, err)
|
||||||
|
+ klog.Errorf("Failed to create EndpointSlice %s in namespace %s: %v",
|
||||||
|
+ slice.Name, slice.Namespace, err)
|
||||||
|
+ // If the namespace is terminating, it's safe to ignore the error.
|
||||||
|
if k8serrors.HasStatusCause(err, v1.NamespaceTerminatingCause) {
|
||||||
|
- return nil
|
||||||
|
+ continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
- klog.Infof("Created EndpointSlice %s in namespace %s", createdSlice.Name, createdSlice.Namespace)
|
||||||
|
+ klog.Infof("Created EndpointSlice %s in namespace %s",
|
||||||
|
+ createdSlice.Name, createdSlice.Namespace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Update slices
|
||||||
|
+ // Update slices that are in the slicesToUpdate list.
|
||||||
|
for _, slice := range slicesToUpdate {
|
||||||
|
- _, err := c.infraClient.DiscoveryV1().EndpointSlices(slice.Namespace).Update(context.TODO(), slice, metav1.UpdateOptions{})
|
||||||
|
+ _, err := c.infraClient.DiscoveryV1().EndpointSlices(slice.Namespace).Update(
|
||||||
|
+ context.TODO(),
|
||||||
|
+ slice,
|
||||||
|
+ metav1.UpdateOptions{},
|
||||||
|
+ )
|
||||||
|
if err != nil {
|
||||||
|
- klog.Errorf("Failed to update EndpointSlice %s in namespace %s: %v", slice.Name, slice.Namespace, err)
|
||||||
|
+ klog.Errorf("Failed to update EndpointSlice %s in namespace %s: %v",
|
||||||
|
+ slice.Name, slice.Namespace, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
- klog.Infof("Updated EndpointSlice %s in namespace %s", slice.Name, slice.Namespace)
|
||||||
|
+ klog.Infof("Updated EndpointSlice %s in namespace %s",
|
||||||
|
+ slice.Name, slice.Namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
- // Delete slices
|
||||||
|
+ // Finally, delete slices that are in slicesToDelete and are no longer needed.
|
||||||
|
for _, slice := range slicesToDelete {
|
||||||
|
- err := c.infraClient.DiscoveryV1().EndpointSlices(slice.Namespace).Delete(context.TODO(), slice.Name, metav1.DeleteOptions{})
|
||||||
|
+ err := c.infraClient.DiscoveryV1().EndpointSlices(slice.Namespace).Delete(
|
||||||
|
+ context.TODO(),
|
||||||
|
+ slice.Name,
|
||||||
|
+ metav1.DeleteOptions{},
|
||||||
|
+ )
|
||||||
|
if err != nil {
|
||||||
|
- klog.Errorf("Failed to delete EndpointSlice %s in namespace %s: %v", slice.Name, slice.Namespace, err)
|
||||||
|
+ klog.Errorf("Failed to delete EndpointSlice %s in namespace %s: %v",
|
||||||
|
+ slice.Name, slice.Namespace, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
- klog.Infof("Deleted EndpointSlice %s in namespace %s", slice.Name, slice.Namespace)
|
||||||
|
+ klog.Infof("Deleted EndpointSlice %s in namespace %s",
|
||||||
|
+ slice.Name, slice.Namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
diff --git a/pkg/controller/kubevirteps/kubevirteps_controller_test.go b/pkg/controller/kubevirteps/kubevirteps_controller_test.go
|
||||||
|
index 1fb86e25f..14d92d340 100644
|
||||||
|
--- a/pkg/controller/kubevirteps/kubevirteps_controller_test.go
|
||||||
|
+++ b/pkg/controller/kubevirteps/kubevirteps_controller_test.go
|
||||||
|
@@ -13,6 +13,7 @@ import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
+ "k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
dfake "k8s.io/client-go/dynamic/fake"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
"k8s.io/client-go/testing"
|
||||||
|
@@ -189,7 +190,7 @@ func setupTestKubevirtEPSController() *testKubevirtEPSController {
|
||||||
|
}: "VirtualMachineInstanceList",
|
||||||
|
})
|
||||||
|
|
||||||
|
- controller := NewKubevirtEPSController(tenantClient, infraClient, infraDynamic, "test")
|
||||||
|
+ controller := NewKubevirtEPSController(tenantClient, infraClient, infraDynamic, "test", "test-cluster")
|
||||||
|
|
||||||
|
err := controller.Init()
|
||||||
|
if err != nil {
|
||||||
|
@@ -686,5 +687,229 @@ var _ = g.Describe("KubevirtEPSController", g.Ordered, func() {
|
||||||
|
return false, err
|
||||||
|
}).Should(BeTrue(), "EndpointSlice in infra cluster should be recreated by the controller after deletion")
|
||||||
|
})
|
||||||
|
+
|
||||||
|
+ g.It("Should correctly handle multiple unique ports in EndpointSlice", func() {
|
||||||
|
+ // Create a VMI in the infra cluster
|
||||||
|
+ createAndAssertVMI("worker-0-test", "ip-10-32-5-13", "123.45.67.89")
|
||||||
|
+
|
||||||
|
+ // Create an EndpointSlice in the tenant cluster
|
||||||
|
+ createAndAssertTenantSlice("test-epslice", "tenant-service-name", discoveryv1.AddressTypeIPv4,
|
||||||
|
+ *createPort("http", 80, v1.ProtocolTCP),
|
||||||
|
+ []discoveryv1.Endpoint{*createEndpoint("123.45.67.89", "worker-0-test", true, true, false)})
|
||||||
|
+
|
||||||
|
+ // Define multiple ports for the Service
|
||||||
|
+ servicePorts := []v1.ServicePort{
|
||||||
|
+ {
|
||||||
|
+ Name: "client",
|
||||||
|
+ Protocol: v1.ProtocolTCP,
|
||||||
|
+ Port: 10001,
|
||||||
|
+ TargetPort: intstr.FromInt(30396),
|
||||||
|
+ NodePort: 30396,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ Name: "dashboard",
|
||||||
|
+ Protocol: v1.ProtocolTCP,
|
||||||
|
+ Port: 8265,
|
||||||
|
+ TargetPort: intstr.FromInt(31003),
|
||||||
|
+ NodePort: 31003,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ Name: "metrics",
|
||||||
|
+ Protocol: v1.ProtocolTCP,
|
||||||
|
+ Port: 8080,
|
||||||
|
+ TargetPort: intstr.FromInt(30452),
|
||||||
|
+ NodePort: 30452,
|
||||||
|
+ },
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ createAndAssertInfraServiceLB("infra-multiport-service", "tenant-service-name", "test-cluster",
|
||||||
|
+ servicePorts[0], v1.ServiceExternalTrafficPolicyLocal)
|
||||||
|
+
|
||||||
|
+ svc, err := testVals.infraClient.CoreV1().Services(infraNamespace).Get(context.TODO(), "infra-multiport-service", metav1.GetOptions{})
|
||||||
|
+ Expect(err).To(BeNil())
|
||||||
|
+
|
||||||
|
+ svc.Spec.Ports = servicePorts
|
||||||
|
+ _, err = testVals.infraClient.CoreV1().Services(infraNamespace).Update(context.TODO(), svc, metav1.UpdateOptions{})
|
||||||
|
+ Expect(err).To(BeNil())
|
||||||
|
+
|
||||||
|
+ var epsListMultiPort *discoveryv1.EndpointSliceList
|
||||||
|
+
|
||||||
|
+ Eventually(func() (bool, error) {
|
||||||
|
+ epsListMultiPort, err = testVals.infraClient.DiscoveryV1().EndpointSlices(infraNamespace).List(context.TODO(), metav1.ListOptions{})
|
||||||
|
+ if len(epsListMultiPort.Items) != 1 {
|
||||||
|
+ return false, err
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ createdSlice := epsListMultiPort.Items[0]
|
||||||
|
+ expectedPortNames := []string{"client", "dashboard", "metrics"}
|
||||||
|
+ foundPortNames := []string{}
|
||||||
|
+
|
||||||
|
+ for _, port := range createdSlice.Ports {
|
||||||
|
+ if port.Name != nil {
|
||||||
|
+ foundPortNames = append(foundPortNames, *port.Name)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if len(foundPortNames) != len(expectedPortNames) {
|
||||||
|
+ return false, err
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ portSet := sets.NewString(foundPortNames...)
|
||||||
|
+ expectedPortSet := sets.NewString(expectedPortNames...)
|
||||||
|
+ return portSet.Equal(expectedPortSet), err
|
||||||
|
+ }).Should(BeTrue(), "EndpointSlice should contain all unique ports from the Service without duplicates")
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ g.It("Should not panic when Service changes to have a non-nil selector, causing EndpointSlice deletion with no new slices to create", func() {
|
||||||
|
+ createAndAssertVMI("worker-0-test", "ip-10-32-5-13", "123.45.67.89")
|
||||||
|
+ createAndAssertTenantSlice("test-epslice", "tenant-service-name", discoveryv1.AddressTypeIPv4,
|
||||||
|
+ *createPort("http", 80, v1.ProtocolTCP),
|
||||||
|
+ []discoveryv1.Endpoint{*createEndpoint("123.45.67.89", "worker-0-test", true, true, false)})
|
||||||
|
+ createAndAssertInfraServiceLB("infra-service-no-selector", "tenant-service-name", "test-cluster",
|
||||||
|
+ v1.ServicePort{
|
||||||
|
+ Name: "web",
|
||||||
|
+ Port: 80,
|
||||||
|
+ NodePort: 31900,
|
||||||
|
+ Protocol: v1.ProtocolTCP,
|
||||||
|
+ TargetPort: intstr.IntOrString{IntVal: 30390},
|
||||||
|
+ },
|
||||||
|
+ v1.ServiceExternalTrafficPolicyLocal,
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ // Wait for the controller to create an EndpointSlice in the infra cluster.
|
||||||
|
+ var epsList *discoveryv1.EndpointSliceList
|
||||||
|
+ var err error
|
||||||
|
+ Eventually(func() (bool, error) {
|
||||||
|
+ epsList, err = testVals.infraClient.DiscoveryV1().EndpointSlices(infraNamespace).
|
||||||
|
+ List(context.TODO(), metav1.ListOptions{})
|
||||||
|
+ if err != nil {
|
||||||
|
+ return false, err
|
||||||
|
+ }
|
||||||
|
+ // Wait exactly 1 slice
|
||||||
|
+ if len(epsList.Items) == 1 {
|
||||||
|
+ return true, nil
|
||||||
|
+ }
|
||||||
|
+ return false, nil
|
||||||
|
+ }).Should(BeTrue(), "Controller should create an EndpointSlice in infra cluster for the LB service")
|
||||||
|
+
|
||||||
|
+ svcWithSelector, err := testVals.infraClient.CoreV1().Services(infraNamespace).
|
||||||
|
+ Get(context.TODO(), "infra-service-no-selector", metav1.GetOptions{})
|
||||||
|
+ Expect(err).To(BeNil())
|
||||||
|
+
|
||||||
|
+ // Let's set any selector to run the slice deletion logic
|
||||||
|
+ svcWithSelector.Spec.Selector = map[string]string{"test": "selector-added"}
|
||||||
|
+ _, err = testVals.infraClient.CoreV1().Services(infraNamespace).
|
||||||
|
+ Update(context.TODO(), svcWithSelector, metav1.UpdateOptions{})
|
||||||
|
+ Expect(err).To(BeNil())
|
||||||
|
+
|
||||||
|
+ Eventually(func() (bool, error) {
|
||||||
|
+ epsList, err = testVals.infraClient.DiscoveryV1().EndpointSlices(infraNamespace).
|
||||||
|
+ List(context.TODO(), metav1.ListOptions{})
|
||||||
|
+ if err != nil {
|
||||||
|
+ return false, err
|
||||||
|
+ }
|
||||||
|
+ // We expect that after the update service.EndpointSlice will become 0
|
||||||
|
+ if len(epsList.Items) == 0 {
|
||||||
|
+ return true, nil
|
||||||
|
+ }
|
||||||
|
+ return false, nil
|
||||||
|
+ }).Should(BeTrue(), "Existing EndpointSlice should be removed because Service now has a selector")
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ g.It("Should remove EndpointSlices and not recreate them when a previously no-selector Service obtains a selector", func() {
|
||||||
|
+ testVals.infraClient.Fake.PrependReactor("create", "endpointslices", func(action testing.Action) (bool, runtime.Object, error) {
|
||||||
|
+ createAction := action.(testing.CreateAction)
|
||||||
|
+ slice := createAction.GetObject().(*discoveryv1.EndpointSlice)
|
||||||
|
+ if slice.Name == "" && slice.GenerateName != "" {
|
||||||
|
+ slice.Name = slice.GenerateName + "-fake001"
|
||||||
|
+ }
|
||||||
|
+ return false, slice, nil
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ createAndAssertVMI("worker-0-test", "ip-10-32-5-13", "123.45.67.89")
|
||||||
|
+
|
||||||
|
+ createAndAssertTenantSlice("test-epslice", "tenant-service-name", discoveryv1.AddressTypeIPv4,
|
||||||
|
+ *createPort("http", 80, v1.ProtocolTCP),
|
||||||
|
+ []discoveryv1.Endpoint{
|
||||||
|
+ *createEndpoint("123.45.67.89", "worker-0-test", true, true, false),
|
||||||
|
+ },
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ noSelectorSvcName := "svc-without-selector"
|
||||||
|
+ svc := &v1.Service{
|
||||||
|
+ ObjectMeta: metav1.ObjectMeta{
|
||||||
|
+ Name: noSelectorSvcName,
|
||||||
|
+ Namespace: infraNamespace,
|
||||||
|
+ Labels: map[string]string{
|
||||||
|
+ kubevirt.TenantServiceNameLabelKey: "tenant-service-name",
|
||||||
|
+ kubevirt.TenantServiceNamespaceLabelKey: tenantNamespace,
|
||||||
|
+ kubevirt.TenantClusterNameLabelKey: "test-cluster",
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ Spec: v1.ServiceSpec{
|
||||||
|
+ Ports: []v1.ServicePort{
|
||||||
|
+ {
|
||||||
|
+ Name: "web",
|
||||||
|
+ Port: 80,
|
||||||
|
+ NodePort: 31900,
|
||||||
|
+ Protocol: v1.ProtocolTCP,
|
||||||
|
+ TargetPort: intstr.IntOrString{IntVal: 30390},
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ Type: v1.ServiceTypeLoadBalancer,
|
||||||
|
+ ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal,
|
||||||
|
+ },
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _, err := testVals.infraClient.CoreV1().Services(infraNamespace).Create(context.TODO(), svc, metav1.CreateOptions{})
|
||||||
|
+ Expect(err).To(BeNil())
|
||||||
|
+
|
||||||
|
+ Eventually(func() (bool, error) {
|
||||||
|
+ epsList, err := testVals.infraClient.DiscoveryV1().EndpointSlices(infraNamespace).
|
||||||
|
+ List(context.TODO(), metav1.ListOptions{})
|
||||||
|
+ if err != nil {
|
||||||
|
+ return false, err
|
||||||
|
+ }
|
||||||
|
+ return len(epsList.Items) == 1, nil
|
||||||
|
+ }).Should(BeTrue(), "Controller should create an EndpointSlice in infra cluster for the no-selector LB service")
|
||||||
|
+
|
||||||
|
+ svcWithSelector, err := testVals.infraClient.CoreV1().Services(infraNamespace).Get(
|
||||||
|
+ context.TODO(), noSelectorSvcName, metav1.GetOptions{})
|
||||||
|
+ Expect(err).To(BeNil())
|
||||||
|
+
|
||||||
|
+ svcWithSelector.Spec.Selector = map[string]string{"app": "test-value"}
|
||||||
|
+ _, err = testVals.infraClient.CoreV1().Services(infraNamespace).
|
||||||
|
+ Update(context.TODO(), svcWithSelector, metav1.UpdateOptions{})
|
||||||
|
+ Expect(err).To(BeNil())
|
||||||
|
+
|
||||||
|
+ Eventually(func() (bool, error) {
|
||||||
|
+ epsList, err := testVals.infraClient.DiscoveryV1().EndpointSlices(infraNamespace).
|
||||||
|
+ List(context.TODO(), metav1.ListOptions{})
|
||||||
|
+ if err != nil {
|
||||||
|
+ return false, err
|
||||||
|
+ }
|
||||||
|
+ return len(epsList.Items) == 0, nil
|
||||||
|
+ }).Should(BeTrue(), "All EndpointSlices should be removed after Service acquires a selector (no new slices created)")
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ g.It("Should ignore Services from a different cluster", func() {
|
||||||
|
+ // Create a Service with cluster label "other-cluster"
|
||||||
|
+ svc := createInfraServiceLB("infra-service-conflict", "tenant-service-name", "other-cluster",
|
||||||
|
+ v1.ServicePort{Name: "web", Port: 80, NodePort: 31900, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{IntVal: 30390}},
|
||||||
|
+ v1.ServiceExternalTrafficPolicyLocal)
|
||||||
|
+ _, err := testVals.infraClient.CoreV1().Services(infraNamespace).Create(context.TODO(), svc, metav1.CreateOptions{})
|
||||||
|
+ Expect(err).To(BeNil())
|
||||||
|
+
|
||||||
|
+ // The controller should ignore this Service, so no EndpointSlice should be created.
|
||||||
|
+ Eventually(func() (bool, error) {
|
||||||
|
+ epsList, err := testVals.infraClient.DiscoveryV1().EndpointSlices(infraNamespace).List(context.TODO(), metav1.ListOptions{})
|
||||||
|
+ if err != nil {
|
||||||
|
+ return false, err
|
||||||
|
+ }
|
||||||
|
+ // Expect zero slices since cluster label does not match "test-cluster"
|
||||||
|
+ return len(epsList.Items) == 0, nil
|
||||||
|
+ }).Should(BeTrue(), "Services with a different cluster label should be ignored")
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.15.2@sha256:cb4ab74099662f73e058f7c7495fb403488622c3425c06ad23b687bfa8bc805b
|
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.17.0@sha256:1a6605d3bff6342e12bcc257e852a4f89e97e8af6d3d259930ec07c7ad5f001d
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/ubuntu-container-disk:v1.30.1@sha256:bc08ea0ced2cb7dd98b26d72a9462fc0a3863adb908a5effbfcdf7227656ea65
|
ghcr.io/cozystack/cozystack/ubuntu-container-disk:v1.30.1@sha256:d842de4637ea6188999464f133c89f63a3bd13f1cb202c10f1f8c0c1c3c3dbd4
|
||||||
|
|||||||
50
packages/apps/kubernetes/templates/_resources.tpl
Normal file
50
packages/apps/kubernetes/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -26,6 +26,13 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- image: "{{ $.Files.Get "images/cluster-autoscaler.tag" | trim }}"
|
- image: "{{ $.Files.Get "images/cluster-autoscaler.tag" | trim }}"
|
||||||
name: cluster-autoscaler
|
name: cluster-autoscaler
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 512m
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: 125m
|
||||||
|
memory: 128Mi
|
||||||
command:
|
command:
|
||||||
- /cluster-autoscaler
|
- /cluster-autoscaler
|
||||||
args:
|
args:
|
||||||
|
|||||||
@@ -102,12 +102,37 @@ metadata:
|
|||||||
annotations:
|
annotations:
|
||||||
kamaji.clastix.io/kubeconfig-secret-key: "super-admin.svc"
|
kamaji.clastix.io/kubeconfig-secret-key: "super-admin.svc"
|
||||||
spec:
|
spec:
|
||||||
|
apiServer:
|
||||||
|
{{- if .Values.kamajiControlPlane.apiServer.resources }}
|
||||||
|
resources: {{- toYaml .Values.kamajiControlPlane.apiServer.resources | nindent 6 }}
|
||||||
|
{{- else if ne .Values.kamajiControlPlane.apiServer.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.kamajiControlPlane.apiServer.resourcesPreset "Release" .Release) | nindent 6 }}
|
||||||
|
{{- end }}
|
||||||
|
controllerManager:
|
||||||
|
{{- if .Values.kamajiControlPlane.controllerManager.resources }}
|
||||||
|
resources: {{- toYaml .Values.kamajiControlPlane.controllerManager.resources | nindent 6 }}
|
||||||
|
{{- else if ne .Values.kamajiControlPlane.controllerManager.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.kamajiControlPlane.controllerManager.resourcesPreset "Release" .Release) | nindent 6 }}
|
||||||
|
{{- end }}
|
||||||
|
scheduler:
|
||||||
|
{{- if .Values.kamajiControlPlane.scheduler.resources }}
|
||||||
|
resources: {{- toYaml .Values.kamajiControlPlane.scheduler.resources | nindent 6 }}
|
||||||
|
{{- else if ne .Values.kamajiControlPlane.scheduler.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.kamajiControlPlane.scheduler.resourcesPreset "Release" .Release) | nindent 6 }}
|
||||||
|
{{- end }}
|
||||||
dataStoreName: "{{ $etcd }}"
|
dataStoreName: "{{ $etcd }}"
|
||||||
addons:
|
addons:
|
||||||
coreDNS:
|
coreDNS:
|
||||||
dnsServiceIPs:
|
dnsServiceIPs:
|
||||||
- 10.95.0.10
|
- 10.95.0.10
|
||||||
konnectivity: {}
|
konnectivity:
|
||||||
|
server:
|
||||||
|
port: 8132
|
||||||
|
{{- if .Values.kamajiControlPlane.addons.konnectivity.server.resources }}
|
||||||
|
resources: {{- toYaml .Values.kamajiControlPlane.addons.konnectivity.server.resources | nindent 10 }}
|
||||||
|
{{- else if ne .Values.kamajiControlPlane.addons.konnectivity.server.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.kamajiControlPlane.addons.konnectivity.server.resourcesPreset "Release" .Release) | nindent 10 }}
|
||||||
|
{{- end }}
|
||||||
kubelet:
|
kubelet:
|
||||||
cgroupfs: systemd
|
cgroupfs: systemd
|
||||||
preferredAddressTypes:
|
preferredAddressTypes:
|
||||||
|
|||||||
@@ -63,11 +63,21 @@ spec:
|
|||||||
mountPath: /etc/kubernetes/kubeconfig
|
mountPath: /etc/kubernetes/kubeconfig
|
||||||
readOnly: true
|
readOnly: true
|
||||||
resources:
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 512m
|
||||||
|
memory: 512Mi
|
||||||
requests:
|
requests:
|
||||||
memory: 50Mi
|
cpu: 125m
|
||||||
cpu: 10m
|
memory: 128Mi
|
||||||
- name: csi-provisioner
|
- name: csi-provisioner
|
||||||
image: quay.io/openshift/origin-csi-external-provisioner:latest
|
image: quay.io/openshift/origin-csi-external-provisioner:latest
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 512m
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
cpu: 125m
|
||||||
|
memory: 128Mi
|
||||||
args:
|
args:
|
||||||
- "--csi-address=$(ADDRESS)"
|
- "--csi-address=$(ADDRESS)"
|
||||||
- "--default-fstype=ext4"
|
- "--default-fstype=ext4"
|
||||||
@@ -102,9 +112,12 @@ spec:
|
|||||||
mountPath: /etc/kubernetes/kubeconfig
|
mountPath: /etc/kubernetes/kubeconfig
|
||||||
readOnly: true
|
readOnly: true
|
||||||
resources:
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 512m
|
||||||
|
memory: 512Mi
|
||||||
requests:
|
requests:
|
||||||
memory: 50Mi
|
cpu: 125m
|
||||||
cpu: 10m
|
memory: 128Mi
|
||||||
- name: csi-liveness-probe
|
- name: csi-liveness-probe
|
||||||
image: quay.io/openshift/origin-csi-livenessprobe:latest
|
image: quay.io/openshift/origin-csi-livenessprobe:latest
|
||||||
args:
|
args:
|
||||||
@@ -115,9 +128,12 @@ spec:
|
|||||||
- name: socket-dir
|
- name: socket-dir
|
||||||
mountPath: /csi
|
mountPath: /csi
|
||||||
resources:
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 512m
|
||||||
|
memory: 512Mi
|
||||||
requests:
|
requests:
|
||||||
memory: 50Mi
|
cpu: 125m
|
||||||
cpu: 10m
|
memory: 128Mi
|
||||||
volumes:
|
volumes:
|
||||||
- name: socket-dir
|
- name: socket-dir
|
||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ spec:
|
|||||||
namespace: cozy-system
|
namespace: cozy-system
|
||||||
kubeConfig:
|
kubeConfig:
|
||||||
secretRef:
|
secretRef:
|
||||||
name: {{ .Release.Name }}-kubeconfig
|
name: {{ .Release.Name }}-admin-kubeconfig
|
||||||
|
key: super-admin.svc
|
||||||
targetNamespace: cozy-cert-manager-crds
|
targetNamespace: cozy-cert-manager-crds
|
||||||
storageNamespace: cozy-cert-manager-crds
|
storageNamespace: cozy-cert-manager-crds
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ spec:
|
|||||||
namespace: cozy-system
|
namespace: cozy-system
|
||||||
kubeConfig:
|
kubeConfig:
|
||||||
secretRef:
|
secretRef:
|
||||||
name: {{ .Release.Name }}-kubeconfig
|
name: {{ .Release.Name }}-admin-kubeconfig
|
||||||
|
key: super-admin.svc
|
||||||
targetNamespace: cozy-cert-manager
|
targetNamespace: cozy-cert-manager
|
||||||
storageNamespace: cozy-cert-manager
|
storageNamespace: cozy-cert-manager
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ spec:
|
|||||||
namespace: cozy-system
|
namespace: cozy-system
|
||||||
kubeConfig:
|
kubeConfig:
|
||||||
secretRef:
|
secretRef:
|
||||||
name: {{ .Release.Name }}-kubeconfig
|
name: {{ .Release.Name }}-admin-kubeconfig
|
||||||
|
key: super-admin.svc
|
||||||
targetNamespace: cozy-cilium
|
targetNamespace: cozy-cilium
|
||||||
storageNamespace: cozy-cilium
|
storageNamespace: cozy-cilium
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ spec:
|
|||||||
namespace: cozy-system
|
namespace: cozy-system
|
||||||
kubeConfig:
|
kubeConfig:
|
||||||
secretRef:
|
secretRef:
|
||||||
name: {{ .Release.Name }}-kubeconfig
|
name: {{ .Release.Name }}-admin-kubeconfig
|
||||||
|
key: super-admin.svc
|
||||||
targetNamespace: cozy-csi
|
targetNamespace: cozy-csi
|
||||||
storageNamespace: cozy-csi
|
storageNamespace: cozy-csi
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ spec:
|
|||||||
namespace: cozy-system
|
namespace: cozy-system
|
||||||
kubeConfig:
|
kubeConfig:
|
||||||
secretRef:
|
secretRef:
|
||||||
name: {{ .Release.Name }}-kubeconfig
|
name: {{ .Release.Name }}-admin-kubeconfig
|
||||||
|
key: super-admin.svc
|
||||||
targetNamespace: cozy-fluxcd
|
targetNamespace: cozy-fluxcd
|
||||||
storageNamespace: cozy-fluxcd
|
storageNamespace: cozy-fluxcd
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ spec:
|
|||||||
namespace: cozy-system
|
namespace: cozy-system
|
||||||
kubeConfig:
|
kubeConfig:
|
||||||
secretRef:
|
secretRef:
|
||||||
name: {{ .Release.Name }}-kubeconfig
|
name: {{ .Release.Name }}-admin-kubeconfig
|
||||||
|
key: super-admin.svc
|
||||||
targetNamespace: cozy-ingress-nginx
|
targetNamespace: cozy-ingress-nginx
|
||||||
storageNamespace: cozy-ingress-nginx
|
storageNamespace: cozy-ingress-nginx
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ spec:
|
|||||||
namespace: cozy-system
|
namespace: cozy-system
|
||||||
kubeConfig:
|
kubeConfig:
|
||||||
secretRef:
|
secretRef:
|
||||||
name: {{ .Release.Name }}-kubeconfig
|
name: {{ .Release.Name }}-admin-kubeconfig
|
||||||
|
key: super-admin.svc
|
||||||
targetNamespace: cozy-monitoring-agents
|
targetNamespace: cozy-monitoring-agents
|
||||||
storageNamespace: cozy-monitoring-agents
|
storageNamespace: cozy-monitoring-agents
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ spec:
|
|||||||
namespace: cozy-system
|
namespace: cozy-system
|
||||||
kubeConfig:
|
kubeConfig:
|
||||||
secretRef:
|
secretRef:
|
||||||
name: {{ .Release.Name }}-kubeconfig
|
name: {{ .Release.Name }}-admin-kubeconfig
|
||||||
|
key: super-admin.svc
|
||||||
targetNamespace: cozy-victoria-metrics-operator
|
targetNamespace: cozy-victoria-metrics-operator
|
||||||
storageNamespace: cozy-victoria-metrics-operator
|
storageNamespace: cozy-victoria-metrics-operator
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -36,8 +36,12 @@ spec:
|
|||||||
#securityContext:
|
#securityContext:
|
||||||
# privileged: true
|
# privileged: true
|
||||||
resources:
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 512m
|
||||||
|
memory: 512Mi
|
||||||
requests:
|
requests:
|
||||||
cpu: 100m
|
cpu: 125m
|
||||||
|
memory: 128Mi
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /etc/kubernetes/kubeconfig
|
- mountPath: /etc/kubernetes/kubeconfig
|
||||||
name: kubeconfig
|
name: kubeconfig
|
||||||
|
|||||||
@@ -69,3 +69,63 @@ addons:
|
|||||||
##
|
##
|
||||||
enabled: false
|
enabled: false
|
||||||
valuesOverride: {}
|
valuesOverride: {}
|
||||||
|
|
||||||
|
## @section Kamaji control plane
|
||||||
|
##
|
||||||
|
kamajiControlPlane:
|
||||||
|
apiServer:
|
||||||
|
## @param kamajiControlPlane.apiServer.resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param kamajiControlPlane.apiServer.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "small"
|
||||||
|
|
||||||
|
controllerManager:
|
||||||
|
## @param kamajiControlPlane.controllerManager.resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param kamajiControlPlane.controllerManager.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "micro"
|
||||||
|
scheduler:
|
||||||
|
## @param kamajiControlPlane.scheduler.resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param kamajiControlPlane.scheduler.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "micro"
|
||||||
|
addons:
|
||||||
|
konnectivity:
|
||||||
|
server:
|
||||||
|
## @param kamajiControlPlane.addons.konnectivity.server.resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param kamajiControlPlane.addons.konnectivity.server.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "micro"
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.5.3
|
version: 0.6.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -83,14 +83,16 @@ more details:
|
|||||||
|
|
||||||
### Backup parameters
|
### Backup parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| ------------------------ | ---------------------------------------------- | ------------------------------------------------------ |
|
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
||||||
| `backup.enabled` | Enable pereiodic backups | `false` |
|
| `backup.enabled` | Enable pereiodic backups | `false` |
|
||||||
| `backup.s3Region` | The AWS S3 region where backups are stored | `us-east-1` |
|
| `backup.s3Region` | The AWS S3 region where backups are stored | `us-east-1` |
|
||||||
| `backup.s3Bucket` | The S3 bucket used for storing backups | `s3.example.org/postgres-backups` |
|
| `backup.s3Bucket` | The S3 bucket used for storing backups | `s3.example.org/postgres-backups` |
|
||||||
| `backup.schedule` | Cron schedule for automated backups | `0 2 * * *` |
|
| `backup.schedule` | Cron schedule for automated backups | `0 2 * * *` |
|
||||||
| `backup.cleanupStrategy` | The strategy for cleaning up old backups | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
| `backup.cleanupStrategy` | The strategy for cleaning up old backups | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
||||||
| `backup.s3AccessKey` | The access key for S3, used for authentication | `oobaiRus9pah8PhohL1ThaeTa4UVa7gu` |
|
| `backup.s3AccessKey` | The access key for S3, used for authentication | `oobaiRus9pah8PhohL1ThaeTa4UVa7gu` |
|
||||||
| `backup.s3SecretKey` | The secret key for S3, used for authentication | `ju3eum4dekeich9ahM1te8waeGai0oog` |
|
| `backup.s3SecretKey` | The secret key for S3, used for authentication | `ju3eum4dekeich9ahM1te8waeGai0oog` |
|
||||||
| `backup.resticPassword` | The password for Restic backup encryption | `ChaXoveekoh6eigh4siesheeda2quai0` |
|
| `backup.resticPassword` | The password for Restic backup encryption | `ChaXoveekoh6eigh4siesheeda2quai0` |
|
||||||
|
| `resources` | Resources | `{}` |
|
||||||
|
| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/mariadb-backup:0.5.3@sha256:8ca1fb01e880d351ee7d984a0b437c1142836963cd079986156ed28750067138
|
ghcr.io/cozystack/cozystack/mariadb-backup:0.6.0@sha256:cfd1c37d8ad24e10681d82d6e6ce8a641b4602c1b0ffa8516ae15b4958bb12d4
|
||||||
|
|||||||
50
packages/apps/mysql/templates/_resources.tpl
Normal file
50
packages/apps/mysql/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -72,3 +72,9 @@ spec:
|
|||||||
|
|
||||||
#secondaryService:
|
#secondaryService:
|
||||||
# type: LoadBalancer
|
# type: LoadBalancer
|
||||||
|
|
||||||
|
{{- if .Values.resources }}
|
||||||
|
resources: {{- toYaml .Values.resources | nindent 4 }}
|
||||||
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
|||||||
@@ -66,6 +66,16 @@
|
|||||||
"default": "ChaXoveekoh6eigh4siesheeda2quai0"
|
"default": "ChaXoveekoh6eigh4siesheeda2quai0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,3 +54,16 @@ backup:
|
|||||||
s3AccessKey: oobaiRus9pah8PhohL1ThaeTa4UVa7gu
|
s3AccessKey: oobaiRus9pah8PhohL1ThaeTa4UVa7gu
|
||||||
s3SecretKey: ju3eum4dekeich9ahM1te8waeGai0oog
|
s3SecretKey: ju3eum4dekeich9ahM1te8waeGai0oog
|
||||||
resticPassword: ChaXoveekoh6eigh4siesheeda2quai0
|
resticPassword: ChaXoveekoh6eigh4siesheeda2quai0
|
||||||
|
|
||||||
|
## @param resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.4.1
|
version: 0.5.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -4,13 +4,15 @@
|
|||||||
|
|
||||||
### Common parameters
|
### Common parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| ------------------- | -------------------------------------------------- | ------- |
|
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||||
| `external` | Enable external access from outside the cluster | `false` |
|
| `external` | Enable external access from outside the cluster | `false` |
|
||||||
| `replicas` | Persistent Volume size for NATS | `2` |
|
| `replicas` | Persistent Volume size for NATS | `2` |
|
||||||
| `storageClass` | StorageClass used to store the data | `""` |
|
| `storageClass` | StorageClass used to store the data | `""` |
|
||||||
| `users` | Users configuration | `{}` |
|
| `users` | Users configuration | `{}` |
|
||||||
| `jetstream.size` | Jetstream persistent storage size | `10Gi` |
|
| `jetstream.size` | Jetstream persistent storage size | `10Gi` |
|
||||||
| `jetstream.enabled` | Enable or disable Jetstream | `true` |
|
| `jetstream.enabled` | Enable or disable Jetstream | `true` |
|
||||||
| `config.merge` | Additional configuration to merge into NATS config | `{}` |
|
| `config.merge` | Additional configuration to merge into NATS config | `{}` |
|
||||||
| `config.resolver` | Additional configuration to merge into NATS config | `{}` |
|
| `config.resolver` | Additional configuration to merge into NATS config | `{}` |
|
||||||
|
| `resources` | Resources | `{}` |
|
||||||
|
| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|||||||
50
packages/apps/nats/templates/_resources.tpl
Normal file
50
packages/apps/nats/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -38,6 +38,17 @@ spec:
|
|||||||
timeout: 5m0s
|
timeout: 5m0s
|
||||||
values:
|
values:
|
||||||
nats:
|
nats:
|
||||||
|
podTemplate:
|
||||||
|
merge:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nats
|
||||||
|
image: nats:2.10.17-alpine
|
||||||
|
{{- if .Values.resources }}
|
||||||
|
resources: {{- toYaml .Values.resources | nindent 22 }}
|
||||||
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 22 }}
|
||||||
|
{{- end }}
|
||||||
fullnameOverride: {{ .Release.Name }}
|
fullnameOverride: {{ .Release.Name }}
|
||||||
config:
|
config:
|
||||||
{{- if or (gt (len $passwords) 0) (gt (len .Values.config.merge) 0) }}
|
{{- if or (gt (len $passwords) 0) (gt (len .Values.config.merge) 0) }}
|
||||||
|
|||||||
@@ -46,6 +46,16 @@
|
|||||||
"default": {}
|
"default": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,3 +61,16 @@ config:
|
|||||||
## Default: {}
|
## Default: {}
|
||||||
## Example see: https://github.com/nats-io/k8s/blob/main/helm/charts/nats/values.yaml#L247
|
## Example see: https://github.com/nats-io/k8s/blob/main/helm/charts/nats/values.yaml#L247
|
||||||
resolver: {}
|
resolver: {}
|
||||||
|
|
||||||
|
## @param resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.9.0
|
version: 0.10.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -58,13 +58,15 @@ more details:
|
|||||||
|
|
||||||
### Backup parameters
|
### Backup parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| ------------------------ | ---------------------------------------------- | ------------------------------------------------------ |
|
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
||||||
| `backup.enabled` | Enable pereiodic backups | `false` |
|
| `backup.enabled` | Enable pereiodic backups | `false` |
|
||||||
| `backup.s3Region` | The AWS S3 region where backups are stored | `us-east-1` |
|
| `backup.s3Region` | The AWS S3 region where backups are stored | `us-east-1` |
|
||||||
| `backup.s3Bucket` | The S3 bucket used for storing backups | `s3.example.org/postgres-backups` |
|
| `backup.s3Bucket` | The S3 bucket used for storing backups | `s3.example.org/postgres-backups` |
|
||||||
| `backup.schedule` | Cron schedule for automated backups | `0 2 * * *` |
|
| `backup.schedule` | Cron schedule for automated backups | `0 2 * * *` |
|
||||||
| `backup.cleanupStrategy` | The strategy for cleaning up old backups | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
| `backup.cleanupStrategy` | The strategy for cleaning up old backups | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
||||||
| `backup.s3AccessKey` | The access key for S3, used for authentication | `oobaiRus9pah8PhohL1ThaeTa4UVa7gu` |
|
| `backup.s3AccessKey` | The access key for S3, used for authentication | `oobaiRus9pah8PhohL1ThaeTa4UVa7gu` |
|
||||||
| `backup.s3SecretKey` | The secret key for S3, used for authentication | `ju3eum4dekeich9ahM1te8waeGai0oog` |
|
| `backup.s3SecretKey` | The secret key for S3, used for authentication | `ju3eum4dekeich9ahM1te8waeGai0oog` |
|
||||||
| `backup.resticPassword` | The password for Restic backup encryption | `ChaXoveekoh6eigh4siesheeda2quai0` |
|
| `backup.resticPassword` | The password for Restic backup encryption | `ChaXoveekoh6eigh4siesheeda2quai0` |
|
||||||
|
| `resources` | Resources | `{}` |
|
||||||
|
| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ghcr.io/cozystack/cozystack/postgres-backup:0.9.0@sha256:2b6ba87f5688a439bd2ac12835a5ab9e601feb15c0c44ed0d9ca48cec7c52521
|
ghcr.io/cozystack/cozystack/postgres-backup:0.10.0@sha256:10179ed56457460d95cd5708db2a00130901255fa30c4dd76c65d2ef5622b61f
|
||||||
|
|||||||
50
packages/apps/postgres/templates/_resources.tpl
Normal file
50
packages/apps/postgres/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -5,6 +5,12 @@ metadata:
|
|||||||
name: {{ .Release.Name }}
|
name: {{ .Release.Name }}
|
||||||
spec:
|
spec:
|
||||||
instances: {{ .Values.replicas }}
|
instances: {{ .Values.replicas }}
|
||||||
|
{{- if .Values.resources }}
|
||||||
|
resources: {{- toYaml .Values.resources | nindent 4 }}
|
||||||
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
enableSuperuserAccess: true
|
enableSuperuserAccess: true
|
||||||
{{- $configMap := lookup "v1" "ConfigMap" "cozy-system" "cozystack-scheduling" }}
|
{{- $configMap := lookup "v1" "ConfigMap" "cozy-system" "cozystack-scheduling" }}
|
||||||
{{- if $configMap }}
|
{{- if $configMap }}
|
||||||
|
|||||||
@@ -101,6 +101,16 @@
|
|||||||
"default": "ChaXoveekoh6eigh4siesheeda2quai0"
|
"default": "ChaXoveekoh6eigh4siesheeda2quai0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,3 +76,16 @@ backup:
|
|||||||
s3AccessKey: oobaiRus9pah8PhohL1ThaeTa4UVa7gu
|
s3AccessKey: oobaiRus9pah8PhohL1ThaeTa4UVa7gu
|
||||||
s3SecretKey: ju3eum4dekeich9ahM1te8waeGai0oog
|
s3SecretKey: ju3eum4dekeich9ahM1te8waeGai0oog
|
||||||
resticPassword: ChaXoveekoh6eigh4siesheeda2quai0
|
resticPassword: ChaXoveekoh6eigh4siesheeda2quai0
|
||||||
|
|
||||||
|
## @param resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.4.4
|
version: 0.5.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ The service utilizes official RabbitMQ operator. This ensures the reliability an
|
|||||||
|
|
||||||
### Configuration parameters
|
### Configuration parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| -------- | --------------------------- | ----- |
|
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
|
||||||
| `users` | Users configuration | `{}` |
|
| `users` | Users configuration | `{}` |
|
||||||
| `vhosts` | Virtual Hosts configuration | `{}` |
|
| `vhosts` | Virtual Hosts configuration | `{}` |
|
||||||
|
| `resources` | Resources | `{}` |
|
||||||
|
| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|||||||
50
packages/apps/rabbitmq/templates/_resources.tpl
Normal file
50
packages/apps/rabbitmq/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -11,7 +11,11 @@ spec:
|
|||||||
service:
|
service:
|
||||||
type: LoadBalancer
|
type: LoadBalancer
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- if .Values.resources }}
|
||||||
|
resources: {{- toYaml .Values.resources | nindent 4 }}
|
||||||
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
override:
|
override:
|
||||||
statefulSet:
|
statefulSet:
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -26,6 +26,16 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "Virtual Hosts configuration",
|
"description": "Virtual Hosts configuration",
|
||||||
"default": {}
|
"default": {}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,3 +39,16 @@ users: {}
|
|||||||
## admin:
|
## admin:
|
||||||
## - user3
|
## - user3
|
||||||
vhosts: {}
|
vhosts: {}
|
||||||
|
|
||||||
|
## @param resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.5.0
|
version: 0.6.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ Service utilizes the Spotahome Redis Operator for efficient management and orche
|
|||||||
|
|
||||||
### Common parameters
|
### Common parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| -------------- | ----------------------------------------------- | ------- |
|
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||||
| `external` | Enable external access from outside the cluster | `false` |
|
| `external` | Enable external access from outside the cluster | `false` |
|
||||||
| `size` | Persistent Volume size | `1Gi` |
|
| `size` | Persistent Volume size | `1Gi` |
|
||||||
| `replicas` | Number of Redis replicas | `2` |
|
| `replicas` | Number of Redis replicas | `2` |
|
||||||
| `storageClass` | StorageClass used to store the data | `""` |
|
| `storageClass` | StorageClass used to store the data | `""` |
|
||||||
| `authEnabled` | Enable password generation | `true` |
|
| `authEnabled` | Enable password generation | `true` |
|
||||||
|
| `resources` | Resources | `{}` |
|
||||||
|
| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
50
packages/apps/redis/templates/_resources.tpl
Normal file
50
packages/apps/redis/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -25,19 +25,18 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
sentinel:
|
sentinel:
|
||||||
replicas: 3
|
replicas: 3
|
||||||
resources:
|
{{- if .Values.resources }}
|
||||||
requests:
|
resources: {{- toYaml .Values.resources | nindent 6 }}
|
||||||
cpu: 100m
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
limits:
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 6 }}
|
||||||
memory: 100Mi
|
{{- end }}
|
||||||
redis:
|
redis:
|
||||||
replicas: {{ .Values.replicas }}
|
replicas: {{ .Values.replicas }}
|
||||||
resources:
|
{{- if .Values.resources }}
|
||||||
requests:
|
resources: {{- toYaml .Values.resources | nindent 6 }}
|
||||||
cpu: 150m
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
memory: 400Mi
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 6 }}
|
||||||
limits:
|
{{- end }}
|
||||||
memory: 1000Mi
|
|
||||||
{{- with .Values.size }}
|
{{- with .Values.size }}
|
||||||
storage:
|
storage:
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
|
|||||||
@@ -26,6 +26,16 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Enable password generation",
|
"description": "Enable password generation",
|
||||||
"default": true
|
"default": true
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,3 +11,16 @@ size: 1Gi
|
|||||||
replicas: 2
|
replicas: 2
|
||||||
storageClass: ""
|
storageClass: ""
|
||||||
authEnabled: true
|
authEnabled: true
|
||||||
|
|
||||||
|
## @param resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# This is the chart version. This version number should be incremented each time you make changes
|
||||||
# to the chart and its templates, including the app version.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.2.0
|
version: 0.3.0
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# This is the version number of the application being deployed. This version number should be
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
# incremented each time you make changes to the application. Versions are not expected to
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ Managed TCP Load Balancer Service efficiently utilizes HAProxy for load balancin
|
|||||||
|
|
||||||
### Configuration parameters
|
### Configuration parameters
|
||||||
|
|
||||||
| Name | Description | Value |
|
| Name | Description | Value |
|
||||||
| -------------------------------- | ------------------------------------------------------------- | ------- |
|
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||||
| `httpAndHttps.mode` | Mode for balancer. Allowed values: `tcp` and `tcp-with-proxy` | `tcp` |
|
| `httpAndHttps.mode` | Mode for balancer. Allowed values: `tcp` and `tcp-with-proxy` | `tcp` |
|
||||||
| `httpAndHttps.targetPorts.http` | HTTP port number. | `80` |
|
| `httpAndHttps.targetPorts.http` | HTTP port number. | `80` |
|
||||||
| `httpAndHttps.targetPorts.https` | HTTPS port number. | `443` |
|
| `httpAndHttps.targetPorts.https` | HTTPS port number. | `443` |
|
||||||
| `httpAndHttps.endpoints` | Endpoint addresses list | `[]` |
|
| `httpAndHttps.endpoints` | Endpoint addresses list | `[]` |
|
||||||
| `whitelistHTTP` | Secure HTTP by enabling client networks whitelisting | `false` |
|
| `whitelistHTTP` | Secure HTTP by enabling client networks whitelisting | `false` |
|
||||||
| `whitelist` | List of client networks | `[]` |
|
| `whitelist` | List of client networks | `[]` |
|
||||||
|
| `resources` | Resources | `{}` |
|
||||||
|
| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `nano` |
|
||||||
|
|||||||
50
packages/apps/tcp-balancer/templates/_resources.tpl
Normal file
50
packages/apps/tcp-balancer/templates/_resources.tpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{/*
|
||||||
|
Copyright Broadcom, Inc. All Rights Reserved.
|
||||||
|
SPDX-License-Identifier: APACHE-2.0
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{/* vim: set filetype=mustache: */}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Return a resource request/limit object based on a given preset.
|
||||||
|
These presets are for basic testing and not meant to be used in production
|
||||||
|
{{ include "resources.preset" (dict "type" "nano") -}}
|
||||||
|
*/}}
|
||||||
|
{{- define "resources.preset" -}}
|
||||||
|
{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}}
|
||||||
|
{{- $presets := dict
|
||||||
|
"nano" (dict
|
||||||
|
"requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"micro" (dict
|
||||||
|
"requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"small" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"medium" (dict
|
||||||
|
"requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"large" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
"2xlarge" (dict
|
||||||
|
"requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi")
|
||||||
|
"limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi")
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{- if hasKey $presets .type -}}
|
||||||
|
{{- index $presets .type | toYaml -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -33,6 +33,11 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- image: haproxy:latest
|
- image: haproxy:latest
|
||||||
name: haproxy
|
name: haproxy
|
||||||
|
{{- if .Values.resources }}
|
||||||
|
resources: {{- toYaml .Values.resources | nindent 10 }}
|
||||||
|
{{- else if ne .Values.resourcesPreset "none" }}
|
||||||
|
resources: {{- include "resources.preset" (dict "type" .Values.resourcesPreset "Release" .Release) | nindent 10 }}
|
||||||
|
{{- end }}
|
||||||
ports:
|
ports:
|
||||||
{{- with .Values.httpAndHttps }}
|
{{- with .Values.httpAndHttps }}
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
|
|||||||
@@ -57,6 +57,16 @@
|
|||||||
"description": "List of client networks",
|
"description": "List of client networks",
|
||||||
"default": [],
|
"default": [],
|
||||||
"items": {}
|
"items": {}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Resources",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"resourcesPreset": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).",
|
||||||
|
"default": "nano"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,3 +43,16 @@ httpAndHttps:
|
|||||||
##
|
##
|
||||||
whitelistHTTP: false
|
whitelistHTTP: false
|
||||||
whitelist: []
|
whitelist: []
|
||||||
|
|
||||||
|
## @param resources Resources
|
||||||
|
resources: {}
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpu: 4000m
|
||||||
|
# memory: 4Gi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 512Mi
|
||||||
|
|
||||||
|
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||||
|
resourcesPreset: "nano"
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ description: Separated tenant namespace
|
|||||||
icon: /logos/tenant.svg
|
icon: /logos/tenant.svg
|
||||||
|
|
||||||
type: application
|
type: application
|
||||||
version: 1.9.0
|
version: 1.9.1
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ metadata:
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- include "cozystack.namespace-anotations" (list $ $existingNS) | nindent 4 }}
|
{{- include "cozystack.namespace-anotations" (list $ $existingNS) | nindent 4 }}
|
||||||
|
alpha.kubevirt.io/auto-memory-limits-ratio: "1.0"
|
||||||
ownerReferences:
|
ownerReferences:
|
||||||
- apiVersion: v1
|
- apiVersion: v1
|
||||||
blockOwnerDeletion: true
|
blockOwnerDeletion: true
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user