Init Image (to create user), plus some (not all) automation of test
This commit is contained in:
parent
c2dd6143e6
commit
8e5fdff0cd
13
.drone.yml
13
.drone.yml
@ -7,11 +7,20 @@ platform:
|
||||
arch: arm64
|
||||
|
||||
steps:
|
||||
- name: push-built-image
|
||||
- name: push-built-init-image
|
||||
image: plugins/docker
|
||||
settings:
|
||||
registry: gitea.scubbo.org
|
||||
repo: gitea.scubbo.org/scubbo/drone-build-status-monitor
|
||||
repo: gitea.scubbo.org/scubbo/drone-build-status-monitor-init
|
||||
username: scubbo
|
||||
password:
|
||||
from_secret: gitea_password
|
||||
- name: push-built-main-image
|
||||
image: plugins/docker
|
||||
settings:
|
||||
dockerfile: Dockerfile-initImage
|
||||
registry: gitea.scubbo.org
|
||||
repo: gitea.scubbo.org/scubbo/drone-build-status-monitor-main
|
||||
username: scubbo
|
||||
password:
|
||||
from_secret: gitea_password
|
@ -4,6 +4,6 @@ COPY requirements.txt requirements.txt
|
||||
RUN pip3 install -r requirements.txt
|
||||
RUN rm requirements.txt
|
||||
WORKDIR /app
|
||||
COPY src/ src
|
||||
COPY src/main/ src
|
||||
RUN chmod +x src/app.py
|
||||
CMD src/app.py
|
||||
|
12
Dockerfile-initImage
Normal file
12
Dockerfile-initImage
Normal file
@ -0,0 +1,12 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk update
|
||||
RUN apk upgrade
|
||||
RUN apk add curl
|
||||
RUN curl -L https://github.com/harness/drone-cli/releases/latest/download/drone_linux_amd64.tar.gz | tar zx
|
||||
RUN install -t /usr/local/bin drone
|
||||
|
||||
WORKDIR /app
|
||||
COPY src/init/ src
|
||||
RUN chmod +x src/init.sh
|
||||
CMD src/init.sh
|
@ -1,7 +1,8 @@
|
||||
TODO - flesh this out more!
|
||||
|
||||
Exposes Prometheus metrics on port 8000. Listens on port 8015 for Webhook update events from Drone.
|
||||
AFAICT, Drone's [metrics]()Exposes Prometheus metrics on port 8000. Listens on port 8015 for Webhook update events from Drone.
|
||||
|
||||
Environment variables:
|
||||
* `ACCESS_TOKEN`
|
||||
* `DRONE_DOMAIN`
|
||||
|
||||
## Demo
|
||||
|
||||
|
12
demo/helm/Chart.lock
Normal file
12
demo/helm/Chart.lock
Normal file
@ -0,0 +1,12 @@
|
||||
dependencies:
|
||||
- name: drone
|
||||
repository: https://charts.drone.io
|
||||
version: 0.6.4
|
||||
- name: kube-prometheus-stack
|
||||
repository: https://prometheus-community.github.io/helm-charts
|
||||
version: 42.0.0
|
||||
- name: kubernetes-dashboard
|
||||
repository: https://kubernetes.github.io/dashboard/
|
||||
version: 6.0.0
|
||||
digest: sha256:44b28e02441df32fdf8a6a039d03ae3196b4aeddb6690b9fd2601232f90ff8d1
|
||||
generated: "2022-11-30T12:58:27.135466-08:00"
|
38
demo/helm/Chart.yaml
Normal file
38
demo/helm/Chart.yaml
Normal file
@ -0,0 +1,38 @@
|
||||
apiVersion: v2
|
||||
name: drone-build-status-monitor
|
||||
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.0
|
||||
|
||||
# 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.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "1.16.0"
|
||||
|
||||
dependencies:
|
||||
# - name: gitea
|
||||
# version: "6.0.3"
|
||||
# repository: https://dl.gitea.io/charts/
|
||||
- name: drone
|
||||
version: "0.6.4"
|
||||
repository: https://charts.drone.io
|
||||
- name: kube-prometheus-stack
|
||||
version: "42.0.0"
|
||||
repository: "https://prometheus-community.github.io/helm-charts"
|
||||
- name: kubernetes-dashboard
|
||||
version: "6.0.0"
|
||||
repository: https://kubernetes.github.io/dashboard/
|
BIN
demo/helm/charts/drone-0.6.4.tgz
Normal file
BIN
demo/helm/charts/drone-0.6.4.tgz
Normal file
Binary file not shown.
BIN
demo/helm/charts/kube-prometheus-stack-42.0.0.tgz
Normal file
BIN
demo/helm/charts/kube-prometheus-stack-42.0.0.tgz
Normal file
Binary file not shown.
BIN
demo/helm/charts/kubernetes-dashboard-6.0.0.tgz
Normal file
BIN
demo/helm/charts/kubernetes-dashboard-6.0.0.tgz
Normal file
Binary file not shown.
62
demo/helm/templates/_helpers.tpl
Normal file
62
demo/helm/templates/_helpers.tpl
Normal file
@ -0,0 +1,62 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "drone-build-status-monitor.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 "drone-build-status-monitor.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 }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "drone-build-status-monitor.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "drone-build-status-monitor.labels" -}}
|
||||
helm.sh/chart: {{ include "drone-build-status-monitor.chart" . }}
|
||||
{{ include "drone-build-status-monitor.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "drone-build-status-monitor.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "drone-build-status-monitor.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "drone-build-status-monitor.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "drone-build-status-monitor.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
72
demo/helm/templates/gitea/deployment.yaml
Normal file
72
demo/helm/templates/gitea/deployment.yaml
Normal file
@ -0,0 +1,72 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-gitea
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gitea
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: gitea
|
||||
spec:
|
||||
initContainers:
|
||||
- name: init
|
||||
image: gitea/gitea:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/usr/sbin/configure_gitea.sh"]
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
env:
|
||||
- name: GITEA_ADMIN_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: username
|
||||
name: drone-build-monitor-demo-gitea-admin-creds
|
||||
- name: GITEA_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: password
|
||||
name: drone-build-monitor-demo-gitea-admin-creds
|
||||
volumeMounts:
|
||||
- name: init
|
||||
mountPath: /usr/sbin
|
||||
- mountPath: /data
|
||||
name: drone-build-monitor-demo-gitea-persistent-volume
|
||||
containers:
|
||||
- name: gitea
|
||||
image: gitea/gitea:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: USER_UID
|
||||
value: "1000"
|
||||
- name: USER_GID
|
||||
value: "1000"
|
||||
- name: GITEA__security__INSTALL_LOCK
|
||||
value: "true"
|
||||
volumeMounts:
|
||||
- mountPath: /etc/timezone
|
||||
name: timezone
|
||||
readOnly: true
|
||||
- mountPath: /etc/localtime
|
||||
name: localtime
|
||||
readOnly: true
|
||||
- mountPath: /data
|
||||
name: drone-build-monitor-demo-gitea-persistent-volume
|
||||
volumes:
|
||||
- name: drone-build-monitor-demo-gitea-persistent-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: drone-build-monitor-demo-gitea-persistent-volume-claim
|
||||
- name: timezone
|
||||
hostPath:
|
||||
path: /etc/timezone
|
||||
type: File
|
||||
- name: localtime
|
||||
hostPath:
|
||||
path: /etc/localtime
|
||||
type: File
|
||||
- name: init
|
||||
secret:
|
||||
secretName: drone-build-monitor-demo-gitea-init
|
||||
defaultMode: 110
|
38
demo/helm/templates/gitea/init-secret.yaml
Normal file
38
demo/helm/templates/gitea/init-secret.yaml
Normal file
@ -0,0 +1,38 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-gitea-init
|
||||
type: Opaque
|
||||
stringData:
|
||||
configure_gitea.sh: |-
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -uo pipefail
|
||||
set -x
|
||||
|
||||
echo '==== BEGIN GITEA CONFIGURATION ===='
|
||||
|
||||
function configure_admin_user() {
|
||||
echo "Printing a lot of debugging"
|
||||
gitea admin user list --admin
|
||||
echo "Admin Username"
|
||||
echo $GITEA_ADMIN_USERNAME
|
||||
echo "Grepped admin list:"
|
||||
gitea admin user list --admin | grep "$GITEA_ADMIN_USERNAME"
|
||||
echo "Grepped awked admin list:"
|
||||
gitea admin user list --admin | grep -e "\s\+${GITEA_ADMIN_USERNAME}\s\+" | awk -F " " "{printf \$1}"
|
||||
local ACCOUNT_ID=$(gitea admin user list --admin | grep -e "\s\+${GITEA_ADMIN_USERNAME}\s\+" | awk -F " " "{printf \$1}")
|
||||
echo "DEBUG - accountId is:";
|
||||
echo $ACCOUNT_ID;
|
||||
if [[ -z "${ACCOUNT_ID}" ]]; then
|
||||
echo "No admin user '${GITEA_ADMIN_USERNAME}' found. Creating now..."
|
||||
gitea admin user create --admin --username "${GITEA_ADMIN_USERNAME}" --password "${GITEA_ADMIN_PASSWORD}" --email "admin@example.org" --must-change-password=false
|
||||
echo '...created.'
|
||||
else
|
||||
echo "Admin account '${GITEA_ADMIN_USERNAME}' already exist. Running update to sync password..."
|
||||
gitea admin user change-password --username "${GITEA_ADMIN_USERNAME}" --password "${GITEA_ADMIN_PASSWORD}"
|
||||
echo '...password sync done.'
|
||||
fi
|
||||
}
|
||||
|
||||
configure_admin_user
|
25
demo/helm/templates/gitea/service.yaml
Normal file
25
demo/helm/templates/gitea/service.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-gitea-service
|
||||
spec:
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: gitea
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-gitea-ssh-service
|
||||
spec:
|
||||
ports:
|
||||
- port: 22
|
||||
targetPort: 22
|
||||
protocol: TCP
|
||||
name: ssh
|
||||
selector:
|
||||
app: gitea
|
35
demo/helm/templates/gitea/volumes.yaml
Normal file
35
demo/helm/templates/gitea/volumes.yaml
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-gitea-persistent-volume
|
||||
spec:
|
||||
capacity:
|
||||
storage: 1Gi
|
||||
volumeMode: Filesystem
|
||||
accessModes:
|
||||
- ReadWriteMany
|
||||
persistentVolumeReclaimPolicy: Delete
|
||||
storageClassName: local-storage
|
||||
local:
|
||||
path: /tmp/gitea-storage
|
||||
nodeAffinity:
|
||||
required:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: absent-label
|
||||
operator: DoesNotExist
|
||||
values:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-gitea-persistent-volume-claim
|
||||
spec:
|
||||
volumeName: drone-build-monitor-demo-gitea-persistent-volume
|
||||
accessModes:
|
||||
- ReadWriteMany
|
||||
storageClassName: local-storage
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
47
demo/helm/templates/nginx/conf-secret.yaml
Normal file
47
demo/helm/templates/nginx/conf-secret.yaml
Normal file
@ -0,0 +1,47 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: nginx-conf-secret
|
||||
type: Opaque
|
||||
stringData:
|
||||
nginx.conf: |-
|
||||
events {
|
||||
worker_connections 1024; ## Default
|
||||
}
|
||||
|
||||
http {
|
||||
|
||||
# Without this, docker image interaction might give a `413 Request Entity Too Large` (default 1M)
|
||||
client_max_body_size 500M;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name fakegitea.local;
|
||||
|
||||
location / {
|
||||
# Use this if running locally with docker, rather than on k8s
|
||||
# proxy_pass http://host.docker.internal:3000;
|
||||
proxy_pass http://drone-build-monitor-demo-gitea-service.demo:3000;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name fakegiteatls.local;
|
||||
|
||||
ssl_certificate /certs/domain.crt;
|
||||
ssl_certificate_key /certs/domain.key;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
location / {
|
||||
# Use this if running locally with docker, rather than on k8s
|
||||
# proxy_pass http://host.docker.internal:3000;
|
||||
proxy_pass http://drone-build-monitor-demo-gitea-service.demo:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
}
|
30
demo/helm/templates/nginx/deployment.yaml
Normal file
30
demo/helm/templates/nginx/deployment.yaml
Normal file
@ -0,0 +1,30 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-nginx
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
volumeMounts:
|
||||
- mountPath: /etc/nginx/
|
||||
name: nginx-conf
|
||||
readOnly: true
|
||||
- mountPath: /certs
|
||||
name: certs
|
||||
volumes:
|
||||
- name: nginx-conf
|
||||
secret:
|
||||
secretName: nginx-conf-secret
|
||||
- name: certs
|
||||
hostPath:
|
||||
path: /tmp/gitea-certs
|
||||
type: Directory
|
17
demo/helm/templates/nginx/ingress.yaml
Normal file
17
demo/helm/templates/nginx/ingress.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: gitea-ingress
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: fakegiteatls.local
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: drone-build-monitor-demo-gitea-service
|
||||
port:
|
||||
number: 3000
|
12
demo/helm/templates/nginx/service.yaml
Normal file
12
demo/helm/templates/nginx/service.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 443
|
||||
targetPort: 443
|
||||
protocol: TCP
|
||||
name: https
|
||||
selector:
|
||||
app: nginx
|
1
demo/helm/templates/secrets/README.md
Normal file
1
demo/helm/templates/secrets/README.md
Normal file
@ -0,0 +1 @@
|
||||
For ease of setup, some of these contain hard-coded values. Use greater care in production deployments!
|
7
demo/helm/templates/secrets/gitea-admin-credentials.yaml
Normal file
7
demo/helm/templates/secrets/gitea-admin-credentials.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-gitea-admin-creds
|
||||
stringData:
|
||||
username: admin-username
|
||||
password: admin-password
|
@ -0,0 +1,26 @@
|
||||
{{- /*
|
||||
This is a Kubernetes secret that holds the token for the Machine user used to poll the Drone API
|
||||
This pattern was taken from:
|
||||
https://itnext.io/manage-auto-generated-secrets-in-your-helm-charts-5aee48ba6918
|
||||
|
||||
This secret provides two values:
|
||||
* `DRONE_USER_CREATE`, an environment variable which will prompt Drone to create a user with the given configuration
|
||||
* `token`, the bare token of the created user, that other services can use in order to act as the user
|
||||
*/}}
|
||||
{{- if empty .Values.primaryDroneMachineUserSecret }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "primary-drone-machine-user-secret"
|
||||
annotations:
|
||||
"helm.sh/resource-policy": "keep"
|
||||
type: Opaque
|
||||
data:
|
||||
# retrieve the secret data using lookup function and when not exists, return an empty dictionary / map as result
|
||||
{{- $existing_secret := (lookup "v1" "Secret" .Release.Namespace "primary-drone-machine-user-secret") | default dict }}
|
||||
{{- $secretData := (get $existing_secret "data") | default dict }}
|
||||
# set $secret to existing secret data or generate a random one (32 chars long) when not exists
|
||||
{{- $secret := (get $secretData "token") | default (randAlphaNum 32) }}
|
||||
token: {{ $secret | b64enc | quote }}
|
||||
DRONE_USER_CREATE: {{ printf "%s%s" "username:root,admin:true,machine:true,token:" $secret | b64enc | quote }}
|
||||
{{- end }}
|
109
demo/helm/values.yaml
Normal file
109
demo/helm/values.yaml
Normal file
@ -0,0 +1,109 @@
|
||||
# Default values for drone-build-status-monitor.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: nginx
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
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: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
# targetMemoryUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
# Everything below here was hand-created
|
||||
|
||||
# Set these if you want to use an existing secret for the Drone
|
||||
# tokens (otherwise, fresh ones will be created if necessary)
|
||||
#
|
||||
# Note the required format of the secret pointed to by
|
||||
# `primaryDroneMachineUserToken` - it must have two entries:
|
||||
# * `DRONE_USER_CREATE=username:root,admin:true,machine:true,token:<token>`
|
||||
# * `token=<token>`
|
||||
#
|
||||
# For explanation why, see https://community.harness.io/t/is-it-possible-to-create-a-new-user-from-a-command-on-the-image-itself/12899/4
|
||||
primaryDroneMachineUserSecret: ""
|
||||
|
||||
# Subchart values
|
||||
kube-prometheus-stack:
|
||||
grafana:
|
||||
enabled: false
|
||||
|
||||
# TODO - fill out appropriate values here
|
||||
drone:
|
||||
extraSecretNamesForEnvFrom:
|
||||
- primary-drone-machine-user-secret
|
||||
env:
|
||||
DRONE_SERVER_HOST: drone-monitoring-demo.local
|
||||
DRONE_RPC_SECRET: hard-coding-is-very-bad-do-not-do-this-in-production
|
||||
DRONE_GITEA_SERVER: drone-build-monitor-demo-gitea-service.demo
|
103
demo/main-script.sh
Normal file
103
demo/main-script.sh
Normal file
@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Note that this is unfinished! I got bored at about the point of making
|
||||
# Gitea trust Kubernetes' certificates so that we could automatically push
|
||||
# to them - I realized that a fully-automated demo isn't really worth the
|
||||
# effort to set it up, since 99% of folks who are interested in this will
|
||||
# already have their own Drone+SourceControl setups working.
|
||||
|
||||
# https://stackoverflow.com/a/677212/1040915
|
||||
if ! command -v multipass &> /dev/null
|
||||
then
|
||||
brew install --cask multipass
|
||||
fi
|
||||
|
||||
###
|
||||
# Generate SSL/TLS certs because they are a requirement for self-hosted OCI registries
|
||||
###
|
||||
#
|
||||
# https://medium.com/@ifeanyiigili/how-to-setup-a-private-docker-registry-with-a-self-sign-certificate-43a7407a1613
|
||||
#mkdir -p /tmp/gitea-certs
|
||||
#openssl req -newkey rsa:4096 -nodes -sha256 \
|
||||
# -keyout /tmp/gitea-certs/domain.key -x509 -days 365 \
|
||||
# -out /tmp/gitea-certs/domain.crt \
|
||||
# -subj '/C=US/ST=CA/L=FakeTown/O=FakeCorp/CN=Fake Gitea Ltd./' \
|
||||
# -addext 'subjectAltName=DNS:fakegiteatls.local'
|
||||
# TODO - update K3s to use the created certificate to trust Gitea's repo:
|
||||
# https://docs.k3s.io/installation/private-registry
|
||||
|
||||
multipass launch --name k3s --mem 4G --disk 40G
|
||||
multipass transfer demo/remote-script.sh k3s:/tmp/remote-script.sh
|
||||
multipass exec k3s -- sh /tmp/remote-script.sh
|
||||
|
||||
## Transfer certificates to multipass VM
|
||||
#multipass transfer /tmp/gitea-certs/domain.crt k3s:/tmp/gitea-certs
|
||||
#multipass transfer /tmp/gitea-certs/domain.key k3s:/tmp/gitea-certs
|
||||
|
||||
# Fetch the k3s-on-multipass configuration to your laptop to enable interaction
|
||||
mkdir -p $HOME/.kube
|
||||
multipass transfer k3s:/tmp/k3s.yaml $HOME/.kube/multipass-k3s.yaml
|
||||
# Following line depends on `jq`, a super-handy utility you should really have installed already! If you don't have or want it for some reason, you can approximate this with `multipass info k3s | grep 'IPv4' | awk '{print $2}'`
|
||||
VM_IP=$(multipass info k3s --format json | jq '.info.k3s.ipv4[0]' -r)
|
||||
# I wish `sed` were consistent between installations so we didn't have to rely on perl for this...
|
||||
perl -i -pe 's/127.0.0.1/'"$VM_IP"'/' $HOME/.kube/multipass-k3s.yaml
|
||||
# Rename all the "default" entities - cluster, user, etc. - to "k3s" so that they will remain distinct when merging with existing config
|
||||
perl -i -pe 's/: default/: k3s/' $HOME/.kube/multipass-k3s.yaml
|
||||
if [[ -f $HOME/.kube/config ]]; then
|
||||
cp $HOME/.kube/config $HOME/.kube/config.BAK
|
||||
# Merge kubernetes config file into existing file: https://medium.com/@jacobtomlinson/how-to-merge-kubernetes-kubectl-config-files-737b61bd517d
|
||||
KUBECONFIG=$HOME/.kube/config:$HOME/.kube/multipass-k3s.yaml kubectl config view --flatten > /tmp/config && mv /tmp/config ~/.kube/config
|
||||
else
|
||||
mv $HOME/.kube/multipass-k3s.yaml $HOME/.kube/config
|
||||
fi
|
||||
|
||||
# This next line relies on `kubectx`. Install like so: https://github.com/ahmetb/kubectx - or manually set your `kubectl` context for these commands
|
||||
kubectl ctx k3s
|
||||
# Install dashboard separately from the main release, so we can use it to debug if things go wrong
|
||||
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
|
||||
helm install -n kubernetes-dashboard --create-namespace kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard
|
||||
# I don't know why, but the Helm chart doesn't seem to grant the created ServiceAccount appropriate permissions
|
||||
kubectl patch clusterrolebinding cluster-admin --type='json' -p='[{"op": "add", "path": "/subjects/1", "value": {"kind": "ServiceAccount", "name": "kubernetes-dashboard", "namespace":"kubernetes-dashboard"}}]'
|
||||
echo "Run 'kubectl proxy' in a separate terminal, then navigate to http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:443/proxy/"
|
||||
echo "Use the following token to log in to the Kubernetes dashboard: $(kubectl -n kubernetes-dashboard create token kubernetes-dashboard)"
|
||||
echo "[Press Enter to continue]"
|
||||
read
|
||||
helm dependency build helm/
|
||||
helm install -n demo --create-namespace demo helm/
|
||||
# Drone UI available on http://localhost:8001/api/v1/namespaces/demo/services/http:demo-drone:8080/proxy
|
||||
# Prometheus UI available on http://localhost:8001/api/v1/namespaces/demo/services/http:demo-kube-prometheus-stack-prometheus:9090/proxy/graph
|
||||
# Gitea UI available on http://localhost:8001/api/v1/namespaces/demo/services/http:drone-build-monitor-demo-gitea-service:3000/proxy/
|
||||
|
||||
|
||||
# This is a hack - it looks like the `configure-gitea` script can't run properly on first execution,
|
||||
# since the installation hasn't completed (and won't, until the Web UI is loaded and interacted with) -
|
||||
# so, by deleting the Gitea pod (which will then be recreated because of the deployment), the `initContainer` is re-run,
|
||||
# creating the admin user with provided credentials.
|
||||
#
|
||||
# There's probably a way to skip the Web UI requirement for installation, but this is just a proof-of-concept
|
||||
# so I'm not going to spend much time trying to find it. Please do let me know if you know how to do it, though!
|
||||
#
|
||||
# The below is commented out because I _think_ I've found how to get around that (by setting `GITEA__security__INSTALL_LOCK=true`,
|
||||
# then calling `gitea migrate` before creating the user) - but keeping it around in case I need it
|
||||
#kubectl delete pod $(kubectl get pods | grep 'gitea' | awk '{print $1}')
|
||||
|
||||
# Do this manually because I don't want to risk messing with sudo privileges!
|
||||
echo "Add the following line to your /etc/hosts:"
|
||||
echo "${VM_IP} fakegiteatls.local"
|
||||
read
|
||||
# Ditto - we probably _could_ do this with automated /etc/docker/daemon.json editing (or
|
||||
# whatever the equivalent is for Mac), but probably not worth it
|
||||
echo "Now add 'fakegiteatls.local' as an insecure Docker Registry, in whatever way"
|
||||
echo "is appropriate for your system"
|
||||
|
||||
# TODO - docker login (and, also, save to Kubernetes cluster)
|
||||
docker build -t drone-build-metrics-init -f ../Dockerfile-initImage ..
|
||||
docker tag drone-build-metrics-init fakegiteatls.local/root/drone-build-metrics-init
|
||||
|
||||
docker build -t drone-build-metrics-demo ..
|
||||
docker tag drone-build-metrics-demo fakegiteatls.local/root/drone-build-metrics-demo
|
||||
|
||||
# ...and then we would set up a Drone build by creating a repository and making an automated
|
||||
# push to it, and then observe metrics.
|
||||
|
||||
|
39
demo/monitoring-deployment.yaml
Normal file
39
demo/monitoring-deployment.yaml
Normal file
@ -0,0 +1,39 @@
|
||||
# This deployment is applied separately from the main Helm chart - which
|
||||
# sets up Drone, Gitea as a Drone source, and Prometheus and Grafana for
|
||||
# monitoring and visualization - because it depends on Gitea being set up
|
||||
# so that we can build and push an image to the Gitea registry.
|
||||
#
|
||||
# This could _probably_ be carried out fully automatically by having
|
||||
# the deployment wait on the presence of the image in the Gitea registry
|
||||
# (with an initContainer that waits on availability), but that seems like
|
||||
# more complexity than is worth it for this proof-of-concept
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: drone-build-monitor-demo-monitor
|
||||
namespace: demo
|
||||
spec:
|
||||
select:
|
||||
matchLabels:
|
||||
app: monitoring
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: monitoring
|
||||
spec:
|
||||
initContainers:
|
||||
- name: init
|
||||
image: "drone-build-monitor-demo-gitea-service.demo:3000/root/drone-monitor-init"
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/app/init.sh"]
|
||||
env:
|
||||
- name: PRIMARY_DRONE_USER_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: token
|
||||
name: primary-drone-machine-user-secret
|
||||
- name: DRONE_URL
|
||||
value: "demo-drone.demo:8080"
|
||||
containers:
|
||||
- name: placeholder
|
||||
image: ubuntu
|
24
demo/remote-script.sh
Executable file
24
demo/remote-script.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
# DO NOT run this script directly - this will be copied to the Multipass cluster to set up k3s
|
||||
sudo apt update
|
||||
sudo NEEDRESTART_MODE=a apt upgrade -y
|
||||
|
||||
# Install k3s, and make config file available
|
||||
curl -sfL https://get.k3s.io | sh -
|
||||
sudo cp /etc/rancher/k3s/k3s.yaml /tmp/k3s.yaml
|
||||
sudo chmod +r /tmp/k3s.yaml
|
||||
|
||||
# Create necessary directories for local-storage from k3s nodes...
|
||||
sudo mkdir -p /tmp/gitea-storage
|
||||
sudo chmod 777 /tmp/gitea-storage
|
||||
|
||||
# ...and for certificates...
|
||||
sudo mkdir -p /tmp/gitea-certs
|
||||
sudo chmod 777 /tmp/gitea-certs
|
||||
|
||||
# ...and for the nginx configuration
|
||||
sudo mkdir -p /tmp/nginx
|
||||
sudo chmod 777 /tmp/nginx
|
||||
|
||||
exit
|
28
src/init/init.sh
Normal file
28
src/init/init.sh
Normal file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
metrics_user_exists() {
|
||||
[ $(drone -s "$DRONE_DOMAIN" -t "$PRIMARY_DRONE_USER_TOKEN" user ls 2>/dev/null | \
|
||||
grep -c '^build-metrics$') -ne 0 ]
|
||||
# `return` on its own will return the return code of the previous statement.
|
||||
# Bash is a very sensible and normal programming language
|
||||
return
|
||||
}
|
||||
|
||||
if metrics_user_exists; then
|
||||
echo "Drone Build Metrics user exists - exiting"
|
||||
exit 0
|
||||
else
|
||||
# I'm assuming that it needs to be admin in order to see and report on every build,
|
||||
# but if you wanted to get really finicky with permissions you could create different
|
||||
# metrics users with different permissions.
|
||||
drone -s "$DRONE_DOMAIN" -t "$PRIMARY_DRONE_USER_TOKEN" \
|
||||
user add --machine --admin --token "$METRICS_DRONE_USER_TOKEN" build-metrics 2>/dev/null
|
||||
# Double-check!
|
||||
if ! metrics_user_exists; then
|
||||
echo "Tried creating the user, but it still doesn't exist - something's gone wrong"
|
||||
echo "Drone Domain: $DRONE_DOMAIN"
|
||||
echo "Primary Drone User Token: $PRIMARY_DRONE_USER_TOKEN"
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
fi
|
0
src/main/__init__.py
Normal file
0
src/main/__init__.py
Normal file
@ -54,7 +54,11 @@ def get_repos(access_token: str, drone_domain: str) -> Iterable[Repo]:
|
||||
return repo_list
|
||||
|
||||
|
||||
def get_latest_build_status(access_token: str, drone_domain: str, owner: str, repo_name: str) -> BuildStatus:
|
||||
def get_latest_build_status(
|
||||
access_token: str,
|
||||
drone_domain: str,
|
||||
owner: str,
|
||||
repo_name: str) -> BuildStatus:
|
||||
builds = requests.get(f'{drone_domain}/api/repos/{owner}/{repo_name}/builds').json()
|
||||
if len(builds) == 0:
|
||||
return BuildStatus('unknown')
|
Loading…
x
Reference in New Issue
Block a user