From 0da8675c44344a5c8e282801af2009feca56fb0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Tue, 2 Jun 2020 18:05:18 +0200 Subject: [PATCH 1/9] Make spinnaker able to deploy in kind --- .circleci/libs/install-and-run-spinnaker.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/libs/install-and-run-spinnaker.sh b/.circleci/libs/install-and-run-spinnaker.sh index d22373d..27c67ee 100755 --- a/.circleci/libs/install-and-run-spinnaker.sh +++ b/.circleci/libs/install-and-run-spinnaker.sh @@ -22,6 +22,10 @@ GATE_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '') hal -q config provider kubernetes enable CONTEXT=$(kubectl config current-context) hal -q config provider kubernetes account add my-k8s-v2-account --provider-version v2 --context $CONTEXT +## Configure account for inner kind communication +cp ~/.kube/config ~/.kube/kind +sed -i "s/server:\ .*/server:\ https:\/\/10.96.0.1:443/g" ~/.kube/kind +hal -q config provider kubernetes account add inner-kind --provider-version v2 --context kind-kind --kubeconfig-file ~/.kube/kind hal -q config deploy edit --type distributed --account-name my-k8s-v2-account ## Install minio From 3b9ce6bb58244371c734662e1159344b1b3adbd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Wed, 3 Jun 2020 12:30:17 +0200 Subject: [PATCH 2/9] Add triggering pipelines do circleci --- .circleci/config.yml | 10 ++++++ .circleci/libs/install-and-run-spinnaker.sh | 2 +- examples/resources/pipelines/deployNginx.json | 36 +++++++++++++++++++ .../resources/pipelines/deployNginx.jsonnet | 27 ++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 examples/resources/pipelines/deployNginx.json create mode 100644 examples/resources/pipelines/deployNginx.jsonnet diff --git a/.circleci/config.yml b/.circleci/config.yml index 98e150c..d459b49 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -203,6 +203,9 @@ jobs: floodgate_extra_params: type: string default: "" + pipelines_to_trigger: + type: string + default: "" machine: image: ubuntu-1604:202004-01 steps: @@ -252,6 +255,12 @@ jobs: /floodgate/bin/floodgate << parameters.floodgate_extra_params >> --config ~/floodgate.yaml sync echo "Compare changes - synced resources" /floodgate/bin/floodgate << parameters.floodgate_extra_params >> --config ~/floodgate.yaml compare + - run: + name: Trigger pipelines + command: | + for pipeline in << parameters.pipelines_to_trigger >> + do curl -X POST -H "content-type: application/json" -d "{ }" http://spinnaker/api/v1/webhooks/webhook/$pipeline + done workflows: periodic: @@ -337,5 +346,6 @@ workflows: - start_spinnaker: name: test floodgate with working spinnaker floodgate_extra_params: "-q" + pipelines_to_trigger: "deploy_nginx" requires: - build diff --git a/.circleci/libs/install-and-run-spinnaker.sh b/.circleci/libs/install-and-run-spinnaker.sh index 27c67ee..c708395 100755 --- a/.circleci/libs/install-and-run-spinnaker.sh +++ b/.circleci/libs/install-and-run-spinnaker.sh @@ -25,7 +25,7 @@ hal -q config provider kubernetes account add my-k8s-v2-account --provider-versi ## Configure account for inner kind communication cp ~/.kube/config ~/.kube/kind sed -i "s/server:\ .*/server:\ https:\/\/10.96.0.1:443/g" ~/.kube/kind -hal -q config provider kubernetes account add inner-kind --provider-version v2 --context kind-kind --kubeconfig-file ~/.kube/kind +hal -q config provider kubernetes account add inner-kind --provider-version v2 --context $CONTEXT --kubeconfig-file ~/.kube/kind hal -q config deploy edit --type distributed --account-name my-k8s-v2-account ## Install minio diff --git a/examples/resources/pipelines/deployNginx.json b/examples/resources/pipelines/deployNginx.json new file mode 100644 index 0000000..4a3730c --- /dev/null +++ b/examples/resources/pipelines/deployNginx.json @@ -0,0 +1,36 @@ +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "nginx-deployment" + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "nginx" + } + }, + "template": { + "metadata": { + "labels": { + "app": "nginx", + "lb": "nginx" + } + }, + "spec": { + "containers": [ + { + "name": "nginx", + "image": "nginx:latest", + "ports": [ + { + "containerPort": 80 + } + ] + } + ] + } + } + } +} diff --git a/examples/resources/pipelines/deployNginx.jsonnet b/examples/resources/pipelines/deployNginx.jsonnet new file mode 100644 index 0000000..b307a6d --- /dev/null +++ b/examples/resources/pipelines/deployNginx.jsonnet @@ -0,0 +1,27 @@ +local pipelines = import 'pipeline.libsonnet'; + +local deployment = import 'deploy.json'; + +local app = "jsonnetapp"; +local webhookTrigger(name, source) = pipelines.triggers + .webhook(name) + .withSource(source); + +local moniker = pipelines.moniker(app); + +local deployManifest (env, manifest = deployment) = pipelines.stages + .deployManifest('Deploy nginx to ' + env) + .withAccount('inner-kind') + .withManifests(manifest) + .withNamespaceOverride(env) + .withMoniker(moniker); + +local deployNginx = deployManifest('spinnaker'); +local triggerPipeline = webhookTrigger("deploy_nginx", "deploy_nginx"); + +pipelines.pipeline() +.withName('Test Deployment') +.withId('test_deployment') +.withApplication(app) +.withStages(deployNginx) +.withTriggers(triggerPipeline) From 3f2917425b973f0e3c0ede517d3d7beef095376f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Thu, 4 Jun 2020 11:00:37 +0200 Subject: [PATCH 3/9] Added API check if pipeline succeededwq --- .circleci/config.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d459b49..739b2ae 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -258,8 +258,33 @@ jobs: - run: name: Trigger pipelines command: | - for pipeline in << parameters.pipelines_to_trigger >> - do curl -X POST -H "content-type: application/json" -d "{ }" http://spinnaker/api/v1/webhooks/webhook/$pipeline + for PIPELINE in deploy_nginx ; do + EVENT_ID=`curl -s -X POST -H "content-type: application/json" -d "{ }" http://spinnaker/api/v1/webhooks/webhook/$PIPELINE | jq -r .eventId` + PASS=`cat ~/.hal/default/profiles/gate-local.yml | grep password` + PASS=${PASS#*:\ } + USER=`cat ~/.hal/default/profiles/gate-local.yml | grep name` + USER=${USER#*:\ } + ALL_APPS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications" | jq -r .[].name` + MAX_ATTEMPTS=10 + for APP in ALL_APPS ; do + PIPELINE_NAME=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].name` + ATTEMPTS=0 + until [ $ATTEMPTS -eq $MAX_ATTEMPTS ] ; do + STATUS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].status` + if [ -n $STATUS ] && [[ $STATUS != "SUCCEEDED" ]] ; then + echo "$PIPELINE_NAME exited with status $STATUS" + exit 1 + elif [ -n $STATUS ] && [[ $STATUS == "SUCCEEDED" ]] ; then + echo "$PIPELINE_NAME succeded" + break + else + echo "Waiting for pipeline to finish" + sleep 3 + fi + ((ATTEMPTS++)) + done + [ $ATTEMPTS -lt $MAX_ATTEMPTS ] + done done workflows: From 7f9f839bf56aa41402c6cd3a6916605283b4c0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Thu, 4 Jun 2020 11:26:03 +0200 Subject: [PATCH 4/9] Fixed condition for API query --- .circleci/config.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 739b2ae..1215a13 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -258,18 +258,18 @@ jobs: - run: name: Trigger pipelines command: | - for PIPELINE in deploy_nginx ; do + for PIPELINE in << parameters.pipelines_to_trigger >> ; do EVENT_ID=`curl -s -X POST -H "content-type: application/json" -d "{ }" http://spinnaker/api/v1/webhooks/webhook/$PIPELINE | jq -r .eventId` PASS=`cat ~/.hal/default/profiles/gate-local.yml | grep password` PASS=${PASS#*:\ } USER=`cat ~/.hal/default/profiles/gate-local.yml | grep name` USER=${USER#*:\ } ALL_APPS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications" | jq -r .[].name` - MAX_ATTEMPTS=10 + MAX_ATTEMPTS=20 for APP in ALL_APPS ; do PIPELINE_NAME=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].name` ATTEMPTS=0 - until [ $ATTEMPTS -eq $MAX_ATTEMPTS ] ; do + while [[ $PIPELINE_NAME != "" ]] && [ $ATTEMPTS -lt $MAX_ATTEMPTS ] ; do STATUS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].status` if [ -n $STATUS ] && [[ $STATUS != "SUCCEEDED" ]] ; then echo "$PIPELINE_NAME exited with status $STATUS" @@ -278,12 +278,11 @@ jobs: echo "$PIPELINE_NAME succeded" break else - echo "Waiting for pipeline to finish" + echo "Waiting for pipeline $PIPELINE_NAME to finish" sleep 3 fi ((ATTEMPTS++)) done - [ $ATTEMPTS -lt $MAX_ATTEMPTS ] done done From 33d816dd9c6c254183c5f3cba9eee997df29e4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Thu, 4 Jun 2020 11:32:11 +0200 Subject: [PATCH 5/9] Install jq --- .circleci/libs/install-and-run-spinnaker.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/libs/install-and-run-spinnaker.sh b/.circleci/libs/install-and-run-spinnaker.sh index c708395..ec52c01 100755 --- a/.circleci/libs/install-and-run-spinnaker.sh +++ b/.circleci/libs/install-and-run-spinnaker.sh @@ -3,6 +3,10 @@ EXEC_DIR=$(dirname "$0") HAL_VERSION=${HAL_VERSION:-1.35.0} +# Install packages +sudo apt update +sudo apt install -y jq + # Install Halyard curl -O https://raw.githubusercontent.com/spinnaker/halyard/master/install/debian/InstallHalyard.sh USERNAME=`whoami` From a98671e9e42b0ef46f58cc242e0d0f05cca04088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Thu, 4 Jun 2020 12:00:30 +0200 Subject: [PATCH 6/9] Usefull prints, handling of NOT_STARTED and RUNNING pipeline status --- .circleci/config.yml | 26 ++++++++++++++----- .../resources/pipelines/deployNginx.jsonnet | 2 +- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1215a13..db47918 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -259,30 +259,42 @@ jobs: name: Trigger pipelines command: | for PIPELINE in << parameters.pipelines_to_trigger >> ; do + echo "Triggering pipeline with source $PIPELINE" EVENT_ID=`curl -s -X POST -H "content-type: application/json" -d "{ }" http://spinnaker/api/v1/webhooks/webhook/$PIPELINE | jq -r .eventId` + echo "eventId: $EVENT_ID" PASS=`cat ~/.hal/default/profiles/gate-local.yml | grep password` PASS=${PASS#*:\ } USER=`cat ~/.hal/default/profiles/gate-local.yml | grep name` USER=${USER#*:\ } ALL_APPS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications" | jq -r .[].name` MAX_ATTEMPTS=20 - for APP in ALL_APPS ; do + for APP in $ALL_APPS ; do PIPELINE_NAME=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].name` ATTEMPTS=0 while [[ $PIPELINE_NAME != "" ]] && [ $ATTEMPTS -lt $MAX_ATTEMPTS ] ; do + echo "Checking pipeline $PIPELINE_NAME status" STATUS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].status` - if [ -n $STATUS ] && [[ $STATUS != "SUCCEEDED" ]] ; then - echo "$PIPELINE_NAME exited with status $STATUS" + if [ -n $STATUS ] && [[ $STATUS == "NOT_STARTED" ]] ; then + echo "Waiting for pipeline $PIPELINE_NAME to start" + sleep 3 + elif [ -n $STATUS ] && [[ $STATUS == "RUNNING" ]] ; then + echo "Waiting for pipeline $PIPELINE_NAME to finish" + sleep 3 + elif [ -n $STATUS ] && [[ $STATUS != "SUCCEEDED" ]] ; then + echo "Pipeline $PIPELINE_NAME exited with status $STATUS" exit 1 elif [ -n $STATUS ] && [[ $STATUS == "SUCCEEDED" ]] ; then - echo "$PIPELINE_NAME succeded" + echo "$Pipeline PIPELINE_NAME succeded" break else - echo "Waiting for pipeline $PIPELINE_NAME to finish" - sleep 3 + echo "Status of pipeline is: $STATUS" + exit 1 fi - ((ATTEMPTS++)) + ((++ATTEMPTS)) done + if [ $ATTEMPTS -lt $MAX_ATTEMPTS ] ; then + echo "Check timed out" + fi done done diff --git a/examples/resources/pipelines/deployNginx.jsonnet b/examples/resources/pipelines/deployNginx.jsonnet index b307a6d..08c0ad9 100644 --- a/examples/resources/pipelines/deployNginx.jsonnet +++ b/examples/resources/pipelines/deployNginx.jsonnet @@ -1,6 +1,6 @@ local pipelines = import 'pipeline.libsonnet'; -local deployment = import 'deploy.json'; +local deployment = import 'deployNginx.json'; local app = "jsonnetapp"; local webhookTrigger(name, source) = pipelines.triggers From a506957a827a6eb6a519c5a086f328453d8f63db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Fri, 5 Jun 2020 12:21:47 +0200 Subject: [PATCH 7/9] add error on timeout --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index db47918..3620750 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -292,8 +292,9 @@ jobs: fi ((++ATTEMPTS)) done - if [ $ATTEMPTS -lt $MAX_ATTEMPTS ] ; then + if [ $ATTEMPTS -ge $MAX_ATTEMPTS ] ; then echo "Check timed out" + exit 1 fi done done From be529bff5c1d9a4931e37de2515090baf9b9b710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Fri, 5 Jun 2020 12:50:45 +0200 Subject: [PATCH 8/9] 5 seconds sleep to let pipeline start --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3620750..69359d3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -262,6 +262,7 @@ jobs: echo "Triggering pipeline with source $PIPELINE" EVENT_ID=`curl -s -X POST -H "content-type: application/json" -d "{ }" http://spinnaker/api/v1/webhooks/webhook/$PIPELINE | jq -r .eventId` echo "eventId: $EVENT_ID" + sleep 5 # Let pipeline start PASS=`cat ~/.hal/default/profiles/gate-local.yml | grep password` PASS=${PASS#*:\ } USER=`cat ~/.hal/default/profiles/gate-local.yml | grep name` From 446f514ffc527874c993baae9f5aee11785eac02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Paradowski?= Date: Sat, 6 Jun 2020 12:08:11 +0200 Subject: [PATCH 9/9] Moved triggering pipelines to separate script --- .circleci/config.yml | 42 +---------------------- .circleci/libs/trigger-pipelines.sh | 53 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 41 deletions(-) create mode 100755 .circleci/libs/trigger-pipelines.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 69359d3..4d9016e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -258,47 +258,7 @@ jobs: - run: name: Trigger pipelines command: | - for PIPELINE in << parameters.pipelines_to_trigger >> ; do - echo "Triggering pipeline with source $PIPELINE" - EVENT_ID=`curl -s -X POST -H "content-type: application/json" -d "{ }" http://spinnaker/api/v1/webhooks/webhook/$PIPELINE | jq -r .eventId` - echo "eventId: $EVENT_ID" - sleep 5 # Let pipeline start - PASS=`cat ~/.hal/default/profiles/gate-local.yml | grep password` - PASS=${PASS#*:\ } - USER=`cat ~/.hal/default/profiles/gate-local.yml | grep name` - USER=${USER#*:\ } - ALL_APPS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications" | jq -r .[].name` - MAX_ATTEMPTS=20 - for APP in $ALL_APPS ; do - PIPELINE_NAME=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].name` - ATTEMPTS=0 - while [[ $PIPELINE_NAME != "" ]] && [ $ATTEMPTS -lt $MAX_ATTEMPTS ] ; do - echo "Checking pipeline $PIPELINE_NAME status" - STATUS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].status` - if [ -n $STATUS ] && [[ $STATUS == "NOT_STARTED" ]] ; then - echo "Waiting for pipeline $PIPELINE_NAME to start" - sleep 3 - elif [ -n $STATUS ] && [[ $STATUS == "RUNNING" ]] ; then - echo "Waiting for pipeline $PIPELINE_NAME to finish" - sleep 3 - elif [ -n $STATUS ] && [[ $STATUS != "SUCCEEDED" ]] ; then - echo "Pipeline $PIPELINE_NAME exited with status $STATUS" - exit 1 - elif [ -n $STATUS ] && [[ $STATUS == "SUCCEEDED" ]] ; then - echo "$Pipeline PIPELINE_NAME succeded" - break - else - echo "Status of pipeline is: $STATUS" - exit 1 - fi - ((++ATTEMPTS)) - done - if [ $ATTEMPTS -ge $MAX_ATTEMPTS ] ; then - echo "Check timed out" - exit 1 - fi - done - done + .circleci/libs/trigger-pipelines.sh << parameters.pipelines_to_trigger >> workflows: periodic: diff --git a/.circleci/libs/trigger-pipelines.sh b/.circleci/libs/trigger-pipelines.sh new file mode 100755 index 0000000..d7686ea --- /dev/null +++ b/.circleci/libs/trigger-pipelines.sh @@ -0,0 +1,53 @@ +#!/bin/bash -e +for PIPELINE in $@ ; do + + PASS=`cat ~/.hal/default/profiles/gate-local.yml | grep password` + PASS=${PASS#*:\ } + USER=`cat ~/.hal/default/profiles/gate-local.yml | grep name` + USER=${USER#*:\ } + ALL_APPS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications" | jq -r .[].name` + MAX_ATTEMPTS=20 + + echo "Triggering pipeline with source $PIPELINE" + EVENT_ID=`curl -s -X POST -H "content-type: application/json" -d "{ }" http://spinnaker/api/v1/webhooks/webhook/$PIPELINE | jq -r .eventId` + echo "eventId: $EVENT_ID" + + for APP in $ALL_APPS ; do + PIPELINE_NAME=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].name` + ATTEMPTS=0 + + while [[ $PIPELINE_NAME != "" ]] && [ $ATTEMPTS -lt $MAX_ATTEMPTS ] ; do + echo "Checking pipeline $PIPELINE_NAME status" + STATUS=`curl -s -X GET --user "$USER:$PASS" "http://spinnaker/api/v1/applications/$APP/executions/search?triggerTypes=webhook&eventId=$EVENT_ID" | jq -r .[].status` + + case $STATUS in + + "NOT_STARTED") + echo "Waiting for pipeline $PIPELINE_NAME to start" + sleep 3 + ;; + + "RUNNING") + echo "Waiting for pipeline $PIPELINE_NAME to finish" + sleep 3 + ;; + + "SUCCEEDED") + echo "$Pipeline PIPELINE_NAME succeded" + break + ;; + + *) + echo "Pipeline $PIPELINE_NAME exited with status $STATUS" + exit 1 + ;; + esac + ((++ATTEMPTS)) + done + + if [ $ATTEMPTS -ge $MAX_ATTEMPTS ] ; then + echo "Check timed out" + exit 1 + fi + done +done