diff options
author | Paul Bonaud <paul.bonaud@fretlink.com> | 2019-07-30 17:57:55 +0200 |
---|---|---|
committer | Paul Bonaud <paul.bonaud@fretlink.com> | 2019-07-31 14:18:37 +0200 |
commit | fa045db6b7d85f1c5aa53b8fba86958bde4b368b (patch) | |
tree | bd8a49590b380867bd2688800ff772a0ae9b8669 | |
parent | 8305eb92f5bb6445868fda6d4e3075011d1fd248 (diff) | |
download | ansible-clever-fa045db6b7d85f1c5aa53b8fba86958bde4b368b.tar.gz ansible-clever-fa045db6b7d85f1c5aa53b8fba86958bde4b368b.tar.zst ansible-clever-fa045db6b7d85f1c5aa53b8fba86958bde4b368b.zip |
deploy: revert back to git push + polling
In #19 we removed the polling script to rely on the clever cli's
ability to wait on `clever deploy` command.
After more than 6 months of experimentation it seems the command is
still not reliable (sometimes the command never returns, sometimes it
returns even when the deployment has finished..).
Thus we are reverting back to our manual process of polling `clever
activity` every 5 seconds.
The timeout for this polling is set at the Ansible level (not in the
bash script) and set for 40 minutes. This should give enough time for
any of our applications to deploy.
-rwxr-xr-x | files/clever-wait-deploy.sh | 80 | ||||
-rw-r--r-- | tasks/deploy.yml | 93 | ||||
-rw-r--r-- | tasks/setup.yml | 1 |
3 files changed, 113 insertions, 61 deletions
diff --git a/files/clever-wait-deploy.sh b/files/clever-wait-deploy.sh new file mode 100755 index 0000000..98c5c37 --- /dev/null +++ b/files/clever-wait-deploy.sh | |||
@@ -0,0 +1,80 @@ | |||
1 | #!/usr/bin/env bash | ||
2 | |||
3 | set -ueo pipefail | ||
4 | |||
5 | VERBOSE=${VERBOSE:-} | ||
6 | lastCleverActivity="" | ||
7 | |||
8 | function cleverActivity { | ||
9 | lastCleverActivity=$(clever activity) | ||
10 | } | ||
11 | |||
12 | function ensure { | ||
13 | if [ "$?" == "1" ] | ||
14 | then | ||
15 | echo "✗ Deployment failed!" | ||
16 | fi | ||
17 | VERBOSE=true | ||
18 | verbose | ||
19 | } | ||
20 | |||
21 | trap ensure EXIT ERR | ||
22 | |||
23 | function deploying { | ||
24 | checkStatus "$1" "IN PROGRESS" | ||
25 | } | ||
26 | |||
27 | function deployed { | ||
28 | checkStatus "$1" "OK" | ||
29 | } | ||
30 | |||
31 | function inactive { | ||
32 | checkStatus "$1" "" "-v" | ||
33 | } | ||
34 | |||
35 | function checkStatus { | ||
36 | local commit="$1" | ||
37 | local status="$2" | ||
38 | |||
39 | cleverActivity | ||
40 | echo "${lastCleverActivity}" | tail -n1 | grep ${3:+ "${3}"} -q -E "${status}.*DEPLOY.*${commit}" | ||
41 | } | ||
42 | |||
43 | function verbose { | ||
44 | if [ -n "${VERBOSE}" ]; then | ||
45 | echo -e "\\nLast clever activity:" | ||
46 | echo -e "${lastCleverActivity}\\n" | ||
47 | fi | ||
48 | } | ||
49 | |||
50 | function check { | ||
51 | local commit="$1" | ||
52 | local samplingTime=5 | ||
53 | |||
54 | echo "️▫ Waiting for deployment to start..." | ||
55 | while inactive "$commit" | ||
56 | do | ||
57 | verbose | ||
58 | sleep $samplingTime | ||
59 | done | ||
60 | |||
61 | # Wait for completion | ||
62 | echo "▪ Deployment in progress..." | ||
63 | while deploying "$commit" | ||
64 | do | ||
65 | verbose | ||
66 | sleep $samplingTime | ||
67 | done | ||
68 | |||
69 | deployed "$commit" | ||
70 | echo "✓ Deployment done." | ||
71 | } | ||
72 | |||
73 | function getHeadRev { | ||
74 | local chdir="$1/.git" | ||
75 | |||
76 | git --git-dir="$chdir" rev-parse HEAD | ||
77 | } | ||
78 | |||
79 | workdir="$(pwd)" | ||
80 | check "$(getHeadRev "${workdir}")" | ||
diff --git a/tasks/deploy.yml b/tasks/deploy.yml index 74232a6..df02464 100644 --- a/tasks/deploy.yml +++ b/tasks/deploy.yml | |||
@@ -31,18 +31,18 @@ | |||
31 | - skip_ansible_lint | 31 | - skip_ansible_lint |
32 | 32 | ||
33 | - name: Deploy to Clever-Cloud | 33 | - name: Deploy to Clever-Cloud |
34 | shell: "clever deploy --force" | 34 | command: "git push --force git+ssh://git@push-par-clevercloud-customers.services.clever-cloud.com/{{ clever_app }}.git HEAD:refs/heads/master" |
35 | args: | 35 | args: |
36 | chdir: "{{ clever_app_root }}" | 36 | chdir: "{{ clever_app_root }}" |
37 | environment: | ||
38 | CONFIGURATION_FILE: "{{ clever_login_file }}" | ||
39 | register: clever_deploy | 37 | register: clever_deploy |
40 | async: 900 # 15 minutes timeout | ||
41 | poll: 30 | ||
42 | ignore_errors: true | 38 | ignore_errors: true |
43 | tags: | 39 | tags: |
44 | - skip_ansible_lint | 40 | - skip_ansible_lint |
45 | 41 | ||
42 | ################################################################## | ||
43 | # Re-deploy only if its the first clever deploy for that project # | ||
44 | ################################################################## | ||
45 | |||
46 | - name: First time push to Clever-Cloud needs a full git clone | 46 | - name: First time push to Clever-Cloud needs a full git clone |
47 | command: "git fetch --unshallow" | 47 | command: "git fetch --unshallow" |
48 | args: | 48 | args: |
@@ -55,72 +55,43 @@ | |||
55 | - skip_ansible_lint | 55 | - skip_ansible_lint |
56 | 56 | ||
57 | - name: Deploy to Clever-Cloud | 57 | - name: Deploy to Clever-Cloud |
58 | shell: "clever deploy --force" | 58 | command: "git push --force git+ssh://git@push-par-clevercloud-customers.services.clever-cloud.com/{{ clever_app }}.git HEAD:refs/heads/master" |
59 | args: | 59 | args: |
60 | chdir: "{{ clever_app_root }}" | 60 | chdir: "{{ clever_app_root }}" |
61 | environment: | 61 | when: |
62 | CONFIGURATION_FILE: "{{ clever_login_file }}" | 62 | - clever_deploy is failed |
63 | when: clever_deploy is failed | 63 | - clever_deploy.stderr is defined |
64 | - clever_deploy.stderr is search("Failed to read git object") | ||
64 | register: clever_deploy | 65 | register: clever_deploy |
65 | async: 900 # 15 minutes timeout | ||
66 | poll: 30 | ||
67 | ignore_errors: true | ||
68 | tags: | 66 | tags: |
69 | - skip_ansible_lint | 67 | - skip_ansible_lint |
70 | 68 | ||
71 | - name: Return deployment logs | 69 | ############################################################################## |
72 | debug: | 70 | # Poll deployment status from 'clever activity' command. # |
73 | var: clever_deploy.stdout | 71 | # 'clever deploy' command is not yet 100% reliable to get a blocking command # |
74 | when: clever_deploy.stdout is defined | 72 | # until the deployment is over. Hence the need for a custom waiting script. # |
75 | 73 | ############################################################################## | |
76 | - name: Return deployment errors | ||
77 | debug: | ||
78 | var: clever_deploy.stderr | ||
79 | when: | ||
80 | - clever_deploy is failed | ||
81 | - clever_deploy.stderr is defined | ||
82 | 74 | ||
83 | - name: Retrieve clever activity | 75 | - name: Watch deployment status |
84 | command: clever activity | 76 | command: "{{ ansible_env.HOME }}/{{ clever_user_path }}/clever-wait-deploy.sh" |
85 | args: | 77 | args: |
86 | chdir: "{{ clever_app_root }}" | 78 | chdir: "{{ clever_app_root }}" |
87 | environment: | 79 | environment: |
88 | CONFIGURATION_FILE: "{{ clever_login_file }}" | 80 | CONFIGURATION_FILE: "{{ clever_login_file }}" |
89 | changed_when: false | 81 | async: 2400 # 40 minutes |
90 | register: clever_activity_result | 82 | poll: 0 |
91 | 83 | register: long_command | |
92 | - name: Display clever activity | 84 | changed_when: False |
93 | debug: | ||
94 | var: clever_activity_result.stdout_lines | ||
95 | 85 | ||
96 | - name: Get current commit sha | 86 | - name: Wait 40 minutes for deployment completion |
97 | command: git show -q --format=format:%H HEAD | 87 | async_status: |
98 | args: | 88 | jid: "{{ long_command.ansible_job_id }}" |
99 | chdir: "{{ clever_app_root }}" | 89 | register: job_result |
100 | warn: False | 90 | until: job_result.finished |
101 | changed_when: false | 91 | delay: 30 |
102 | register: current_commit_sha | 92 | retries: 80 # 40 minutes (80 * 30 secs delay) |
103 | 93 | ||
104 | # #### | 94 | # Output of waiting script stdout |
105 | # Expects all configuration to be located in the project's repository. | 95 | - name: Output waiting script logs |
106 | # Making a git commit bound to the same *configuration* and *executable* version. | 96 | debug: |
107 | # ## | 97 | var: job_result.stdout_lines |
108 | - name: Fail if current commit is not the last deployed one | ||
109 | fail: | ||
110 | msg: "The clever deployment failed! Please check latest deploy activity logs above." | ||
111 | when: | ||
112 | - clever_deploy is failed | ||
113 | - clever_deploy.stderr is defined | ||
114 | - clever_deploy.stderr is search("application is up-to-date") | ||
115 | - | | ||
116 | (current_commit_sha.stdout_lines[-1] not in clever_activity_result.stdout_lines[-1]) | ||
117 | or | ||
118 | (clever_activity_valid_deploy_keyword not in clever_activity_result.stdout_lines[-1]) | ||
119 | |||
120 | - name: Fail on any other deployment errors | ||
121 | fail: | ||
122 | msg: "The clever deployment failed! Please check logs above." | ||
123 | when: | ||
124 | - clever_deploy is failed | ||
125 | - clever_deploy.stderr is defined | ||
126 | - clever_deploy.stderr is not search("application is up-to-date") | ||
diff --git a/tasks/setup.yml b/tasks/setup.yml index 9d1f8aa..c5abb81 100644 --- a/tasks/setup.yml +++ b/tasks/setup.yml | |||
@@ -27,5 +27,6 @@ | |||
27 | dest: "{{ ansible_env.HOME }}/{{ clever_user_path }}/{{ item }}" | 27 | dest: "{{ ansible_env.HOME }}/{{ clever_user_path }}/{{ item }}" |
28 | mode: 0755 | 28 | mode: 0755 |
29 | with_items: | 29 | with_items: |
30 | - clever-wait-deploy.sh | ||
30 | - clever-set-domain.sh | 31 | - clever-set-domain.sh |
31 | - clever-set-drain.sh | 32 | - clever-set-drain.sh |