diff --git a/.github/workflows/chart-push-release.yml b/.github/workflows/chart-push-release.yml new file mode 100644 index 000000000..912ed8fb0 --- /dev/null +++ b/.github/workflows/chart-push-release.yml @@ -0,0 +1,34 @@ +name: "Push helm chart on release" + +env: + IMAGE_NAME: ghcr.io/${{ github.repository }} + +on: + push: + tags: + - v* +jobs: + package-and-push-helm-chart: + runs-on: ubuntu-22.04 + steps: + - name: install helm + uses: azure/setup-helm@v4.2.0 + with: + version: latest + + - name: Check out the repo + uses: actions/checkout@v4 + + - name: update chart + env: + GITHUB_TAG: ${{ github.ref_name }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPO_OWNER: ${{ github.repository_owner }} + run: make chart-prepare-release + + - name: push chart + env: + GITHUB_TAG: ${{ github.ref_name }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPO_OWNER: ${{ github.repository_owner }} + run: make chart-push-release diff --git a/Makefile b/Makefile index d74fbdc8e..61440079b 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,6 @@ +CURPATH=$(PWD) +BIN_DIR=$(CURPATH)/bin + IMAGE_NAME ?= whereabouts IMAGE_REGISTRY ?= ghcr.io/k8snetworkplumbingwg IMAGE_PULL_POLICY ?= Always @@ -24,3 +27,19 @@ test: build install-tools kind: hack/e2e-setup-kind-cluster.sh -n $(COMPUTE_NODES) + +$(BIN_DIR): + @mkdir -p $(BIN_DIR) + +YQ=$(BIN_DIR)/yq +YQ_VERSION=v4.44.1 +$(YQ): | $(BIN_DIR); $(info installing yq) + @curl -fsSL -o $(YQ) https://github.com/mikefarah/yq/releases/download/$(YQ_VERSION)/yq_linux_amd64 && chmod +x $(YQ) + +.PHONY: chart-prepare-release +chart-prepare-release: | $(YQ) ; ## prepare chart for release + @GITHUB_TAG=$(GITHUB_TAG) GITHUB_TOKEN=$(GITHUB_TOKEN) GITHUB_REPO_OWNER=$(GITHUB_REPO_OWNER) hack/release/chart-update.sh + +.PHONY: chart-push-release +chart-push-release: ## push release chart + @GITHUB_TAG=$(GITHUB_TAG) GITHUB_TOKEN=$(GITHUB_TOKEN) GITHUB_REPO_OWNER=$(GITHUB_REPO_OWNER) hack/release/chart-push.sh diff --git a/README.md b/README.md index d3c331ffd..acea31329 100644 --- a/README.md +++ b/README.md @@ -51,13 +51,10 @@ kubectl apply \ The daemonset installation requires Kubernetes Version 1.16 or later. ### Installing with helm 3 -You can also install multus and whereabouts with helm 3 (helm 2 is not supported) +You can also install whereabouts with helm 3: ``` -git clone https://github.com/k8snetworkplumbingwg/helm-charts.git -cd helm-charts -helm upgrade --install multus ./multus --namespace kube-system -helm upgrade --install whereabouts ./whereabouts --namespace kube-system +helm template whereabouts oci://ghcr.io/k8snetworkplumbingwg/whereabouts-chart --version ``` diff --git a/deployment/whereabouts-chart/Chart.yaml b/deployment/whereabouts-chart/Chart.yaml new file mode 100644 index 000000000..86d3c6b4c --- /dev/null +++ b/deployment/whereabouts-chart/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +name: whereabouts-chart +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# 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. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.1 + +# 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 +# follow Semantic Versioning. They should reflect the version the application is using. +appVersion: v0.8.0 diff --git a/deployment/whereabouts-chart/crds/whereabouts.cni.cncf.io_ippools.yaml b/deployment/whereabouts-chart/crds/whereabouts.cni.cncf.io_ippools.yaml new file mode 100644 index 000000000..c912654e3 --- /dev/null +++ b/deployment/whereabouts-chart/crds/whereabouts.cni.cncf.io_ippools.yaml @@ -0,0 +1,69 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: ippools.whereabouts.cni.cncf.io +spec: + group: whereabouts.cni.cncf.io + names: + kind: IPPool + listKind: IPPoolList + plural: ippools + singular: ippool + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IPPool is the Schema for the ippools API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: IPPoolSpec defines the desired state of IPPool + properties: + allocations: + additionalProperties: + description: IPAllocation represents metadata about the pod/container + owner of a specific IP + properties: + id: + type: string + podref: + type: string + required: + - id + type: object + description: Allocations is the set of allocated IPs for the given + range. Its` indices are a direct mapping to the IP with the same + index/offset for the pool's range. + type: object + range: + description: Range is a RFC 4632/4291-style string that represents + an IP address and prefix length in CIDR notation + type: string + required: + - allocations + - range + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deployment/whereabouts-chart/crds/whereabouts.cni.cncf.io_overlappingrangeipreservations.yaml b/deployment/whereabouts-chart/crds/whereabouts.cni.cncf.io_overlappingrangeipreservations.yaml new file mode 100644 index 000000000..82d9547d4 --- /dev/null +++ b/deployment/whereabouts-chart/crds/whereabouts.cni.cncf.io_overlappingrangeipreservations.yaml @@ -0,0 +1,56 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: overlappingrangeipreservations.whereabouts.cni.cncf.io +spec: + group: whereabouts.cni.cncf.io + names: + kind: OverlappingRangeIPReservation + listKind: OverlappingRangeIPReservationList + plural: overlappingrangeipreservations + singular: overlappingrangeipreservation + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: OverlappingRangeIPReservation is the Schema for the OverlappingRangeIPReservations + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: OverlappingRangeIPReservationSpec defines the desired state + of OverlappingRangeIPReservation + properties: + containerid: + type: string + podref: + type: string + required: + - containerid + type: object + required: + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deployment/whereabouts-chart/templates/NOTES.txt b/deployment/whereabouts-chart/templates/NOTES.txt new file mode 100644 index 000000000..e68e92df9 --- /dev/null +++ b/deployment/whereabouts-chart/templates/NOTES.txt @@ -0,0 +1,5 @@ +Whereabouts is installed!! + +You can view the pods with the following command: + +kubectl get pods -n {{ .Release.Namespace }} -l app=whereabouts diff --git a/deployment/whereabouts-chart/templates/_helpers.tpl b/deployment/whereabouts-chart/templates/_helpers.tpl new file mode 100644 index 000000000..7dd6fe731 --- /dev/null +++ b/deployment/whereabouts-chart/templates/_helpers.tpl @@ -0,0 +1,75 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "whereabouts.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "whereabouts.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Provide a method to override namespace so parent charts can set it +*/}} +{{- define "whereabouts.namespace" -}} +{{- if hasKey .Values "namespaceOverride" -}} +namespace: {{ .Values.namespaceOverride }} +{{- else }} +namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "whereabouts.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "whereabouts.labels" -}} +app: whereabouts +helm.sh/chart: {{ include "whereabouts.chart" . }} +{{ include "whereabouts.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "whereabouts.selectorLabels" -}} +app: {{ include "whereabouts.name" . }} +app.kubernetes.io/name: {{ include "whereabouts.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "whereabouts.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "whereabouts.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/deployment/whereabouts-chart/templates/cluster_role.yaml b/deployment/whereabouts-chart/templates/cluster_role.yaml new file mode 100644 index 000000000..61a732d22 --- /dev/null +++ b/deployment/whereabouts-chart/templates/cluster_role.yaml @@ -0,0 +1,49 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "whereabouts.serviceAccountName" . }} +rules: +- apiGroups: + - whereabouts.cni.cncf.io + resources: + - ippools + - overlappingrangeipreservations + - nodeslicepools + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - '*' +- apiGroups: [""] + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: ["k8s.cni.cncf.io"] + resources: + - network-attachment-definitions + verbs: + - get + - list + - watch +- apiGroups: + - "" + - events.k8s.io + resources: + - events + verbs: + - create + - patch + - update + - get diff --git a/deployment/whereabouts-chart/templates/cluster_role_binding.yaml b/deployment/whereabouts-chart/templates/cluster_role_binding.yaml new file mode 100644 index 000000000..b1c0127de --- /dev/null +++ b/deployment/whereabouts-chart/templates/cluster_role_binding.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create -}} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "whereabouts.serviceAccountName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "whereabouts.serviceAccountName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "whereabouts.serviceAccountName" . }} + {{- include "whereabouts.namespace" . | nindent 2 }} +{{- end }} diff --git a/deployment/whereabouts-chart/templates/configmap.yaml b/deployment/whereabouts-chart/templates/configmap.yaml new file mode 100644 index 000000000..2e6c8029b --- /dev/null +++ b/deployment/whereabouts-chart/templates/configmap.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "whereabouts.fullname" . }}-config + {{- include "whereabouts.namespace" . | nindent 2 }} + annotations: + kubernetes.io/description: | + Configmap containing user customizable cronjob schedule +data: + cron-expression: "30 4 * * *" # Default schedule is once per day at 4:30am. Users may configure this value to their liking. diff --git a/deployment/whereabouts-chart/templates/cronjob.yaml b/deployment/whereabouts-chart/templates/cronjob.yaml new file mode 100644 index 000000000..9a3eb65cc --- /dev/null +++ b/deployment/whereabouts-chart/templates/cronjob.yaml @@ -0,0 +1,57 @@ +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + name: {{ include "whereabouts.fullname" . }} + {{- include "whereabouts.namespace" . | nindent 2 }} + labels: + {{- include "whereabouts.labels" . | nindent 4 }} +spec: + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: {{ .Values.successfulJobsHistoryLimit | default "0" }} + schedule: "*/5 * * * *" + jobTemplate: + spec: + backoffLimit: 0 + template: + metadata: + labels: + name: whereabouts + {{- include "whereabouts.selectorLabels" . | nindent 12 }} + spec: + priorityClassName: "system-node-critical" + serviceAccountName: {{ include "whereabouts.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 12 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 16 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + {{- toYaml .Values.resources | nindent 16 }} + command: + - /ip-reconciler + - -log-level=verbose + volumeMounts: + - name: cni-net-dir + mountPath: /host/etc/cni/net.d + volumes: + - name: cni-net-dir + hostPath: + path: /etc/cni/net.d + restartPolicy: OnFailure + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 12 }} + {{- end }} diff --git a/deployment/whereabouts-chart/templates/daemonset.yaml b/deployment/whereabouts-chart/templates/daemonset.yaml new file mode 100644 index 000000000..aad360871 --- /dev/null +++ b/deployment/whereabouts-chart/templates/daemonset.yaml @@ -0,0 +1,89 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "whereabouts.fullname" . }} + {{- include "whereabouts.namespace" . | nindent 2 }} + labels: + {{- include "whereabouts.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + name: whereabouts + {{- include "whereabouts.selectorLabels" . | nindent 6 }} + updateStrategy: + type: {{ .Values.updateStrategy }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + name: whereabouts + {{- include "whereabouts.selectorLabels" . | nindent 8 }} + spec: + hostNetwork: true + serviceAccountName: {{ include "whereabouts.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: [ "/bin/sh" ] + args: + - -c + - > + SLEEP=false /install-cni.sh && + /ip-control-loop -log-level debug + env: + - name: NODENAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: WHEREABOUTS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: cnibin + mountPath: /host/opt/cni/bin + - name: cni-net-dir + mountPath: /host/etc/cni/net.d + - name: cron-scheduler-configmap + mountPath: /cron-schedule + volumes: + - name: cnibin + hostPath: + path: {{ .Values.cniConf.binDir }} + - name: cni-net-dir + hostPath: + path: {{ .Values.cniConf.confDir }} + - name: cron-scheduler-configmap + configMap: + name: {{ include "whereabouts.fullname" . }}-config + defaultMode: 0744 + items: + - key: "cron-expression" + path: "config" + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/deployment/whereabouts-chart/templates/node-slice-controller.yaml b/deployment/whereabouts-chart/templates/node-slice-controller.yaml new file mode 100644 index 000000000..889905a61 --- /dev/null +++ b/deployment/whereabouts-chart/templates/node-slice-controller.yaml @@ -0,0 +1,87 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "whereabouts.fullname" . }}-controller + {{- include "whereabouts.namespace" . | nindent 2 }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ include "whereabouts.fullname" . }}-controller + template: + metadata: + labels: + app: {{ include "whereabouts.fullname" . }}-controller + spec: + containers: + - command: + - /node-slice-controller + env: + - name: NODENAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: WHEREABOUTS_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + name: whereabouts + resources: + {{- toYaml .Values.resources | nindent 12 }} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cnibin + - mountPath: /host/etc/cni/net.d + name: cni-net-dir + - mountPath: /cron-schedule + name: cron-scheduler-configmap + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-6kd6k + readOnly: true + preemptionPolicy: PreemptLowerPriority + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: {{ include "whereabouts.serviceAccountName" . }} + serviceAccountName: {{ include "whereabouts.serviceAccountName" . }} + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: /opt/cni/bin + type: "" + name: cnibin + - hostPath: + path: /etc/cni/net.d + type: "" + name: cni-net-dir + - configMap: + defaultMode: 484 + items: + - key: cron-expression + path: config + name: {{ include "whereabouts.fullname" . }}-config + name: cron-scheduler-configmap + - name: kube-api-access-6kd6k + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace \ No newline at end of file diff --git a/deployment/whereabouts-chart/templates/serviceaccount.yaml b/deployment/whereabouts-chart/templates/serviceaccount.yaml new file mode 100644 index 000000000..47147d458 --- /dev/null +++ b/deployment/whereabouts-chart/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "whereabouts.serviceAccountName" . }} + {{- include "whereabouts.namespace" . | nindent 2 }} + labels: + {{- include "whereabouts.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/deployment/whereabouts-chart/values.yaml b/deployment/whereabouts-chart/values.yaml new file mode 100644 index 000000000..f632a5568 --- /dev/null +++ b/deployment/whereabouts-chart/values.yaml @@ -0,0 +1,54 @@ +# Default values for whereabouts. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +image: + repository: ghcr.io/k8snetworkplumbingwg/whereabouts + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v0.8.0 + +updateStrategy: RollingUpdate +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" +namespaceOverride: "kube-system" +successfulJobsHistoryLimit: 0 + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + #name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: + privileged: true + +resources: + requests: + cpu: "100m" + memory: "50Mi" + limits: + cpu: "100m" + memory: "50Mi" + +nodeSelector: + kubernetes.io/os: linux + +tolerations: + - operator: Exists + effect: NoSchedule + +affinity: {} + +cniConf: + confDir: /etc/cni/net.d + binDir: /opt/cni/bin diff --git a/hack/release/chart-push.sh b/hack/release/chart-push.sh new file mode 100755 index 000000000..97c2629bd --- /dev/null +++ b/hack/release/chart-push.sh @@ -0,0 +1,42 @@ +#!/bin/bash +set -ex + +# github repo owner: e.g k8snetworkplumbingwg +GITHUB_REPO_OWNER=${GITHUB_REPO_OWNER:-} +# github api token with package:write permissions +GITHUB_TOKEN=${GITHUB_TOKEN:-} +# github tag e.g v1.2.3 +GITHUB_TAG=${GITHUB_TAG:-} + +BASE=${PWD} +HELM_CHART=${BASE}/deployment/whereabouts-chart +HELM_CHART_VERSION=${GITHUB_TAG#"v"} +HELM_CHART_TARBALL="whereabouts-chart-${HELM_CHART_VERSION}.tgz" + +# make sure helm is installed +set +e +which helm +if [ $? -ne 0 ]; then + echo "ERROR: helm must be installed" + exit 1 +fi +set -e + +if [ -z "$GITHUB_REPO_OWNER" ]; then + echo "ERROR: GITHUB_REPO_OWNER must be provided as env var" + exit 1 +fi + +if [ -z "$GITHUB_TOKEN" ]; then + echo "ERROR: GITHUB_TOKEN must be provided as env var" + exit 1 +fi + +if [ -z "$GITHUB_TAG" ]; then + echo "ERROR: GITHUB_TAG must be provided as env var" + exit 1 +fi + +helm package ${HELM_CHART} +helm registry login ghcr.io -u ${GITHUB_REPO_OWNER} -p ${GITHUB_TOKEN} +helm push ${HELM_CHART_TARBALL} oci://ghcr.io/${GITHUB_REPO_OWNER} diff --git a/hack/release/chart-update.sh b/hack/release/chart-update.sh new file mode 100755 index 000000000..7ce19b7ab --- /dev/null +++ b/hack/release/chart-update.sh @@ -0,0 +1,55 @@ +#!/bin/bash +set -ex + +# github tag e.g v1.2.3 +GITHUB_TAG=${GITHUB_TAG:-} +# github api token (needed only for read access) +GITHUB_TOKEN=${GITHUB_TOKEN:-} +# github repo owner e.g k8snetworkplumbingwg +GITHUB_REPO_OWNER=${GITHUB_REPO_OWNER:-} + +BASE=${PWD} +YQ_CMD="${BASE}/bin/yq" +HELM_VALUES=${BASE}/deployment/whereabouts-chart/values.yaml +HELM_CHART=${BASE}/deployment/whereabouts-chart/Chart.yaml + + +if [ -z "$GITHUB_TAG" ]; then + echo "ERROR: GITHUB_TAG must be provided as env var" + exit 1 +fi + +if [ -z "$GITHUB_TOKEN" ]; then + echo "ERROR: GITHUB_TOKEN must be provided as env var" + exit 1 +fi + +if [ -z "$GITHUB_REPO_OWNER" ]; then + echo "ERROR: GITHUB_REPO_OWNER must be provided as env var" + exit 1 +fi + +get_latest_github_tag() { + local owner="$1" + local repo="$2" + local latest_tag + + # Fetch the latest tags using GitHub API and extract the latest tag name + latest_tag=$(curl -s "https://api.github.com/repos/$owner/$repo/tags" --header "Authorization: Bearer ${GITHUB_TOKEN}" | jq -r '.[0].name') + + echo "$latest_tag" +} + +# tag provided via env var +WHEREABOUTS_TAG=${GITHUB_TAG} + +# patch values.yaml in-place + +# whereabouts image: +WHEREABOUTS_REPO=${GITHUB_REPO_OWNER} # this is used to allow to release whereabouts from forks +$YQ_CMD -i ".image.repository = \"ghcr.io/${WHEREABOUTS_REPO}/whereabouts\"" ${HELM_VALUES} +$YQ_CMD -i ".image.tag = \"${WHEREABOUTS_TAG}\"" ${HELM_VALUES} + +# patch Chart.yaml in-place +$YQ_CMD -i ".version = \"${WHEREABOUTS_TAG#"v"}\"" ${HELM_CHART} +$YQ_CMD -i ".appVersion = \"${WHEREABOUTS_TAG}\"" ${HELM_CHART}