config.yml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. version: 2.1
  2. jobs:
  3. build:
  4. docker:
  5. # Custom image; see tools/build/Dockerfile
  6. - image: gcr.io/neo4j-helm/build:latest
  7. environment:
  8. PROJECT: neo4j-helm
  9. CLUSTER: ci-test
  10. ZONE: us-central1-a
  11. NODES: 3
  12. NAME_CLUSTERED: testrunc
  13. NAME_STANDALONE: testrunsa
  14. NAME_RESTORE: testrevive
  15. BUILD_ARTIFACTS: build
  16. SERVICE_KEY_FILE: /tmp/service-key.json
  17. BUCKET: gs://circleci-build-system
  18. AZURE_CONTAINER_NAME: circleci-build-system
  19. steps:
  20. - checkout
  21. - setup_remote_docker
  22. - run:
  23. name: Tooling pre-requisites
  24. command: |
  25. # We will install local tools so add those to path.
  26. echo "export PATH=./tools:.:$PATH" >> $BASH_ENV
  27. mkdir -p $BUILD_ARTIFACTS
  28. mkdir -p tools
  29. - restore_cache:
  30. name: Restore NPM Package Cache
  31. keys:
  32. - npm-packages-{{ checksum "doc/package.json" }}
  33. - run:
  34. name: Setup GCP Tooling
  35. command: |
  36. echo $GCLOUD_SERVICE_KEY > $SERVICE_KEY_FILE
  37. gcloud auth activate-service-account \
  38. $GCLOUD_SERVICE_ACCOUNT \
  39. --key-file=$SERVICE_KEY_FILE
  40. gcloud auth configure-docker --quiet
  41. - run:
  42. name: Setup Azure Tooling
  43. command: |
  44. # az command is built into the testing container.
  45. az login --service-principal --username "$SP_ID" --password "$SP_PASSWORD" --tenant "$TENANT_ID"
  46. - run:
  47. name: Generate Docs
  48. command: |
  49. cd doc
  50. npm install
  51. echo "Generating docs"
  52. ./node_modules/.bin/antora --stacktrace docs.yml
  53. - save_cache:
  54. name: Save Yarn Package Cache
  55. key: npm-packages-{{ checksum "doc/package.json" }}
  56. paths:
  57. - ~/.cache/npm
  58. - run:
  59. name: Lint
  60. command: helm lint .
  61. - run:
  62. name: GKE Setup / Auth
  63. command: |
  64. echo "GKE SETUP"
  65. export CLUSTER_NAME=$CLUSTER-$CIRCLE_BUILD_NUM
  66. ./tools/test/provision-k8s.sh $CLUSTER_NAME
  67. - run:
  68. name: Create test namespace
  69. command: |
  70. cat \<<EOF | kubectl apply -f -
  71. apiVersion: v1
  72. kind: Namespace
  73. metadata:
  74. name: ns-$CIRCLE_BUILD_NUM
  75. EOF
  76. - run:
  77. name: Install secrets for maintenance ops and testing
  78. command: |
  79. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  80. kubectl create secret generic neo4j-service-key \
  81. --namespace $NAMESPACE \
  82. --from-file=credentials=$SERVICE_KEY_FILE
  83. # This secret is injected in the test process to demonstrate that
  84. # config works. This is just any valid config we can check inside of
  85. # a running system.
  86. kubectl create secret generic my-secret-config \
  87. --namespace $NAMESPACE \
  88. --from-literal=NEO4J_dbms_transaction_concurrent_maximum=100
  89. echo "export ACCOUNT_NAME=$ACCOUNT_NAME" >> azure-credentials.sh
  90. echo "export ACCOUNT_KEY=$ACCOUNT_KEY" >> azure-credentials.sh
  91. kubectl create secret generic azure-credentials \
  92. --namespace $NAMESPACE \
  93. --from-file=credentials=azure-credentials.sh
  94. - run:
  95. name: Package and Install Neo4j-Helm Chart
  96. command: |
  97. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  98. helm package .
  99. chart_archive=$(ls neo4j*.tgz)
  100. cp *.tgz $BUILD_ARTIFACTS/
  101. echo "Installing $chart_archive (CAUSAL CLUSTER TEST SCENARIO)"
  102. helm install $NAME_CLUSTERED -f deployment-scenarios/ci/cluster.yaml $chart_archive \
  103. --namespace $NAMESPACE \
  104. -v 3 | tee -a $BUILD_ARTIFACTS/INSTALL-cluster.txt
  105. echo "Installing $chart_archive (STANDALONE SCENARIO)"
  106. helm install $NAME_STANDALONE -f deployment-scenarios/ci/standalone.yaml $chart_archive \
  107. --namespace $NAMESPACE \
  108. -v 3 | tee -a $BUILD_ARTIFACTS/INSTALL-standalone.txt
  109. echo "Installing $chart_archive (AZURE RESTORE SCENARIO)"
  110. helm install $NAME_RESTORE -f deployment-scenarios/ci/single-instance-restore.yaml $chart_archive \
  111. --namespace $NAMESPACE \
  112. -v 3 | tee -a $BUILD_ARTIFACTS/INSTALL-restore.txt
  113. #- run:
  114. # name: Twiddling our Thumbs
  115. # command: |
  116. # sleep 60
  117. # NAMESPACE=ns-$CIRCLE_BUILD_NUM
  118. # kubectl logs --namespace $NAMESPACE \
  119. # -l "app.kubernetes.io/name=neo4j,app.kubernetes.io/component=core" | tee -a $BUILD_ARTIFACTS/startlogs.txt
  120. - run:
  121. name: Wait for GKE STANDALONE deployment to succeed and become ready
  122. command: |
  123. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  124. kubectl rollout status --namespace $NAMESPACE StatefulSet/$NAME_STANDALONE-neo4j-core --watch | tee -a $BUILD_ARTIFACTS/wait-standalone.txt
  125. # We're going to test standalone first because it forms faster than cluster. In the background,
  126. # cluster is still forming....
  127. - run:
  128. name: Test STANDALONE
  129. command: |
  130. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  131. helm test $NAME_STANDALONE --namespace $NAMESPACE --logs | tee -a $BUILD_ARTIFACTS/TEST-STANDALONE.txt
  132. - run:
  133. name: Package backup chart
  134. command: |
  135. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  136. helm package tools/backup
  137. chart_archive=$(ls neo4j*.tgz)
  138. cp *.tgz $BUILD_ARTIFACTS/
  139. - run:
  140. name: Kubectl update
  141. command: |
  142. kubectl version
  143. - run:
  144. name: Install GCP Backup chart on standalone
  145. command: |
  146. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  147. helm install standalone-backup-gcp tools/backup \
  148. --namespace $NAMESPACE \
  149. --set neo4jaddr=$NAME_STANDALONE-neo4j.$NAMESPACE.svc.cluster.local:6362 \
  150. --set bucket=$BUCKET/$CIRCLE_BUILD_NUM/ \
  151. --set database="neo4j\,system" \
  152. --set cloudProvider=gcp \
  153. --set jobSchedule="0 */12 * * *" \
  154. --set secretName=neo4j-service-key \
  155. sleep 5
  156. kubectl get all -n $NAMESPACE
  157. echo "Taking a backup"
  158. kubectl create job --namespace $NAMESPACE --from=cronjob/standalone-backup-gcp-job gcp-hot-backup
  159. - run:
  160. name: Install Azure Backup chart on standalone
  161. command: |
  162. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  163. helm install standalone-backup-azure tools/backup \
  164. --namespace $NAMESPACE \
  165. --set neo4jaddr=$NAME_STANDALONE-neo4j.$NAMESPACE.svc.cluster.local:6362 \
  166. --set bucket=$AZURE_CONTAINER_NAME/build-$CIRCLE_BUILD_NUM/ \
  167. --set database="neo4j\,system" \
  168. --set cloudProvider=azure \
  169. --set jobSchedule="0 */12 * * *" \
  170. --set secretName=azure-credentials
  171. sleep 5
  172. kubectl get all -n $NAMESPACE
  173. echo "Taking a backup"
  174. kubectl create job --namespace $NAMESPACE --from=cronjob/standalone-backup-azure-job azure-hot-backup
  175. - run:
  176. name: Wait for GKE CLUSTERED deployment to succeed and become ready
  177. command: |
  178. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  179. kubectl rollout status --namespace $NAMESPACE StatefulSet/$NAME_CLUSTERED-neo4j-core --watch | tee -a $BUILD_ARTIFACTS/wait-cluster.txt
  180. kubectl rollout status --namespace $NAMESPACE StatefulSet/$NAME_CLUSTERED-neo4j-replica --watch | tee -a $BUILD_ARTIFACTS/wait-cluster-rr.txt
  181. - run:
  182. name: Test
  183. command: |
  184. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  185. helm test $NAME_CLUSTERED --namespace $NAMESPACE --logs | tee -a $BUILD_ARTIFACTS/TEST-CLUSTER.txt
  186. - run:
  187. name: Harvest Logs from cluster
  188. when: always
  189. command: |
  190. # Prove log persistence
  191. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  192. for idx in 0 1 2 ; do
  193. kubectl --namespace $NAMESPACE exec $NAME_CLUSTERED-neo4j-core-$idx -- /bin/cat /data/logs/debug.log > $BUILD_ARTIFACTS/core-$idx-debug.log ;
  194. done
  195. kubectl --namespace $NAMESPACE exec $NAME_CLUSTERED-neo4j-replica-0 -- /bin/cat /data/logs/debug.log > $BUILD_ARTIFACTS/replica-0-debug.log
  196. - run:
  197. name: Settle
  198. command: |
  199. sleep 120
  200. - run:
  201. name: Verify that GCP backup succeeded
  202. command: |
  203. # If "latest" backup pointer files exist in a dir that is specific to this
  204. # build number, we should be good.
  205. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  206. kubectl get all -n $NAMESPACE
  207. export LOGFILE=$BUILD_ARTIFACTS/gcp-backup.log
  208. kubectl get job --namespace $NAMESPACE | tee -a $LOGFILE
  209. helm status standalone-backup-gcp --namespace $NAMESPACE | tee -a $LOGFILE
  210. backup_pods=$(kubectl get pods --namespace $NAMESPACE | grep gcp-hot-backup | sed 's/ .*$//' | head -n 1)
  211. echo "Backup pods $backup_pods" | tee -a $LOGFILE
  212. kubectl describe pod --namespace $NAMESPACE "$backup_pods" | tee -a $LOGFILE
  213. kubectl logs --namespace $NAMESPACE "$backup_pods" | tee -a $LOGFILE
  214. gsutil ls "$BUCKET/$CIRCLE_BUILD_NUM/neo4j/neo4j-latest.tar.gz" 2>&1 | tee -a $BUILD_ARTIFACTS/gcp-backup.log
  215. gsutil ls "$BUCKET/$CIRCLE_BUILD_NUM/system/system-latest.tar.gz" 2>&1 | tee -a $BUILD_ARTIFACTS/gcp-backup.log
  216. - run:
  217. name: Verify that Azure backup succeeded
  218. command: |
  219. # If "latest" backup pointer files exist in a dir that is specific to this
  220. # build number, we should be good.
  221. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  222. kubectl get all -n $NAMESPACE
  223. export LOGFILE=$BUILD_ARTIFACTS/azure-backup.log
  224. kubectl get job --namespace $NAMESPACE | tee -a $LOGFILE
  225. helm status standalone-backup-azure --namespace $NAMESPACE | tee -a $LOGFILE
  226. backup_pods=$(kubectl get pods --namespace $NAMESPACE | grep azure-hot-backup | sed 's/ .*$//' | head -n 1)
  227. echo "Backup pods $backup_pods" | tee -a $LOGFILE
  228. kubectl describe pod --namespace $NAMESPACE "$backup_pods" | tee -a $LOGFILE
  229. kubectl logs --namespace $NAMESPACE "$backup_pods" | tee -a $LOGFILE
  230. az storage blob list -c $AZURE_CONTAINER_NAME --account-name helmbackups --prefix build-$CIRCLE_BUILD_NUM/ | tee -a files.txt
  231. cat files.txt >> $LOGFILE
  232. total_files=$(cat files.txt | grep name | wc -l)
  233. if [ $total_files = 6 ] ; then
  234. echo "Test pass" ;
  235. else
  236. echo "$total_files total files on Azure storage; failed"
  237. exit 1
  238. fi
  239. - run:
  240. name: Verify Azure RESTORE succeeded to single instance
  241. command: |
  242. NAMESPACE=ns-$CIRCLE_BUILD_NUM
  243. export NEO4J_PASSWORD=mySecretPassword
  244. kubectl logs --namespace $NAMESPACE $NAME_RESTORE-neo4j-core-0 \
  245. -c restore-from-backup | tee -a $BUILD_ARTIFACTS/restore.log
  246. # Wait for instance to come alive.
  247. kubectl rollout status --namespace $NAMESPACE StatefulSet/$NAME_RESTORE-neo4j-core --watch | tee -a $BUILD_ARTIFACTS/wait-standalone-restore.txt
  248. echo "MATCH (n) RETURN count(n) as n;" | kubectl run -i --rm cypher-shell \
  249. --namespace $NAMESPACE \
  250. --image=neo4j:4.4.10-enterprise --restart=Never \
  251. --command -- ./bin/cypher-shell -u neo4j -p "$NEO4J_PASSWORD" \
  252. -a bolt://$NAME_RESTORE-neo4j.$NAMESPACE.svc.cluster.local 2>&1 | tee restore-result.log
  253. echo "MATCH (n) RETURN count(n) as n;" | kubectl run -i --rm cypher-shell \
  254. --namespace $NAMESPACE \
  255. --image=neo4j:4.4.10-enterprise --restart=Never \
  256. --command -- ./bin/cypher-shell -u neo4j -p "$NEO4J_PASSWORD" \
  257. -a neo4j://$NAME_RESTORE-neo4j.$NAMESPACE.svc.cluster.local 2>&1 | tee restore-result.log
  258. cp restore-result.log $BUILD_ARTIFACTS/
  259. # Strip all cypher shell output down to a single integer result cound for n
  260. export record_count=$(cat restore-result.log | egrep '^[0-9]+$')
  261. echo "record_count=$record_count"
  262. if [ "$record_count" -gt "1000" ] ; then
  263. echo "Test pass" ;
  264. else
  265. echo "Test FAIL with record count $record_count"
  266. exit 1
  267. fi
  268. - run:
  269. name: Uninstall / Cleanup
  270. # Make sure to always run this, particularly if the test fails,
  271. # to avoid clogging our cluster.
  272. when: always
  273. command: |
  274. echo "TEAR DOWN GKE INSTANCE"
  275. gcloud container clusters delete $CLUSTER-$CIRCLE_BUILD_NUM \
  276. --async \
  277. --zone "$ZONE" \
  278. --project $PROJECT \
  279. --quiet
  280. - store_artifacts:
  281. path: build
  282. - store_artifacts:
  283. path: doc/build/site