
This 'jarvis-merge' pipeline reruns validation of a submittable patchset and upon success, will submit the patchset, integrating it to the main branch. It will also promote a repository's artifacts from their respective -staging areas to their non-staging counterparts. Change-Id: I2e46d95543c6a835f7c17c1097a7ea84b1092f4d
259 lines
12 KiB
YAML
259 lines
12 KiB
YAML
{{- define "Task-createProjectAccess" -}}
|
|
---
|
|
apiVersion: tekton.dev/v1beta1
|
|
kind: Task
|
|
metadata:
|
|
name: {{ template "helpers.labels.fullname" . }}-createprojectaccess
|
|
spec:
|
|
params:
|
|
- name: repoRoot
|
|
- name: project
|
|
- name: changeNumber
|
|
- name: patchSetNumber
|
|
- name: pipeline
|
|
workspaces:
|
|
- name: output
|
|
description: The git repo will be cloned onto the volume backing this workspace
|
|
results:
|
|
- name: commit
|
|
description: The precise commit SHA that was fetched by this Task
|
|
- name: namespace
|
|
description: The namespace created for this pipelinerun
|
|
steps:
|
|
- name: create-namespace
|
|
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_create_namespace" ) }}
|
|
script: |
|
|
#!/bin/bash
|
|
set -ex
|
|
create_namespace() {
|
|
if ! [[ $(kubectl get ns jarvis-$(params.changeNumber)-$(params.patchSetNumber)) ]] ; then
|
|
kubectl create ns jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
echo "Created namespace jarvis-$(params.changeNumber)-$(params.patchSetNumber)"
|
|
else
|
|
echo "Namespace already exists, delete all resources for re-run."
|
|
kubectl delete pr -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) --all
|
|
helm delete development-pipeline -n jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
kubectl delete role -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) --all
|
|
kubectl delete secret -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) --all
|
|
kubectl delete sa -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) --all
|
|
kubectl delete rolebinding -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) --all
|
|
fi
|
|
}
|
|
create_namespace
|
|
- name: create-k8s-objects
|
|
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_create_namespace" ) }}
|
|
script: |
|
|
#!/bin/bash
|
|
create_sa() {
|
|
if ! [[ $(kubectl get serviceaccount -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) sa-development-pipeline) ]] ; then
|
|
tee $(workspaces.output.path)/service-account.yaml <<EOF
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: sa-development-pipeline
|
|
namespace: jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
EOF
|
|
else
|
|
echo "Service Account already exists"
|
|
exit
|
|
fi
|
|
}
|
|
create_role() {
|
|
if ! [[ $(kubectl get role -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) jarvis-$(params.changeNumber)-$(params.patchSetNumber)) ]] ; then
|
|
tee $(workspaces.output.path)/role.yaml <<EOF
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: Role
|
|
metadata:
|
|
name: jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
namespace: jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
rules:
|
|
# EventListeners need to be able to fetch all namespaced resources
|
|
- apiGroups: ["triggers.tekton.dev"]
|
|
resources: ["eventlisteners", "triggerbindings", "triggertemplates", "triggers"]
|
|
verbs: ["get", "list", "watch"]
|
|
- apiGroups: [""]
|
|
resources: ["configmaps"]
|
|
verbs: ["get", "list", "watch"]
|
|
# Permissions to execute helm dry-run TODO restrict to specific namespace
|
|
- apiGroups: [""]
|
|
resources: ["secrets", "services"]
|
|
verbs: ["get"]
|
|
- apiGroups: ["apps"]
|
|
resources: ["deployments"]
|
|
verbs: ["get"]
|
|
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
resources: ["roles", "rolebindings"]
|
|
verbs: ["get"]
|
|
EOF
|
|
else
|
|
echo "Role already exists"
|
|
exit
|
|
fi
|
|
}
|
|
create_rolebinding() {
|
|
if ! [[ $(kubectl get rolebinding -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) jarvis-$(params.changeNumber)-$(params.patchSetNumber)) ]] ; then
|
|
tee $(workspaces.output.path)/rolebinding.yaml <<EOF
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: RoleBinding
|
|
metadata:
|
|
name: jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
namespace: jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: sa-development-pipeline
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: Role
|
|
name: jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
EOF
|
|
else
|
|
echo "rolebinding already exists"
|
|
exit
|
|
fi
|
|
}
|
|
#Service account creation
|
|
create_sa
|
|
create_role
|
|
create_rolebinding
|
|
|
|
cat $(workspaces.output.path)/service-account.yaml | kubectl apply -f -
|
|
cat $(workspaces.output.path)/role.yaml | kubectl apply -f -
|
|
cat $(workspaces.output.path)/rolebinding.yaml | kubectl apply -f -
|
|
|
|
- name: checkout-repo
|
|
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_git" ) }}
|
|
script: |
|
|
#!/bin/sh
|
|
set -eu -o pipefail -x
|
|
|
|
# A change ref has the format refs/changes/X/Y/Z where X is
|
|
# the last two digits of the change number, Y is the entire
|
|
# change number, and Z is the patch set. For example, if
|
|
# the change number is 263270, the ref would be
|
|
# refs/changes/70/263270/2 for the second patch set.
|
|
change_ref="refs/changes/$(echo "0$(params.changeNumber)" | awk '{ print substr( $0, length($0) - 1, length($0) ) }')/$(params.changeNumber)/$(params.patchSetNumber)"
|
|
echo $change_ref
|
|
|
|
|
|
CHECKOUT_DIR="$(workspaces.output.path)"
|
|
|
|
cleandir() {
|
|
# Delete any existing contents of the repo directory if it exists.
|
|
#
|
|
# We don't just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/"
|
|
# or the root of a mounted volume.
|
|
if [[ -d "$CHECKOUT_DIR" ]] ; then
|
|
# Delete non-hidden files and directories
|
|
rm -rf "$CHECKOUT_DIR"/*
|
|
# Delete files and directories starting with . but excluding ..
|
|
rm -rf "$CHECKOUT_DIR"/.[!.]*
|
|
# Delete files and directories starting with .. plus any other character
|
|
rm -rf "$CHECKOUT_DIR"/..?*
|
|
fi
|
|
}
|
|
cleandir
|
|
|
|
cd ${CHECKOUT_DIR}
|
|
git init
|
|
git config http.sslVerify "false"
|
|
git config advice.detachedHead "false"
|
|
git fetch $(params.repoRoot)/$(params.project) $change_ref
|
|
git checkout FETCH_HEAD
|
|
|
|
RESULT_SHA="$(git rev-parse HEAD)"
|
|
EXIT_CODE="$?"
|
|
if [ "$EXIT_CODE" != 0 ] ; then
|
|
exit $EXIT_CODE
|
|
fi
|
|
|
|
echo -n "$RESULT_SHA" > $(results.commit.path)
|
|
- name: create-secrets
|
|
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_secrets" ) }}
|
|
script: |
|
|
#!/bin/bash
|
|
## Creating kubeconfig secret in correct namespace
|
|
SECRET_JSON_ORIGINAL=$(mktemp --suffix=".json")
|
|
kubectl get secret -n development-pipeline kubeconfig-secret -o=json > "$SECRET_JSON_ORIGINAL"
|
|
SECRET_JSON=$(mktemp --suffix=".json")
|
|
jq 'del(.metadata.namespace) | del(.metadata.creationTimestamp) | del(.metadata.labels."controller-uid") | del(.metadata.resourceVersion) | del(.metadata.selfLink) | del(.metadata.uid) | del(.spec.selector) | del(.spec.template.metadata.creationTimestamp) | del(.spec.template.metadata.labels."controller-uid" )' "$SECRET_JSON_ORIGINAL" > "$SECRET_JSON"
|
|
|
|
cat "$SECRET_JSON" | kubectl create -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) -f -
|
|
|
|
## Creating Harbor certificate in correct namespace
|
|
SECRET_JSON_ORIGINAL=$(mktemp --suffix=".json")
|
|
kubectl get secret -n development-pipeline harbor-ca -o=json > "$SECRET_JSON_ORIGINAL"
|
|
SECRET_JSON=$(mktemp --suffix=".json")
|
|
jq 'del(.metadata.namespace) | del(.metadata.creationTimestamp) | del(.metadata.labels."controller-uid") | del(.metadata.resourceVersion) | del(.metadata.selfLink) | del(.metadata.uid) | del(.spec.selector) | del(.spec.template.metadata.creationTimestamp) | del(.spec.template.metadata.labels."controller-uid" )' "$SECRET_JSON_ORIGINAL" > "$SECRET_JSON"
|
|
|
|
cat "$SECRET_JSON" | kubectl create -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) -f -
|
|
|
|
rm "$SECRET_JSON_ORIGINAL"
|
|
rm "$SECRET_JSON"
|
|
|
|
## Harbor basic auth and docker auth
|
|
kubectl create secret generic harbor-basic-auth \
|
|
--from-literal=username='admin' \
|
|
--from-literal=password='Harbor12345' \
|
|
-n jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
|
|
kubectl create secret docker-registry harbor-docker-auth \
|
|
--docker-username=admin \
|
|
--docker-password=Harbor12345 \
|
|
--docker-email=example@gmail.com \
|
|
--docker-server=harbor-core.jarvis.local \
|
|
-n jarvis-$(params.changeNumber)-$(params.patchSetNumber)
|
|
- name: install-development-pipeline
|
|
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_secrets" ) }}
|
|
script: |
|
|
#!/bin/bash
|
|
|
|
change_ref="refs/changes/$(echo "0$(params.changeNumber)" | awk '{ print substr( $0, length($0) - 1, length($0) ) }')/$(params.changeNumber)/$(params.patchSetNumber)"
|
|
echo $change_ref
|
|
|
|
cd "$(workspaces.output.path)"/jarvis
|
|
|
|
# escape commas in no_proxy because Helm tries to split the value on commas
|
|
helm upgrade --install development-pipeline \
|
|
-n jarvis-$(params.changeNumber)-$(params.patchSetNumber) \
|
|
./development-pipeline \
|
|
--set proxy.http_proxy="{{ .Values.proxy.http_proxy }}" \
|
|
--set proxy.https_proxy="{{ .Values.proxy.https_proxy }}" \
|
|
--set proxy.no_proxy="$(echo {{ .Values.proxy.no_proxy }} | sed "s/,/\\\,/g")" \
|
|
--set proxy.internal_certs_dir="{{ .Values.proxy.internal_certs_dir }}" \
|
|
--set "git_repo=$(params.repoRoot)/$(params.project)" \
|
|
--set "refspec=$change_ref" \
|
|
--set "namespace=jarvis-$(params.changeNumber)-$(params.patchSetNumber)"
|
|
|
|
echo -n "jarvis-$(params.changeNumber)-$(params.patchSetNumber)" > $(results.namespace.path)
|
|
- name: create-pipelinerun
|
|
image: {{ include "helpers.pod.container.image" ( dict "Global" $ "Application" "task_secrets" ) }}
|
|
script: |
|
|
#!/bin/bash
|
|
|
|
kubectl create \
|
|
-n jarvis-$(params.changeNumber)-$(params.patchSetNumber) \
|
|
-f "$(workspaces.output.path)"/jarvis/development-pipeline/pipelinerun-$(params.pipeline).yaml
|
|
# Default wait timeout is 1000 seconds
|
|
end=$(date +%s)
|
|
timeout=${3:-3000}
|
|
end=$((end + timeout))
|
|
|
|
while true; do
|
|
pipelinerunstatus="$(kubectl get pipelinerun -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) $(kubectl get pipelinerun -n jarvis-$(params.changeNumber)-$(params.patchSetNumber) -o name | awk -F '/' "/development-pipeline/ { print \$NF; exit }") | tail -1 | awk '{ print $2 }')"
|
|
[ "${pipelinerunstatus}" == "True" ] && break
|
|
[ "${pipelinerunstatus}" == "False" ] && exit 1
|
|
sleep 5
|
|
now=$(date +%s)
|
|
if [ $now -gt $end ] ; then
|
|
echo "Pipelinerun failed to complete after $timeout seconds"
|
|
echo
|
|
kubectl get pipelinerun --namespace jarvis-$(params.changeNumber)-$(params.patchSetNumber) -o wide
|
|
echo "Some pipelineruns are not complete"
|
|
exit 1
|
|
fi
|
|
echo "kubectl get pipelinerun -n jarvis-$(params.changeNumber)-$(params.patchSetNumber)" | grep development-pipeline
|
|
done
|
|
...
|
|
{{- end -}}
|
|
{{- include "helpers.template.overlay" ( dict "Global" $ "template_definition" "Task-createProjectAccess" ) }}
|