diff --git a/README.md b/README.md index 31e7e0ca..57bc7f37 100644 --- a/README.md +++ b/README.md @@ -48,21 +48,18 @@ helm upgrade --install agent clemlesne-azure-pipelines-agent/azure-pipelines-age | `extraVolumes` | Additional volumes for the agent pod. | `[]` | | `fullnameOverride` | Overrides release fullname | `""` | | `image.pullPolicy` | Container image pull policy | `Always` if `image.tag` is `latest`, else `IfNotPresent` | -| `image.repository` | Container image repository | `clemlesne/azure-pipelines-agent` | -| `image.tag` | Container image tag | `""` (same version as the chart) | +| `image.repository` | Container image repository | `ghcr.io/clemlesne/azure-pipelines-agent:bullseye` | | `initContainers` | InitContainers for the agent pod. | `[]` | | `nameOverride` | Overrides release name | `""` | | `nodeSelector` | Node labels for pod assignment | `{}` | -| `pipelines.agent.mountDocker` | Enable to mount the host `docker.sock` | `false` | | `pipelines.agent.workDir` | The work directory the agent should use | `_work` | -| `pipelines.pat.secretRef` | The reference to the secret storing the Personal Access Token (PAT) used by the agent to connect. | `""` | -| `pipelines.pat.value` | Personal Access Token (PAT) used by the agent to connect. | `""` | +| `pipelines.pat` | Personal Access Token (PAT) used by the agent to connect. | `""` | | `pipelines.pool` | Agent pool to which the Agent should register. | `""` | | `pipelines.url` | The Azure base URL for your organization | `""` | | `resources` | Resource limits | `{}` | -| `serviceAccount.clusterAdmin` | Sets the service account as a cluster admin | _release name_ | | `serviceAccount.create` | Create ServiceAccount | `true` | | `serviceAccount.name` | ServiceAccount name | _release name_ | +| `tagSuffix` | Container image tag | `""` (same version as the chart) | | `tolerations` | Toleration labels for pod assignment | `[]` | ## Support diff --git a/src/docker/start.sh b/src/docker/start.sh index d67713ee..c6ad47b6 100644 --- a/src/docker/start.sh +++ b/src/docker/start.sh @@ -26,7 +26,7 @@ if [ -z "$AZP_TOKEN_FILE" ]; then fi AZP_TOKEN_FILE=/azp/.token - echo -n $AZP_TOKEN > "$AZP_TOKEN_FILE" + echo -n $AZP_TOKEN >"$AZP_TOKEN_FILE" fi unset AZP_TOKEN @@ -64,9 +64,9 @@ export VSO_AGENT_IGNORE=AZP_TOKEN,AZP_TOKEN_FILE print_header "1. Determining matching Azure Pipelines agent..." AZP_AGENT_PACKAGES=$(curl -LsS \ - -u user:$(cat "$AZP_TOKEN_FILE") \ - -H 'Accept:application/json;' \ - "$AZP_URL/_apis/distributedtask/packages/agent?platform=$TARGETARCH&top=1") + -u user:$(cat "$AZP_TOKEN_FILE") \ + -H 'Accept:application/json;' \ + "$AZP_URL/_apis/distributedtask/packages/agent?platform=$TARGETARCH&top=1") AZP_AGENT_PACKAGE_LATEST_URL=$(echo "$AZP_AGENT_PACKAGES" | jq -r '.value[0].downloadUrl') @@ -78,7 +78,8 @@ fi print_header "2. Downloading and extracting Azure Pipelines agent..." -curl -LsS $AZP_AGENT_PACKAGE_LATEST_URL | tar -xz & wait $! +curl -LsS $AZP_AGENT_PACKAGE_LATEST_URL | tar -xz & +wait $! source ./env.sh @@ -96,16 +97,22 @@ print_header "3. Configuring Azure Pipelines agent..." --pool "${AZP_POOL:-Default}" \ --work "${AZP_WORK:-_work}" \ --replace \ - --acceptTeeEula & wait $! + --acceptTeeEula & +wait $! print_header "4. Running Azure Pipelines agent..." -trap 'cleanup; exit 0' EXIT -trap 'cleanup; exit 130' INT -trap 'cleanup; exit 143' TERM +if ! grep -q "template" <<<"$AZP_AGENT_NAME"; then + echo "Cleanup Traps Enabled" + + trap 'cleanup; exit 0' EXIT + trap 'cleanup; exit 130' INT + trap 'cleanup; exit 143' TERM +fi -chmod +x ./run.sh +chmod +x ./run-docker.sh # To be aware of TERM and INT signals call run.sh # Running it with the --once flag at the end will shut down the agent after the build is executed -./run.sh "$@" & wait $! +./run-docker.sh "$@" --once & +wait $! diff --git a/src/helm/azure-pipelines-agent/templates/NOTES.txt b/src/helm/azure-pipelines-agent/templates/NOTES.txt index 8dfa114f..9d3db842 100644 --- a/src/helm/azure-pipelines-agent/templates/NOTES.txt +++ b/src/helm/azure-pipelines-agent/templates/NOTES.txt @@ -1,5 +1,5 @@ Check your Azure DevOps portal at to manage the Azure Pipelines Agent: -{{ .Values.pipelines.url | quote }}/_settings/agentpools +{{ .Values.pipelines.url }}/_settings/agentpools -Happy building! +Happy pipelines! 🙂 diff --git a/src/helm/azure-pipelines-agent/templates/_helpers.tpl b/src/helm/azure-pipelines-agent/templates/_helpers.tpl index 7808b280..bc207fec 100644 --- a/src/helm/azure-pipelines-agent/templates/_helpers.tpl +++ b/src/helm/azure-pipelines-agent/templates/_helpers.tpl @@ -60,40 +60,3 @@ Create the name of the service account to use {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} - -{{/* -Add volumes to the agent pod. -*/}} -{{- define "this.volumes" -}} -{{- if or .Values.pipelines.agent.mountDocker .Values.extraVolumes -}} -volumes: -{{- if .Values.extraVolumes }} -{{- with .Values.extraVolumes }} -{{ toYaml . }} -{{- end }} -{{- end }} -{{- if .Values.pipelines.agent.mountDocker }} -- name: dockersock - hostPath: - path: /var/run/docker.sock -{{- end }} -{{- end }} -{{- end }} - -{{/* -Add volume mounts to the agent container. -*/}} -{{- define "this.volumeMounts" -}} -{{- if or .Values.pipelines.agent.mountDocker .Values.extraVolumeMounts -}} -volumeMounts: -{{- if .Values.pipelines.agent.mountDocker }} -- name: dockersock - mountPath: /var/run/docker.sock -{{- end }} -{{- if .Values.extraVolumeMounts }} -{{- with .Values.extraVolumeMounts }} -{{ toYaml . }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} diff --git a/src/helm/azure-pipelines-agent/templates/clusterrolebinding.yaml b/src/helm/azure-pipelines-agent/templates/clusterrolebinding.yaml deleted file mode 100644 index 3f5d821f..00000000 --- a/src/helm/azure-pipelines-agent/templates/clusterrolebinding.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -{{- if .Values.serviceAccount.clusterAdmin -}} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ include "this.fullname" . }}-cluster-admin - labels: -{{ include "this.labels" . | indent 4 }} -roleRef: - kind: ClusterRole - name: cluster-admin - apiGroup: rbac.authorization.k8s.io -subjects: - - kind: ServiceAccount - name: {{ include "this.serviceAccountName" . }} - namespace: {{ .Release.Namespace }} -{{- end -}} -{{- end -}} diff --git a/src/helm/azure-pipelines-agent/templates/statefulset.yaml b/src/helm/azure-pipelines-agent/templates/deployment.yaml similarity index 53% rename from src/helm/azure-pipelines-agent/templates/statefulset.yaml rename to src/helm/azure-pipelines-agent/templates/deployment.yaml index 8da529a6..136fedac 100644 --- a/src/helm/azure-pipelines-agent/templates/statefulset.yaml +++ b/src/helm/azure-pipelines-agent/templates/deployment.yaml @@ -1,92 +1,70 @@ apiVersion: apps/v1 -kind: StatefulSet +kind: Deployment metadata: name: {{ include "this.fullname" . }} labels: {{- include "this.labels" . | nindent 4 }} spec: - podManagementPolicy: Parallel - replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "this.selectorLabels" . | nindent 6 }} - serviceName: {{ include "this.fullname" . }} template: metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} labels: {{- include "this.selectorLabels" . | nindent 8 }} + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "this.serviceAccountName" . }} - securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} - {{- with .Values.initContainers }} - initContainers: - {{- toYaml . | nindent 8 }} - {{- end }} containers: - name: {{ .Chart.Name }} - {{- if .Values.pipelines.agent.mountDocker }} - securityContext: - privileged: true - {{- if .Values.securityContext }} - {{- with .Values.securityContext }} - {{- toYaml . | nindent 12 }} - {{- end }} - {{- end }} - {{- else }} - {{- if .Values.securityContext }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - {{- end }} - {{- end }} image: "{{ .Values.image.repository }}-{{ .Values.image.tagSuffix | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: - name: AZP_AGENT_NAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.name + value: {{ include "this.fullname" . }} - name: AZP_URL - value: {{ .Values.pipelines.url | quote }} + valueFrom: + secretKeyRef: + name: {{ include "this.fullname" . }} + key: url - name: AZP_POOL value: {{ .Values.pipelines.pool | quote }} - name: AZP_WORK value: {{ .Values.pipelines.agent.workDir | quote }} - name: AZP_TOKEN - {{- if .Values.pipelines.pat.secretRef }} - {{- with .Values.pipelines.pat.secretRef }} valueFrom: secretKeyRef: - {{- toYaml . | nindent 18 }} - {{- end }} - {{- else }} - value: {{ .Values.pipelines.pat.value | quote }} - {{- end }} + name: {{ include "this.fullname" . }} + key: pat {{- with .Values.additionalEnv }} {{- toYaml . | nindent 12 }} {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} - {{- include "this.volumeMounts" . | nindent 10 -}} - {{- include "this.volumes" . | nindent 6 }} + {{- if .Values.extraVolumeMounts }} + volumeMounts: + {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.extraVolumes }} + volumes: + {{- toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.affinity }} + {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} + {{- end }} + {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} diff --git a/src/helm/azure-pipelines-agent/templates/hpa.yaml b/src/helm/azure-pipelines-agent/templates/hpa.yaml new file mode 100644 index 00000000..dbf25d2e --- /dev/null +++ b/src/helm/azure-pipelines-agent/templates/hpa.yaml @@ -0,0 +1,35 @@ +apiVersion: keda.sh/v1alpha1 +kind: TriggerAuthentication +metadata: + name: {{ include "this.fullname" . }} + labels: + {{- include "this.labels" . | nindent 4 }} +spec: + secretTargetRef: + - parameter: organizationURL + name: {{ include "this.fullname" . }} + key: url + - parameter: personalAccessToken + name: {{ include "this.fullname" . }} + key: pat +--- +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{ include "this.fullname" . }} + labels: + {{- include "this.labels" . | nindent 4 }} +spec: + scaleTargetRef: + name: {{ include "this.fullname" . }} + maxReplicaCount: {{ .Values.autoscaling.maxReplicas }} + minReplicaCount: {{ .Values.autoscaling.minReplicas }} + pollingInterval: 5 + cooldownPeriod: 60 + triggers: + - type: azure-pipelines + metadata: + poolName: {{ .Values.pipelines.pool }} + parent: {{ include "this.fullname" . }} + authenticationRef: + name: {{ include "this.fullname" . }} diff --git a/src/helm/azure-pipelines-agent/templates/secret.yaml b/src/helm/azure-pipelines-agent/templates/secret.yaml new file mode 100644 index 00000000..a1e49c02 --- /dev/null +++ b/src/helm/azure-pipelines-agent/templates/secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "this.fullname" . }} + labels: + {{- include "this.labels" . | nindent 4 }} +stringData: + pat: {{ .Values.pipelines.pat | quote }} + url: {{ .Values.pipelines.url | quote }} diff --git a/src/helm/azure-pipelines-agent/values.yaml b/src/helm/azure-pipelines-agent/values.yaml index c6bdddc7..c7a2e9d4 100644 --- a/src/helm/azure-pipelines-agent/values.yaml +++ b/src/helm/azure-pipelines-agent/values.yaml @@ -14,33 +14,21 @@ imagePullSecrets: [] nameOverride: "" fullnameOverride: "" -# Pat: Can be either a string or a reference to a secret. -# If it is a string, it is used as the value of the secret: -# -# value: "my-secret" -# -# If it is a reference to a secret: -# secretRef: -# name: my-secret -# key: my-key +autoscaling: + minReplicas: 1 + maxReplicas: 100 + pipelines: url: "" - pat: - value: "" - #secretRef: {} - pool: "Default" + pat: "" + pool: Default agent: name: "" - mountDocker: false - workDir: "_work" + workDir: _work serviceAccount: - # Specifies whether a service account should be created create: true - # Sets the agent as a cluster admin (useful if you want the agent to manage the cluster) - clusterAdmin: false - # The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template + # The name of the service account to use. If not set and create is true, a name is generated using the fullname template name: "" podSecurityContext: {} @@ -75,7 +63,7 @@ affinity: {} # Additional environment variables for the agent container. # Like: # - name: XXX -# value: "YYY" +# value: YYY # # or reference to a secret or configmap: # - name: SPECIAL_LEVEL_KEY