diff --git a/argocd/applications/woodpecker.yaml b/argocd/applications/woodpecker.yaml index d55e20a..54a1ac5 100644 --- a/argocd/applications/woodpecker.yaml +++ b/argocd/applications/woodpecker.yaml @@ -6,10 +6,13 @@ metadata: namespace: argocd spec: project: k-space.ee - source: - repoURL: 'git@git.k-space.ee:k-space/kube.git' - path: woodpecker - targetRevision: HEAD + sources: + - repoURL: git@git.k-space.ee:k-space/kube.git + targetRevision: HEAD + path: woodpecker + - repoURL: 'git@git.k-space.ee:secretspace/kube.git' + targetRevision: HEAD + path: woodpecker destination: server: 'https://kubernetes.default.svc' namespace: woodpecker diff --git a/woodpecker/.gitignore b/woodpecker/.gitignore new file mode 100644 index 0000000..2faa846 --- /dev/null +++ b/woodpecker/.gitignore @@ -0,0 +1,2 @@ +charts/ +*.env diff --git a/woodpecker/README.md b/woodpecker/README.md index 0367159..0627425 100644 --- a/woodpecker/README.md +++ b/woodpecker/README.md @@ -1,17 +1,26 @@ -# Woodpecker CI -Woodpecker CI obsoletes Drone CI which has confusing licensing conditions. +First kustomize helm chart thing. -Deployment steps: +As of commit time, woodpecker chart does not support agents in separate namespace. +Render it locally: + +```sh +kustomize build . --enable-helm ``` -kubectl create namespace woodpecker -kubectl create namespace woodpecker-execution -kubectl create secret generic -n woodpecker woodpecker-secret \ - --from-literal=WOODPECKER_AGENT_SECRET=$(openssl rand -hex 32) \ - --from-literal=WOODPECKER_GITEA_CLIENT=... \ - --from-literal=WOODPECKER_GITEA_SECRET=... -kubectl create secret generic -n woodpecker-execution woodpecker-secret \ - --from-literal=WOODPECKER_AGENT_SECRET=$(kubectl get secret -n woodpecker woodpecker-secret -o jsonpath="{.data.WOODPECKER_AGENT_SECRET}" | base64 -d) -kubectl apply -n woodpecker -f woodpecker-server.yml -kubectl apply -n woodpecker-execution -f woodpecker-agent.yml + +If upstream chart does not have `extraSecretNamesForEnvFrom`, patch instead: + +```yaml +patches: +- target: + version: v1 + kind: StatefulSet + name: release-name-server + # or: labelSelector: app.kubernetes.io/name=server + patch: |- + - op: add + path: /spec/template/spec/containers/0/envFrom/- + value: + secretRef: + name: woodpecker-gitea-oauth2 ``` diff --git a/woodpecker/kustomization.yaml b/woodpecker/kustomization.yaml new file mode 100644 index 0000000..7d8b122 --- /dev/null +++ b/woodpecker/kustomization.yaml @@ -0,0 +1,61 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: woodpecker + +# spec: https://kubectl.docs.kubernetes.io/references/kustomize/builtins/#_helmchartinflationgenerator_ +helmCharts: +- includeCRDs: true + name: &name woodpecker + releaseName: *name + repo: oci://ghcr.io/woodpecker-ci/helm + valuesInline: + agent: + image: + registry: mirror.gcr.io + env: + WOODPECKER_BACKEND_K8S_STORAGE_CLASS: woodpecker + WOODPECKER_BACKEND_K8S_VOLUME_SIZE: 100Mi + persistence: + enabled: false + server: + ingress: + enabled: true + ingressClassName: treafik + annotations: + external-dns.alpha.kubernetes.io/target: traefik.k-space.ee + traefik.ingress.kubernetes.io/router.entrypoints: websecure + hosts: + - host: woodpecker.k-space.ee + paths: + - backend: + serviceName: woodpecker-server # *name-server (from releaseName) + path: "/" + tls: + - hosts: ["*.k-space.ee"] + + env: + WOODPECKER_ADMIN: eaas,rasmus + WOODPECKER_DATABASE_DRIVER: mysql + WOODPECKER_GITEA: true + WOODPECKER_GITEA_URL: https://git.k-space.ee + WOODPECKER_HOST: https://woodpecker.k-space.ee + WOODPECKER_OPEN: true + extraSecretNamesForEnvFrom: + - woodpecker-gitea-oauth2 + - woodpecker-db + image: + registry: mirror.gcr.io + # persistentVolume: + # enabled: false + version: 3.0.7 + +secretGenerator: + - name: woodpecker-gitea-oauth2 + envs: + - woodpecker-gitea.env + - name: woodpecker-db + literals: + - WOODPECKER_DATABASE_DRIVER=mysql + envs: + - woodpecker-db.env diff --git a/woodpecker/woodpecker-agent.yml b/woodpecker/woodpecker-agent.yml deleted file mode 100644 index 700b723..0000000 --- a/woodpecker/woodpecker-agent.yml +++ /dev/null @@ -1,99 +0,0 @@ ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: woodpecker-agent - namespace: woodpecker-execution ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: woodpecker-agent - namespace: woodpecker-execution -rules: - - apiGroups: - - '' - resources: - - persistentvolumeclaims - verbs: - - create - - delete - - apiGroups: - - '' - resources: - - services - verbs: - - create - - delete - - apiGroups: - - '' - resources: - - pods - - pods/log - verbs: - - watch - - create - - delete - - get - - list ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: woodpecker-agent - namespace: woodpecker-execution -subjects: - - kind: ServiceAccount - name: woodpecker-agent - namespace: woodpecker-execution -roleRef: - kind: Role - name: woodpecker-agent - apiGroup: rbac.authorization.k8s.io ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: woodpecker-agent - namespace: woodpecker-execution -spec: - replicas: 2 - selector: - matchLabels: - app: woodpecker-agent - template: - metadata: - labels: - app: woodpecker-agent - spec: - serviceAccountName: woodpecker-agent - securityContext: - runAsNonRoot: true - runAsUser: 1000 - containers: - - name: agent - securityContext: - readOnlyRootFilesystem: false - image: woodpeckerci/woodpecker-agent:v2.7.0 - ports: - - name: http - containerPort: 3000 - protocol: TCP - env: - - name: WOODPECKER_BACKEND - value: kubernetes - - name: WOODPECKER_BACKEND_K8S_NAMESPACE - value: woodpecker-execution - - name: WOODPECKER_BACKEND_K8S_STORAGE_CLASS - value: woodpecker - - name: WOODPECKER_BACKEND_K8S_STORAGE_RWX - value: "true" - - name: WOODPECKER_BACKEND_K8S_VOLUME_SIZE - value: 100Mi - - name: WOODPECKER_SERVER - value: "woodpecker-grpc.woodpecker.svc.cluster.local:9000" - - name: WOODPECKER_AGENT_SECRET - valueFrom: - secretKeyRef: - name: woodpecker-secret - key: WOODPECKER_AGENT_SECRET diff --git a/woodpecker/woodpecker-db.env.example b/woodpecker/woodpecker-db.env.example new file mode 100644 index 0000000..64fe99c --- /dev/null +++ b/woodpecker/woodpecker-db.env.example @@ -0,0 +1,2 @@ +# Don't be a dummy by commiting renders with secrets +WOODPECKER_DATABASE_DATASOURCE=kspace_woodpecker:<SECRET>@tcp(172.20.36.1:3306)/kspace_woodpecker?parseTime=true diff --git a/woodpecker/woodpecker-gitea.env.example b/woodpecker/woodpecker-gitea.env.example new file mode 100644 index 0000000..360fc70 --- /dev/null +++ b/woodpecker/woodpecker-gitea.env.example @@ -0,0 +1,5 @@ +# Don't be a dummy by commiting renders with secrets +# +# https://woodpecker-ci.org/docs/administration/configuration/forges/gitea#registration +WOODPECKER_GITEA_CLIENT= +WOODPECKER_GITEA_SECRET= diff --git a/woodpecker/woodpecker-server.yml b/woodpecker/woodpecker-server.yml deleted file mode 100644 index 205b206..0000000 --- a/woodpecker/woodpecker-server.yml +++ /dev/null @@ -1,118 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: woodpecker -spec: - type: ClusterIP - ports: - - port: 80 - targetPort: http - protocol: TCP - name: http - selector: - app: woodpecker ---- -apiVersion: v1 -kind: Service -metadata: - name: woodpecker-grpc -spec: - type: ClusterIP - ports: - - port: 9000 - targetPort: grpc - protocol: TCP - name: grpc - selector: - app: woodpecker ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: woodpecker -spec: - serviceName: woodpecker - replicas: 1 - selector: - matchLabels: - app: woodpecker - template: - metadata: - labels: - app: woodpecker - spec: - automountServiceAccountToken: false - securityContext: - {} - containers: - - name: server - image: woodpeckerci/woodpecker-server:v2.7.0 - ports: - - name: http - containerPort: 8000 - - name: grpc - containerPort: 9000 - env: - - name: WOODPECKER_ADMIN - value: eaas - - name: WOODPECKER_OPEN - value: "true" - - name: WOODPECKER_HOST - value: "https://woodpecker.k-space.ee" - - name: WOODPECKER_GITEA - value: "true" - - name: WOODPECKER_GITEA_URL - value: "https://git.k-space.ee/" - - name: WOODPECKER_GITEA_CLIENT - valueFrom: - secretKeyRef: - name: woodpecker-secret - key: WOODPECKER_GITEA_CLIENT - - name: WOODPECKER_GITEA_SECRET - valueFrom: - secretKeyRef: - name: woodpecker-secret - key: WOODPECKER_GITEA_SECRET - - name: "WOODPECKER_AGENT_SECRET" - valueFrom: - secretKeyRef: - name: woodpecker-secret - key: WOODPECKER_AGENT_SECRET - - name: "WOODPECKER_DATABASE_DRIVER" - value: "mysql" - envFrom: - - secretRef: - name: woodpecker-mysql - volumeMounts: - - name: woodpecker-data - mountPath: /var/lib/woodpecker - volumes: - - name: woodpecker-data - persistentVolumeClaim: - claimName: woodpecker-data-woodpecker-0 ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: woodpecker - annotations: - external-dns.alpha.kubernetes.io/target: traefik.k-space.ee - kubernetes.io/ingress.class: traefik - traefik.ingress.kubernetes.io/router.entrypoints: websecure - traefik.ingress.kubernetes.io/router.tls: "true" -spec: - tls: - - hosts: - - "*.k-space.ee" - rules: - - host: "woodpecker.k-space.ee" - http: - paths: - - pathType: Prefix - path: / - backend: - service: - name: woodpecker - port: - number: 80