debian-mirror-gitlab/scripts/review_apps/review-apps.sh

297 lines
10 KiB
Bash
Raw Normal View History

2018-12-05 23:21:45 +05:30
[[ "$TRACE" ]] && set -x
export TILLER_NAMESPACE="$KUBE_NAMESPACE"
2019-09-30 21:07:59 +05:30
function deploy_exists() {
2019-07-07 11:18:12 +05:30
local namespace="${1}"
local deploy="${2}"
echoinfo "Checking if ${deploy} exists in the ${namespace} namespace..." true
helm status --tiller-namespace "${namespace}" "${deploy}" >/dev/null 2>&1
local deploy_exists=$?
echoinfo "Deployment status for ${deploy} is ${deploy_exists}"
return $deploy_exists
}
2019-09-30 21:07:59 +05:30
function previous_deploy_failed() {
2019-07-07 11:18:12 +05:30
local deploy="${1}"
echoinfo "Checking for previous deployment of ${deploy}" true
2019-07-31 22:56:46 +05:30
helm status "${deploy}" >/dev/null 2>&1
2019-07-07 11:18:12 +05:30
local status=$?
# if `status` is `0`, deployment exists, has a status
if [ $status -eq 0 ]; then
echoinfo "Previous deployment found, checking status..."
2019-07-31 22:56:46 +05:30
deployment_status=$(helm status "${deploy}" | grep ^STATUS | cut -d' ' -f2)
2019-07-07 11:18:12 +05:30
echoinfo "Previous deployment state: ${deployment_status}"
if [[ "$deployment_status" == "FAILED" || "$deployment_status" == "PENDING_UPGRADE" || "$deployment_status" == "PENDING_INSTALL" ]]; then
status=0;
else
status=1;
fi
else
echoerr "Previous deployment NOT found."
fi
return $status
}
2019-12-04 20:38:33 +05:30
function delete_release() {
2019-07-07 11:18:12 +05:30
if [ -z "$CI_ENVIRONMENT_SLUG" ]; then
echoerr "No release given, aborting the delete!"
return
fi
local name="$CI_ENVIRONMENT_SLUG"
echoinfo "Deleting release '$name'..." true
2019-07-31 22:56:46 +05:30
helm delete --purge "$name"
2019-07-07 11:18:12 +05:30
}
2019-12-04 20:38:33 +05:30
function delete_failed_release() {
if [ -z "$CI_ENVIRONMENT_SLUG" ]; then
echoerr "No release given, aborting the delete!"
return
fi
if ! deploy_exists "${KUBE_NAMESPACE}" "${CI_ENVIRONMENT_SLUG}"; then
echoinfo "No Review App with ${CI_ENVIRONMENT_SLUG} is currently deployed."
else
# Cleanup and previous installs, as FAILED and PENDING_UPGRADE will cause errors with `upgrade`
if previous_deploy_failed "$CI_ENVIRONMENT_SLUG" ; then
echoinfo "Review App deployment in bad state, cleaning up $CI_ENVIRONMENT_SLUG"
delete_release
else
echoinfo "Review App deployment in good state"
fi
fi
}
2019-07-07 11:18:12 +05:30
function get_pod() {
local app_name="${1}"
local status="${2-Running}"
2019-10-12 21:52:04 +05:30
get_pod_cmd="kubectl get pods -n ${KUBE_NAMESPACE} --field-selector=status.phase=${status} -lapp=${app_name},release=${CI_ENVIRONMENT_SLUG} --no-headers -o=custom-columns=NAME:.metadata.name | tail -n 1"
2019-09-30 21:07:59 +05:30
echoinfo "Waiting till '${app_name}' pod is ready" true
echoinfo "Running '${get_pod_cmd}'"
2019-07-07 11:18:12 +05:30
2019-09-30 21:07:59 +05:30
local interval=5
local elapsed_seconds=0
local max_seconds=$((2 * 60))
2019-07-07 11:18:12 +05:30
while true; do
2019-07-31 22:56:46 +05:30
local pod_name
pod_name="$(eval "${get_pod_cmd}")"
2019-07-07 11:18:12 +05:30
[[ "${pod_name}" == "" ]] || break
2019-09-30 21:07:59 +05:30
if [[ "${elapsed_seconds}" -gt "${max_seconds}" ]]; then
echoerr "The pod name couldn't be found after ${elapsed_seconds} seconds, aborting."
break
fi
let "elapsed_seconds+=interval"
sleep ${interval}
2019-07-07 11:18:12 +05:30
done
echoinfo "The pod name is '${pod_name}'."
echo "${pod_name}"
}
2018-12-05 23:21:45 +05:30
function check_kube_domain() {
2019-07-07 11:18:12 +05:30
echoinfo "Checking that Kube domain exists..." true
2018-12-05 23:21:45 +05:30
if [ -z ${REVIEW_APPS_DOMAIN+x} ]; then
echo "In order to deploy or use Review Apps, REVIEW_APPS_DOMAIN variable must be set"
echo "You can do it in Auto DevOps project settings or defining a variable at group or project level"
echo "You can also manually add it in .gitlab-ci.yml"
false
else
true
fi
}
2019-05-30 16:15:17 +05:30
function ensure_namespace() {
2019-07-07 11:18:12 +05:30
echoinfo "Ensuring the ${KUBE_NAMESPACE} namespace exists..." true
2018-12-05 23:21:45 +05:30
kubectl describe namespace "$KUBE_NAMESPACE" || kubectl create namespace "$KUBE_NAMESPACE"
}
function install_tiller() {
2019-07-07 11:18:12 +05:30
echoinfo "Checking deployment/tiller-deploy status in the ${TILLER_NAMESPACE} namespace..." true
echoinfo "Initiating the Helm client..."
helm init --client-only
2019-09-30 21:07:59 +05:30
# Set toleration for Tiller to be installed on a specific node pool
2019-03-02 22:35:43 +05:30
helm init \
2019-09-30 21:07:59 +05:30
--wait \
2019-03-02 22:35:43 +05:30
--upgrade \
2019-09-30 21:07:59 +05:30
--node-selectors "app=helm" \
--replicas 3 \
--override "spec.template.spec.tolerations[0].key"="dedicated" \
--override "spec.template.spec.tolerations[0].operator"="Equal" \
--override "spec.template.spec.tolerations[0].value"="helm" \
--override "spec.template.spec.tolerations[0].effect"="NoSchedule"
2019-07-07 11:18:12 +05:30
2018-12-05 23:21:45 +05:30
kubectl rollout status -n "$TILLER_NAMESPACE" -w "deployment/tiller-deploy"
2019-07-07 11:18:12 +05:30
2018-12-05 23:21:45 +05:30
if ! helm version --debug; then
echo "Failed to init Tiller."
return 1
fi
2019-07-07 11:18:12 +05:30
}
function install_external_dns() {
local release_name="dns-gitlab-review-app"
2019-07-31 22:56:46 +05:30
local domain
domain=$(echo "${REVIEW_APPS_DOMAIN}" | awk -F. '{printf "%s.%s", $(NF-1), $NF}')
2019-07-07 11:18:12 +05:30
echoinfo "Installing external DNS for domain ${domain}..." true
2019-09-30 21:07:59 +05:30
if ! deploy_exists "${KUBE_NAMESPACE}" "${release_name}" || previous_deploy_failed "${release_name}" ; then
2019-07-07 11:18:12 +05:30
echoinfo "Installing external-dns Helm chart"
helm repo update
2019-09-30 21:07:59 +05:30
# Default requested: CPU => 0, memory => 0
helm install stable/external-dns --version '^2.2.1' \
2019-07-07 11:18:12 +05:30
-n "${release_name}" \
--namespace "${KUBE_NAMESPACE}" \
--set provider="aws" \
2019-09-30 21:07:59 +05:30
--set aws.credentials.secretKey="${REVIEW_APPS_AWS_SECRET_KEY}" \
--set aws.credentials.accessKey="${REVIEW_APPS_AWS_ACCESS_KEY}" \
2019-07-07 11:18:12 +05:30
--set aws.zoneType="public" \
2019-09-30 21:07:59 +05:30
--set aws.batchChangeSize=400 \
2019-07-07 11:18:12 +05:30
--set domainFilters[0]="${domain}" \
--set txtOwnerId="${KUBE_NAMESPACE}" \
--set rbac.create="true" \
2019-09-30 21:07:59 +05:30
--set policy="sync" \
--set resources.requests.cpu=50m \
--set resources.limits.cpu=100m \
--set resources.requests.memory=100M \
--set resources.limits.memory=200M
2019-07-07 11:18:12 +05:30
else
echoinfo "The external-dns Helm chart is already successfully deployed."
fi
2018-12-05 23:21:45 +05:30
}
2019-09-30 21:07:59 +05:30
function create_application_secret() {
2019-07-07 11:18:12 +05:30
echoinfo "Creating the ${CI_ENVIRONMENT_SLUG}-gitlab-initial-root-password secret in the ${KUBE_NAMESPACE} namespace..." true
2018-12-05 23:21:45 +05:30
kubectl create secret generic -n "$KUBE_NAMESPACE" \
2019-07-31 22:56:46 +05:30
"${CI_ENVIRONMENT_SLUG}-gitlab-initial-root-password" \
--from-literal="password=${REVIEW_APPS_ROOT_PASSWORD}" \
2018-12-05 23:21:45 +05:30
--dry-run -o json | kubectl apply -f -
}
2019-09-30 21:07:59 +05:30
function download_chart() {
2019-07-07 11:18:12 +05:30
echoinfo "Downloading the GitLab chart..." true
2019-05-18 00:54:41 +05:30
2019-12-04 20:38:33 +05:30
curl --location -o gitlab.tar.bz2 "https://gitlab.com/gitlab-org/charts/gitlab/-/archive/${GITLAB_HELM_CHART_REF}/gitlab-${GITLAB_HELM_CHART_REF}.tar.bz2"
2019-07-07 11:18:12 +05:30
tar -xjf gitlab.tar.bz2
2019-07-31 22:56:46 +05:30
cd "gitlab-${GITLAB_HELM_CHART_REF}"
2019-07-07 11:18:12 +05:30
echoinfo "Adding the gitlab repo to Helm..."
helm repo add gitlab https://charts.gitlab.io
echoinfo "Building the gitlab chart's dependencies..."
helm dependency build .
2018-12-05 23:21:45 +05:30
}
function deploy() {
2019-07-07 11:18:12 +05:30
local name="$CI_ENVIRONMENT_SLUG"
2019-12-04 20:38:33 +05:30
local edition="${GITLAB_EDITION-ce}"
2019-07-07 11:18:12 +05:30
echoinfo "Deploying ${name}..." true
2018-12-05 23:21:45 +05:30
2019-02-15 15:39:39 +05:30
IMAGE_REPOSITORY="registry.gitlab.com/gitlab-org/build/cng-mirror"
2019-12-04 20:38:33 +05:30
gitlab_migrations_image_repository="${IMAGE_REPOSITORY}/gitlab-rails-${edition}"
gitlab_sidekiq_image_repository="${IMAGE_REPOSITORY}/gitlab-sidekiq-${edition}"
gitlab_unicorn_image_repository="${IMAGE_REPOSITORY}/gitlab-unicorn-${edition}"
gitlab_task_runner_image_repository="${IMAGE_REPOSITORY}/gitlab-task-runner-${edition}"
2019-02-15 15:39:39 +05:30
gitlab_gitaly_image_repository="${IMAGE_REPOSITORY}/gitaly"
gitlab_shell_image_repository="${IMAGE_REPOSITORY}/gitlab-shell"
2019-12-04 20:38:33 +05:30
gitlab_workhorse_image_repository="${IMAGE_REPOSITORY}/gitlab-workhorse-${edition}"
2018-12-05 23:21:45 +05:30
2019-09-30 21:07:59 +05:30
create_application_secret
2018-12-05 23:21:45 +05:30
HELM_CMD=$(cat << EOF
helm upgrade --install \
2019-12-04 20:38:33 +05:30
--wait \
2019-10-12 21:52:04 +05:30
--timeout 900 \
2019-12-04 20:38:33 +05:30
--set ci.branch="$CI_COMMIT_REF_NAME" \
--set ci.commit.sha="$CI_COMMIT_SHORT_SHA" \
--set ci.job.url="$CI_JOB_URL" \
--set ci.pipeline.url="$CI_PIPELINE_URL" \
2018-12-05 23:21:45 +05:30
--set releaseOverride="$CI_ENVIRONMENT_SLUG" \
--set global.hosts.hostSuffix="$HOST_SUFFIX" \
--set global.hosts.domain="$REVIEW_APPS_DOMAIN" \
--set gitlab.migrations.image.repository="$gitlab_migrations_image_repository" \
2019-02-15 15:39:39 +05:30
--set gitlab.migrations.image.tag="$CI_COMMIT_REF_SLUG" \
2019-07-31 22:56:46 +05:30
--set gitlab.gitaly.image.repository="$gitlab_gitaly_image_repository" \
2018-12-05 23:21:45 +05:30
--set gitlab.gitaly.image.tag="v$GITALY_VERSION" \
2019-07-31 22:56:46 +05:30
--set gitlab.gitlab-shell.image.repository="$gitlab_shell_image_repository" \
2018-12-05 23:21:45 +05:30
--set gitlab.gitlab-shell.image.tag="v$GITLAB_SHELL_VERSION" \
2019-09-30 21:07:59 +05:30
--set gitlab.sidekiq.image.repository="$gitlab_sidekiq_image_repository" \
--set gitlab.sidekiq.image.tag="$CI_COMMIT_REF_SLUG" \
--set gitlab.unicorn.image.repository="$gitlab_unicorn_image_repository" \
--set gitlab.unicorn.image.tag="$CI_COMMIT_REF_SLUG" \
2018-12-05 23:21:45 +05:30
--set gitlab.unicorn.workhorse.image="$gitlab_workhorse_image_repository" \
2019-02-15 15:39:39 +05:30
--set gitlab.unicorn.workhorse.tag="$CI_COMMIT_REF_SLUG" \
2019-09-30 21:07:59 +05:30
--set gitlab.task-runner.image.repository="$gitlab_task_runner_image_repository" \
--set gitlab.task-runner.image.tag="$CI_COMMIT_REF_SLUG"
EOF
)
HELM_CMD=$(cat << EOF
$HELM_CMD \
--namespace="$KUBE_NAMESPACE" \
--version="$CI_PIPELINE_ID-$CI_JOB_ID" \
2019-12-04 20:38:33 +05:30
-f "../scripts/review_apps/base-config.yaml" \
2019-09-30 21:07:59 +05:30
"$name" .
2018-12-05 23:21:45 +05:30
EOF
)
2019-07-07 11:18:12 +05:30
echoinfo "Deploying with:"
echoinfo "${HELM_CMD}"
2018-12-05 23:21:45 +05:30
2019-09-30 21:07:59 +05:30
eval "${HELM_CMD}"
}
function display_deployment_debug() {
2019-12-21 20:55:43 +05:30
# Get all pods for this release
echoinfo "Pods for release ${CI_ENVIRONMENT_SLUG}"
2019-12-04 20:38:33 +05:30
kubectl get pods -n "$KUBE_NAMESPACE" -lrelease=${CI_ENVIRONMENT_SLUG}
2019-12-21 20:55:43 +05:30
# Get all non-completed jobs
echoinfo "Unsuccessful Jobs for release ${CI_ENVIRONMENT_SLUG}"
kubectl get jobs -n "$KUBE_NAMESPACE" -lrelease=${CI_ENVIRONMENT_SLUG} --field-selector=status.successful!=1
2019-07-31 22:56:46 +05:30
}
2019-02-15 15:39:39 +05:30
function add_license() {
if [ -z "${REVIEW_APPS_EE_LICENSE}" ]; then echo "License not found" && return; fi
task_runner_pod=$(get_pod "task-runner");
if [ -z "${task_runner_pod}" ]; then echo "Task runner pod not found" && return; fi
2019-07-07 11:18:12 +05:30
echoinfo "Installing license..." true
2019-02-15 15:39:39 +05:30
echo "${REVIEW_APPS_EE_LICENSE}" > /tmp/license.gitlab
2019-07-31 22:56:46 +05:30
kubectl -n "$KUBE_NAMESPACE" cp /tmp/license.gitlab "${task_runner_pod}":/tmp/license.gitlab
2019-02-15 15:39:39 +05:30
rm /tmp/license.gitlab
2019-07-31 22:56:46 +05:30
kubectl -n "$KUBE_NAMESPACE" exec -it "${task_runner_pod}" -- /srv/gitlab/bin/rails runner -e production \
2019-02-15 15:39:39 +05:30
'
content = File.read("/tmp/license.gitlab").strip;
FileUtils.rm_f("/tmp/license.gitlab");
unless License.where(data:content).empty?
puts "License already exists";
Kernel.exit 0;
end
unless License.new(data: content).save
puts "Could not add license";
Kernel.exit 0;
end
puts "License added";
'
}