mirror of
https://github.com/cozystack/cozystack.git
synced 2026-03-16 03:48:55 +00:00
Compare commits
18 Commits
feat/expos
...
feat/sched
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c59b6dc51 | ||
|
|
43d49b6e46 | ||
|
|
1024ee7607 | ||
|
|
6046a31e8c | ||
|
|
0387fae62c | ||
|
|
b821c0748e | ||
|
|
ee8533647b | ||
|
|
b3f356a5ed | ||
|
|
ffd6e628e2 | ||
|
|
22f2e4f82a | ||
|
|
39df52542b | ||
|
|
2b60c010dd | ||
|
|
f906a0d8ad | ||
|
|
ee83aaa82e | ||
|
|
f647cfd7b9 | ||
|
|
941fb02cd1 | ||
|
|
f82f13bf32 | ||
|
|
1dd27f6b23 |
29
docs/changelogs/v1.0.5.md
Normal file
29
docs/changelogs/v1.0.5.md
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
https://github.com/cozystack/cozystack/releases/tag/v1.0.5
|
||||
-->
|
||||
|
||||
## Fixes
|
||||
|
||||
* **[api] Fix spurious OpenAPI post-processing errors for non-apps group versions**: The API server no longer logs false errors while generating OpenAPI specs for core and other non-`apps.cozystack.io` group versions. The post-processor now exits early when the base `Application` schemas are absent, reducing noisy startup logs without affecting application schema generation ([**@kvaps**](https://github.com/kvaps) in #2212, #2216).
|
||||
|
||||
## Documentation
|
||||
|
||||
* **[website] Add `DependenciesNotReady` troubleshooting and correct packages management build target**: Added a troubleshooting guide for packages stuck in `DependenciesNotReady`, including how to inspect operator logs and identify missing dependencies, and fixed the outdated `make image-cozystack` command to `make image-packages` in the packages management guide ([**@kvaps**](https://github.com/kvaps) in cozystack/website#450).
|
||||
|
||||
* **[website] Clarify operator-first installation order**: Reordered the platform installation guide and tutorial so users install the Cozystack operator before preparing and applying the Platform Package, matching the rest of the installation docs and reducing setup confusion during fresh installs ([**@sircthulhu**](https://github.com/sircthulhu) in cozystack/website#449).
|
||||
|
||||
* **[website] Add automated installation guide for Ansible**: Added end-to-end documentation for deploying Cozystack with the `cozystack.installer` Ansible collection, including inventory examples, distro-specific playbooks, configuration reference, verification steps, and explicit version pinning guidance to help operators automate installs safely ([**@lexfrei**](https://github.com/lexfrei) in cozystack/website#442).
|
||||
|
||||
* **[website] Expand CA rotation operations guide**: Completed the CA rotation documentation with separate Talos and Kubernetes certificate rotation procedures, dry-run preview steps, and post-rotation guidance for fetching updated `talosconfig` and `kubeconfig` files after certificate changes ([**@kvaps**](https://github.com/kvaps) in cozystack/website#406).
|
||||
|
||||
* **[website] Improve backup operations documentation**: Enhanced the operator backup and recovery guide with clearer Velero enablement steps, concrete provider and bucket examples, and more useful commands for inspecting backups, schedules, restores, CRD status, and logs ([**@androndo**](https://github.com/androndo) in cozystack/website#440).
|
||||
|
||||
* **[website] Add custom metrics collection guide**: Added a monitoring guide showing how tenants can expose their own Prometheus exporters through `VMServiceScrape` and `VMPodScrape`, including namespace labeling requirements, example manifests, verification steps, and troubleshooting advice ([**@IvanHunters**](https://github.com/IvanHunters) in cozystack/website#444).
|
||||
|
||||
* **[website] Document PackageSource and Package architecture**: Added a Key Concepts reference covering `PackageSource` and `Package` reconciliation flow, dependency handling, update propagation, rollback behavior, FluxPlunger recovery, and the `cozypkg` CLI for package management ([**@IvanHunters**](https://github.com/IvanHunters) in cozystack/website#445).
|
||||
|
||||
* **[website] Refresh v1 application and platform documentation**: Fixed the documentation auto-update flow and published a broad v1 documentation refresh covering newly documented applications, updated naming and navigation, virtualization and platform content updates, and reorganized versioned docs pages ([**@myasnikovdaniil**](https://github.com/myasnikovdaniil) in cozystack/website#439).
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/cozystack/cozystack/compare/v1.0.4...v1.0.5
|
||||
@@ -230,6 +230,10 @@ func applyListInputOverrides(schema map[string]any, kind string, openAPIProps ma
|
||||
kafkaProps["storageClass"] = storageClassListInput()
|
||||
zkProps := ensureSchemaPath(schema, "spec", "zookeeper")
|
||||
zkProps["storageClass"] = storageClassListInput()
|
||||
|
||||
case "Tenant":
|
||||
specProps := ensureSchemaPath(schema, "spec")
|
||||
specProps["schedulingClass"] = schedulingClassListInput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,6 +250,20 @@ func storageClassListInput() map[string]any {
|
||||
}
|
||||
}
|
||||
|
||||
// schedulingClassListInput returns a listInput field config for a schedulingClass dropdown
|
||||
// backed by the cluster's available SchedulingClass CRs.
|
||||
func schedulingClassListInput() map[string]any {
|
||||
return map[string]any{
|
||||
"type": "listInput",
|
||||
"customProps": map[string]any{
|
||||
"valueUri": "/api/clusters/{cluster}/k8s/apis/cozystack.io/v1alpha1/schedulingclasses",
|
||||
"keysToValue": []any{"metadata", "name"},
|
||||
"keysToLabel": []any{"metadata", "name"},
|
||||
"allowEmpty": true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ensureArrayItemProps ensures that parentProps[fieldName].items.properties exists
|
||||
// and returns the items properties map. Used for overriding fields inside array items.
|
||||
func ensureArrayItemProps(parentProps map[string]any, fieldName string) map[string]any {
|
||||
|
||||
@@ -8,11 +8,14 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/cozystack/cozystack/pkg/lineage"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/rest"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
@@ -31,6 +34,11 @@ const (
|
||||
ManagerGroupKey = "apps.cozystack.io/application.group"
|
||||
ManagerKindKey = "apps.cozystack.io/application.kind"
|
||||
ManagerNameKey = "apps.cozystack.io/application.name"
|
||||
|
||||
// Scheduling constants
|
||||
SchedulingClassLabel = "scheduling.cozystack.io/class"
|
||||
SchedulingClassAnnotation = "scheduler.cozystack.io/scheduling-class"
|
||||
CozystackSchedulerName = "cozystack-scheduler"
|
||||
)
|
||||
|
||||
// getResourceSelectors returns the appropriate ApplicationDefinitionResources for a given GroupKind
|
||||
@@ -115,6 +123,11 @@ func (h *LineageControllerWebhook) Handle(ctx context.Context, req admission.Req
|
||||
|
||||
h.applyLabels(obj, labels)
|
||||
|
||||
if err := h.applySchedulingClass(ctx, obj, req.Namespace); err != nil {
|
||||
logger.Error(err, "error applying scheduling class")
|
||||
return admission.Errored(500, fmt.Errorf("error applying scheduling class: %w", err))
|
||||
}
|
||||
|
||||
mutated, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return admission.Errored(500, fmt.Errorf("marshal mutated pod: %w", err))
|
||||
@@ -185,6 +198,57 @@ func (h *LineageControllerWebhook) applyLabels(o *unstructured.Unstructured, lab
|
||||
o.SetLabels(existing)
|
||||
}
|
||||
|
||||
// applySchedulingClass injects schedulerName and scheduling-class annotation
|
||||
// into Pods whose namespace carries the scheduling.cozystack.io/class label.
|
||||
// If the referenced SchedulingClass CR does not exist (e.g. the scheduler
|
||||
// package is not installed), the injection is silently skipped so that pods
|
||||
// are not left Pending.
|
||||
func (h *LineageControllerWebhook) applySchedulingClass(ctx context.Context, obj *unstructured.Unstructured, namespace string) error {
|
||||
if obj.GetKind() != "Pod" {
|
||||
return nil
|
||||
}
|
||||
|
||||
ns := &corev1.Namespace{}
|
||||
if err := h.Get(ctx, client.ObjectKey{Name: namespace}, ns); err != nil {
|
||||
return fmt.Errorf("getting namespace %s: %w", namespace, err)
|
||||
}
|
||||
|
||||
schedulingClass, ok := ns.Labels[SchedulingClassLabel]
|
||||
if !ok || schedulingClass == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify that the referenced SchedulingClass CR exists.
|
||||
// If the CRD is not installed or the CR is missing, skip injection
|
||||
// so that pods are not stuck Pending on a non-existent scheduler.
|
||||
_, err := h.dynClient.Resource(schedulingClassGVR).Get(ctx, schedulingClass, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
logger := log.FromContext(ctx)
|
||||
logger.Info("SchedulingClass not found, skipping scheduler injection",
|
||||
"schedulingClass", schedulingClass, "namespace", namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := unstructured.SetNestedField(obj.Object, CozystackSchedulerName, "spec", "schedulerName"); err != nil {
|
||||
return fmt.Errorf("setting schedulerName: %w", err)
|
||||
}
|
||||
|
||||
annotations := obj.GetAnnotations()
|
||||
if annotations == nil {
|
||||
annotations = make(map[string]string)
|
||||
}
|
||||
annotations[SchedulingClassAnnotation] = schedulingClass
|
||||
obj.SetAnnotations(annotations)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var schedulingClassGVR = schema.GroupVersionResource{
|
||||
Group: "cozystack.io",
|
||||
Version: "v1alpha1",
|
||||
Resource: "schedulingclasses",
|
||||
}
|
||||
|
||||
func (h *LineageControllerWebhook) decodeUnstructured(req admission.Request, out *unstructured.Unstructured) error {
|
||||
if h.decoder != nil {
|
||||
if err := h.decoder.Decode(req, out); err == nil {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KUBERNETES_VERSION = v1.35
|
||||
KUBERNETES_VERSIONS = $(shell awk -F'"' '{print $$2}' files/versions.yaml)
|
||||
KUBERNETES_PKG_TAG = $(shell awk '$$1 == "version:" {print $$2}' Chart.yaml)
|
||||
|
||||
include ../../../hack/common-envs.mk
|
||||
@@ -15,17 +15,19 @@ update:
|
||||
image: image-ubuntu-container-disk image-kubevirt-cloud-provider image-kubevirt-csi-driver image-cluster-autoscaler
|
||||
|
||||
image-ubuntu-container-disk:
|
||||
docker buildx build images/ubuntu-container-disk \
|
||||
--build-arg KUBERNETES_VERSION=${KUBERNETES_VERSION} \
|
||||
--tag $(REGISTRY)/ubuntu-container-disk:$(call settag,$(KUBERNETES_VERSION)) \
|
||||
--tag $(REGISTRY)/ubuntu-container-disk:$(call settag,$(KUBERNETES_VERSION)-$(TAG)) \
|
||||
--cache-from type=registry,ref=$(REGISTRY)/ubuntu-container-disk:latest \
|
||||
--cache-to type=inline \
|
||||
--metadata-file images/ubuntu-container-disk.json \
|
||||
$(BUILDX_ARGS)
|
||||
echo "$(REGISTRY)/ubuntu-container-disk:$(call settag,$(KUBERNETES_VERSION))@$$(yq e '."containerimage.digest"' images/ubuntu-container-disk.json -o json -r)" \
|
||||
> images/ubuntu-container-disk.tag
|
||||
rm -f images/ubuntu-container-disk.json
|
||||
$(foreach ver,$(KUBERNETES_VERSIONS), \
|
||||
docker buildx build images/ubuntu-container-disk \
|
||||
--build-arg KUBERNETES_VERSION=$(ver) \
|
||||
--tag $(REGISTRY)/ubuntu-container-disk:$(call settag,$(ver)) \
|
||||
--tag $(REGISTRY)/ubuntu-container-disk:$(call settag,$(ver)-$(TAG)) \
|
||||
--cache-from type=registry,ref=$(REGISTRY)/ubuntu-container-disk:$(call settag,$(ver)) \
|
||||
--cache-to type=inline \
|
||||
--metadata-file images/ubuntu-container-disk-$(ver).json \
|
||||
$(BUILDX_ARGS) && \
|
||||
echo "$(REGISTRY)/ubuntu-container-disk:$(call settag,$(ver))@$$(yq e '."containerimage.digest"' images/ubuntu-container-disk-$(ver).json -o json -r)" \
|
||||
> images/ubuntu-container-disk-$(ver).tag && \
|
||||
rm -f images/ubuntu-container-disk-$(ver).json; \
|
||||
)
|
||||
|
||||
image-kubevirt-cloud-provider:
|
||||
docker buildx build images/kubevirt-cloud-provider \
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ttl.sh/rjfkdsjflsk/ubuntu-container-disk:v1.30@sha256:8c2276f68beb67edf5bf76d6c97b271dd9303b336e1d5850ae2b91a590c9bb57
|
||||
@@ -0,0 +1 @@
|
||||
ttl.sh/rjfkdsjflsk/ubuntu-container-disk:v1.31@sha256:2b631cd227bc9b1bae16de033830e756cd6590b512dc0d2b13367ee626f3e4ca
|
||||
@@ -0,0 +1 @@
|
||||
ttl.sh/rjfkdsjflsk/ubuntu-container-disk:v1.32@sha256:600d6ce7df4eaa8cc79c7d6d1b01ecac43e7696beb84eafce752d9210a16455f
|
||||
@@ -0,0 +1 @@
|
||||
ttl.sh/rjfkdsjflsk/ubuntu-container-disk:v1.33@sha256:243e55d6f2887a4f6ce8526de52fd083b7b88194d5c7f3eaa51b87efb557ac88
|
||||
@@ -0,0 +1 @@
|
||||
ttl.sh/rjfkdsjflsk/ubuntu-container-disk:v1.34@sha256:ad8377d5644ba51729dc69dff4c9f6b4a48957075d054a58c61a45d0bb41f6af
|
||||
@@ -0,0 +1 @@
|
||||
ttl.sh/rjfkdsjflsk/ubuntu-container-disk:v1.35@sha256:1c2f2430383a9b9882358c60c194465c1b6092b4aa77536a0343cf74155c0067
|
||||
@@ -1 +0,0 @@
|
||||
ghcr.io/cozystack/cozystack/ubuntu-container-disk:v1.35@sha256:39f626c802dd84f95720ffb54fcd80dfb8a58ac280498870d0a1aa30d4252f94
|
||||
@@ -74,7 +74,7 @@ spec:
|
||||
volumes:
|
||||
- name: system
|
||||
containerDisk:
|
||||
image: "{{ $.Files.Get "images/ubuntu-container-disk.tag" | trim }}"
|
||||
image: "{{ $.Files.Get (printf "images/ubuntu-container-disk-%s.tag" $.Values.version) | trim }}"
|
||||
- name: ephemeral
|
||||
emptyDisk:
|
||||
capacity: {{ .group.ephemeralStorage | default "20Gi" }}
|
||||
@@ -249,6 +249,9 @@ spec:
|
||||
joinConfiguration:
|
||||
nodeRegistration:
|
||||
kubeletExtraArgs: {}
|
||||
# Ignore this for 1.31
|
||||
ignorePreflightErrors:
|
||||
- FileExisting-conntrack
|
||||
discovery:
|
||||
bootstrapToken:
|
||||
apiServerEndpoint: {{ $.Release.Name }}.{{ $.Release.Namespace }}.svc:6443
|
||||
|
||||
@@ -74,14 +74,15 @@ tenant-u1
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------- |
|
||||
| `host` | The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host). | `string` | `""` |
|
||||
| `etcd` | Deploy own Etcd cluster. | `bool` | `false` |
|
||||
| `monitoring` | Deploy own Monitoring Stack. | `bool` | `false` |
|
||||
| `ingress` | Deploy own Ingress Controller. | `bool` | `false` |
|
||||
| `seaweedfs` | Deploy own SeaweedFS. | `bool` | `false` |
|
||||
| `resourceQuotas` | Define resource quotas for the tenant. | `map[string]quantity` | `{}` |
|
||||
| Name | Description | Type | Value |
|
||||
| ----------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------- |
|
||||
| `host` | The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host). | `string` | `""` |
|
||||
| `etcd` | Deploy own Etcd cluster. | `bool` | `false` |
|
||||
| `monitoring` | Deploy own Monitoring Stack. | `bool` | `false` |
|
||||
| `ingress` | Deploy own Ingress Controller. | `bool` | `false` |
|
||||
| `seaweedfs` | Deploy own SeaweedFS. | `bool` | `false` |
|
||||
| `schedulingClass` | The name of a SchedulingClass CR to apply scheduling constraints for this tenant's workloads. | `string` | `""` |
|
||||
| `resourceQuotas` | Define resource quotas for the tenant. | `map[string]quantity` | `{}` |
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -38,6 +38,12 @@
|
||||
{{- if .Values.seaweedfs }}
|
||||
{{- $seaweedfs = $tenantName }}
|
||||
{{- end }}
|
||||
|
||||
{{/* SchedulingClass: inherited from parent, can be set if parent has none */}}
|
||||
{{- $schedulingClass := $parentNamespace.schedulingClass | default "" }}
|
||||
{{- if and (not $schedulingClass) .Values.schedulingClass }}
|
||||
{{- $schedulingClass = .Values.schedulingClass }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
@@ -58,6 +64,9 @@ metadata:
|
||||
namespace.cozystack.io/monitoring: {{ $monitoring | quote }}
|
||||
namespace.cozystack.io/seaweedfs: {{ $seaweedfs | quote }}
|
||||
namespace.cozystack.io/host: {{ $computedHost | quote }}
|
||||
{{- with $schedulingClass }}
|
||||
scheduling.cozystack.io/class: {{ . | quote }}
|
||||
{{- end }}
|
||||
alpha.kubevirt.io/auto-memory-limits-ratio: "1.0"
|
||||
ownerReferences:
|
||||
- apiVersion: v1
|
||||
@@ -86,4 +95,7 @@ stringData:
|
||||
monitoring: {{ $monitoring | quote }}
|
||||
seaweedfs: {{ $seaweedfs | quote }}
|
||||
host: {{ $computedHost | quote }}
|
||||
{{- with $schedulingClass }}
|
||||
schedulingClass: {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -39,6 +39,11 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
}
|
||||
},
|
||||
"schedulingClass": {
|
||||
"description": "The name of a SchedulingClass CR to apply scheduling constraints for this tenant's workloads.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"seaweedfs": {
|
||||
"description": "Deploy own SeaweedFS.",
|
||||
"type": "boolean",
|
||||
|
||||
@@ -17,5 +17,8 @@ ingress: false
|
||||
## @param {bool} seaweedfs - Deploy own SeaweedFS.
|
||||
seaweedfs: false
|
||||
|
||||
## @param {string} [schedulingClass] - The name of a SchedulingClass CR to apply scheduling constraints for this tenant's workloads.
|
||||
schedulingClass: ""
|
||||
|
||||
## @param {map[string]quantity} resourceQuotas - Define resource quotas for the tenant.
|
||||
resourceQuotas: {}
|
||||
|
||||
19
packages/core/platform/sources/cozystack-scheduler.yaml
Normal file
19
packages/core/platform/sources/cozystack-scheduler.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
apiVersion: cozystack.io/v1alpha1
|
||||
kind: PackageSource
|
||||
metadata:
|
||||
name: cozystack.cozystack-scheduler
|
||||
spec:
|
||||
sourceRef:
|
||||
kind: OCIRepository
|
||||
name: cozystack-packages
|
||||
namespace: cozy-system
|
||||
path: /
|
||||
variants:
|
||||
- name: default
|
||||
components:
|
||||
- name: cozystack-scheduler
|
||||
path: system/cozystack-scheduler
|
||||
install:
|
||||
namespace: kube-system
|
||||
releaseName: cozystack-scheduler
|
||||
@@ -156,5 +156,6 @@
|
||||
{{include "cozystack.platform.package.default" (list "cozystack.bootbox" $) }}
|
||||
{{- end }}
|
||||
{{include "cozystack.platform.package.optional.default" (list "cozystack.hetzner-robotlb" $) }}
|
||||
{{include "cozystack.platform.package.optional.default" (list "cozystack.cozystack-scheduler" $) }}
|
||||
|
||||
{{- end }}
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
{{- $endpoint := printf "s3.%s" .Values._namespace.host }}
|
||||
{{- range $name, $user := .Values.users }}
|
||||
{{- $secretName := printf "%s-%s" $.Values.bucketName $name }}
|
||||
{{- $existingSecret := lookup "v1" "Secret" $.Release.Namespace $secretName }}
|
||||
{{- if $existingSecret }}
|
||||
{{- $bucketInfo := fromJson (b64dec (index $existingSecret.data "BucketInfo")) }}
|
||||
{{- $endpoint = trimPrefix "https://" (index $bucketInfo.spec.secretS3 "endpoint") }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -17,6 +26,6 @@ spec:
|
||||
image: "{{ $.Files.Get "images/s3manager.tag" | trim }}"
|
||||
env:
|
||||
- name: ENDPOINT
|
||||
value: "s3.{{ .Values._namespace.host }}"
|
||||
value: {{ $endpoint | quote }}
|
||||
- name: SKIP_SSL_VERIFICATION
|
||||
value: "true"
|
||||
|
||||
3
packages/system/cozystack-scheduler/Chart.yaml
Normal file
3
packages/system/cozystack-scheduler/Chart.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
apiVersion: v2
|
||||
name: cozy-cozystack-scheduler
|
||||
version: 0.1.0
|
||||
10
packages/system/cozystack-scheduler/Makefile
Normal file
10
packages/system/cozystack-scheduler/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
export NAME=cozystack-scheduler
|
||||
export NAMESPACE=kube-system
|
||||
|
||||
include ../../../hack/package.mk
|
||||
|
||||
update:
|
||||
rm -rf crds templates values.yaml Chart.yaml
|
||||
tag=$$(git ls-remote --tags --sort="v:refname" https://github.com/cozystack/cozystack-scheduler | awk -F'[/^]' 'END{print $$3}') && \
|
||||
curl -sSL https://github.com/cozystack/cozystack-scheduler/archive/refs/tags/$${tag}.tar.gz | \
|
||||
tar xzvf - --strip 2 cozystack-scheduler-$${tag#*v}/chart
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: cozystack-scheduler
|
||||
rules:
|
||||
- apiGroups: ["cozystack.io"]
|
||||
resources:
|
||||
- schedulingclasses
|
||||
verbs: ["get", "list", "watch"]
|
||||
@@ -0,0 +1,38 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: cozystack-scheduler:kube-scheduler
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:kube-scheduler
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cozystack-scheduler
|
||||
namespace: {{ .Release.Namespace }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: cozystack-scheduler:volume-scheduler
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:volume-scheduler
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cozystack-scheduler
|
||||
namespace: {{ .Release.Namespace }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: cozystack-scheduler
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cozystack-scheduler
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cozystack-scheduler
|
||||
namespace: {{ .Release.Namespace }}
|
||||
54
packages/system/cozystack-scheduler/templates/configmap.yaml
Normal file
54
packages/system/cozystack-scheduler/templates/configmap.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cozystack-scheduler-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
data:
|
||||
scheduler-config.yaml: |
|
||||
apiVersion: kubescheduler.config.k8s.io/v1
|
||||
kind: KubeSchedulerConfiguration
|
||||
leaderElection:
|
||||
leaderElect: true
|
||||
resourceNamespace: {{ .Release.Namespace }}
|
||||
resourceName: cozystack-scheduler
|
||||
profiles:
|
||||
- schedulerName: cozystack-scheduler
|
||||
plugins:
|
||||
preFilter:
|
||||
disabled:
|
||||
- name: InterPodAffinity
|
||||
- name: NodeAffinity
|
||||
- name: PodTopologySpread
|
||||
enabled:
|
||||
- name: CozystackInterPodAffinity
|
||||
- name: CozystackNodeAffinity
|
||||
- name: CozystackPodTopologySpread
|
||||
- name: CozystackSchedulingClass
|
||||
filter:
|
||||
disabled:
|
||||
- name: InterPodAffinity
|
||||
- name: NodeAffinity
|
||||
- name: PodTopologySpread
|
||||
enabled:
|
||||
- name: CozystackInterPodAffinity
|
||||
- name: CozystackNodeAffinity
|
||||
- name: CozystackPodTopologySpread
|
||||
- name: CozystackSchedulingClass
|
||||
preScore:
|
||||
disabled:
|
||||
- name: InterPodAffinity
|
||||
- name: NodeAffinity
|
||||
- name: PodTopologySpread
|
||||
enabled:
|
||||
- name: CozystackInterPodAffinity
|
||||
- name: CozystackNodeAffinity
|
||||
- name: CozystackPodTopologySpread
|
||||
score:
|
||||
disabled:
|
||||
- name: InterPodAffinity
|
||||
- name: NodeAffinity
|
||||
- name: PodTopologySpread
|
||||
enabled:
|
||||
- name: CozystackInterPodAffinity
|
||||
- name: CozystackNodeAffinity
|
||||
- name: CozystackPodTopologySpread
|
||||
@@ -0,0 +1,37 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cozystack-scheduler
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cozystack-scheduler
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cozystack-scheduler
|
||||
spec:
|
||||
serviceAccountName: cozystack-scheduler
|
||||
containers:
|
||||
- name: cozystack-scheduler
|
||||
image: {{ .Values.image }}
|
||||
command:
|
||||
- /cozystack-scheduler
|
||||
- --config=/etc/kubernetes/scheduler-config.yaml
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 10259
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 15
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/kubernetes/scheduler-config.yaml
|
||||
subPath: scheduler-config.yaml
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: cozystack-scheduler-config
|
||||
@@ -0,0 +1,40 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: cozystack-scheduler:extension-apiserver-authentication-reader
|
||||
namespace: kube-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: extension-apiserver-authentication-reader
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cozystack-scheduler
|
||||
namespace: {{ .Release.Namespace }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: cozystack-scheduler:leader-election
|
||||
namespace: {{ .Release.Namespace }}
|
||||
rules:
|
||||
- apiGroups: ["coordination.k8s.io"]
|
||||
resources: ["leases"]
|
||||
verbs: ["create", "get", "list", "update", "watch"]
|
||||
- apiGroups: ["coordination.k8s.io"]
|
||||
resources: ["leasecandidates"]
|
||||
verbs: ["create", "get", "list", "update", "watch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: cozystack-scheduler:leader-election
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: cozystack-scheduler:leader-election
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cozystack-scheduler
|
||||
namespace: {{ .Release.Namespace }}
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: cozystack-scheduler
|
||||
namespace: {{ .Release.Namespace }}
|
||||
2
packages/system/cozystack-scheduler/values.yaml
Normal file
2
packages/system/cozystack-scheduler/values.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
image: ghcr.io/cozystack/cozystack/cozystack-scheduler:v0.1.0@sha256:5f7150c82177478467ff80628acb5a400291aff503364aa9e26fc346d79a73cf
|
||||
replicas: 1
|
||||
@@ -8,7 +8,7 @@ spec:
|
||||
singular: tenant
|
||||
plural: tenants
|
||||
openAPISchema: |-
|
||||
{"title":"Chart Values","type":"object","properties":{"etcd":{"description":"Deploy own Etcd cluster.","type":"boolean","default":false},"host":{"description":"The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host).","type":"string","default":""},"ingress":{"description":"Deploy own Ingress Controller.","type":"boolean","default":false},"monitoring":{"description":"Deploy own Monitoring Stack.","type":"boolean","default":false},"resourceQuotas":{"description":"Define resource quotas for the tenant.","type":"object","default":{},"additionalProperties":{"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}},"seaweedfs":{"description":"Deploy own SeaweedFS.","type":"boolean","default":false}}}
|
||||
{"title":"Chart Values","type":"object","properties":{"etcd":{"description":"Deploy own Etcd cluster.","type":"boolean","default":false},"host":{"description":"The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host).","type":"string","default":""},"ingress":{"description":"Deploy own Ingress Controller.","type":"boolean","default":false},"monitoring":{"description":"Deploy own Monitoring Stack.","type":"boolean","default":false},"resourceQuotas":{"description":"Define resource quotas for the tenant.","type":"object","default":{},"additionalProperties":{"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}},"schedulingClass":{"description":"The name of a SchedulingClass CR to apply scheduling constraints for this tenant's workloads.","type":"string","default":""},"seaweedfs":{"description":"Deploy own SeaweedFS.","type":"boolean","default":false}}}
|
||||
release:
|
||||
prefix: tenant-
|
||||
labels:
|
||||
@@ -23,7 +23,7 @@ spec:
|
||||
plural: Tenants
|
||||
description: Separated tenant namespace
|
||||
icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQwMykiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDAzKSI+CjxwYXRoIGQ9Ik03MiAyOUM2Ni4zOTI2IDI5IDYxLjAxNDggMzEuMjM4OCA1Ny4wNDk3IDM1LjIyNEM1My4wODQ3IDM5LjIwOTEgNTAuODU3MSA0NC42MTQxIDUwLjg1NzEgNTAuMjVDNTAuODU3MSA1NS44ODU5IDUzLjA4NDcgNjEuMjkwOSA1Ny4wNDk3IDY1LjI3NkM2MS4wMTQ4IDY5LjI2MTIgNjYuMzkyNiA3MS41IDcyIDcxLjVDNzcuNjA3NCA3MS41IDgyLjk4NTIgNjkuMjYxMiA4Ni45NTAzIDY1LjI3NkM5MC45MTUzIDYxLjI5MDkgOTMuMTQyOSA1NS44ODU5IDkzLjE0MjkgNTAuMjVDOTMuMTQyOSA0NC42MTQxIDkwLjkxNTMgMzkuMjA5MSA4Ni45NTAzIDM1LjIyNEM4Mi45ODUyIDMxLjIzODggNzcuNjA3NCAyOSA3MiAyOVpNNjAuOTgyNiA4My4zMDM3QzYwLjQ1NCA4Mi41ODk4IDU5LjU5NTEgODIuMTkxNCA1OC43MTk2IDgyLjI3NDRDNDUuMzg5NyA4My43MzU0IDM1IDk1LjEwNzQgMzUgMTA4LjkwM0MzNSAxMTEuNzI2IDM3LjI3OTUgMTE0IDQwLjA3MSAxMTRIMTAzLjkyOUMxMDYuNzM3IDExNCAxMDkgMTExLjcwOSAxMDkgMTA4LjkwM0MxMDkgOTUuMTA3NCA5OC42MTAzIDgzLjc1MiA4NS4yNjM4IDgyLjI5MUM4NC4zODg0IDgyLjE5MTQgODMuNTI5NSA4Mi42MDY0IDgzLjAwMDkgODMuMzIwM0w3NC4wOTc4IDk1LjI0MDJDNzMuMDQwNiA5Ni42NTE0IDcwLjkyNjMgOTYuNjUxNCA2OS44NjkyIDk1LjI0MDJMNjAuOTY2MSA4My4zMjAzTDYwLjk4MjYgODMuMzAzN1oiIGZpbGw9ImJsYWNrIi8+CjwvZz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODdfMzQwMyIgeDE9IjcyIiB5MT0iMTQ0IiB4Mj0iLTEuMjgxN2UtMDUiIHkyPSI0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNDMEQ2RkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjMiIHN0b3AtY29sb3I9IiNDNERBRkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjY1IiBzdG9wLWNvbG9yPSIjRDNFOUZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0U5RkZGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zNDAzIj4KPHJlY3Qgd2lkdGg9Ijc0IiBoZWlnaHQ9Ijg1IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzUgMjkpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==
|
||||
keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "etcd"], ["spec", "monitoring"], ["spec", "ingress"], ["spec", "seaweedfs"], ["spec", "resourceQuotas"]]
|
||||
keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "etcd"], ["spec", "monitoring"], ["spec", "ingress"], ["spec", "seaweedfs"], ["spec", "schedulingClass"], ["spec", "resourceQuotas"]]
|
||||
secrets:
|
||||
exclude: []
|
||||
include: []
|
||||
|
||||
@@ -224,8 +224,8 @@ func buildPostProcessV3(kindSchemas map[string]string) func(*spec3.OpenAPI) (*sp
|
||||
base, ok1 := doc.Components.Schemas[baseRef]
|
||||
list, ok2 := doc.Components.Schemas[baseListRef]
|
||||
stat, ok3 := doc.Components.Schemas[baseStatusRef]
|
||||
if !(ok1 && ok2 && ok3) && len(kindSchemas) > 0 {
|
||||
return doc, fmt.Errorf("base Application* schemas not found")
|
||||
if !(ok1 && ok2 && ok3) {
|
||||
return doc, nil // not the apps GV — nothing to patch
|
||||
}
|
||||
|
||||
// Clone base schemas for each kind
|
||||
@@ -339,8 +339,8 @@ func buildPostProcessV2(kindSchemas map[string]string) func(*spec.Swagger) (*spe
|
||||
base, ok1 := defs[baseRef]
|
||||
list, ok2 := defs[baseListRef]
|
||||
stat, ok3 := defs[baseStatusRef]
|
||||
if !(ok1 && ok2 && ok3) && len(kindSchemas) > 0 {
|
||||
return sw, fmt.Errorf("base Application* schemas not found")
|
||||
if !(ok1 && ok2 && ok3) {
|
||||
return sw, nil // not the apps GV — nothing to patch
|
||||
}
|
||||
|
||||
for kind, raw := range kindSchemas {
|
||||
|
||||
Reference in New Issue
Block a user