Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symlinking on deploys & Rollback functionality #8

Merged
merged 12 commits into from
Apr 17, 2021
151 changes: 123 additions & 28 deletions ansible/roles/glimesh-web/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
name: "{{ inventory_hostname }}"

- name: Ensure .ssh directory exists.
file:
file:
dest: "/root/.ssh"
mode: 0700
owner: root
mode: 0700
owner: root
state: directory

- name: Install ssh key
copy:
src: "glimesh-deploy"
copy:
src: "glimesh-deploy"
dest: "/root/.ssh/id_rsa"
mode: 0600
owner: root
Expand All @@ -27,12 +27,12 @@

# - name: install required packages
# apt:
# pkg:
# - esl-erlang
# - elixir
# - npm
# pkg:
# - esl-erlang
# - elixir
# - npm
# - git
# - openssl
# - openssl
# - imagemagick
# state: present
# update_cache: yes
Expand All @@ -43,8 +43,10 @@
- name: install rebar
command: mix local.rebar --force

- name: ensure /tmp/glimesh.tv exists
file: path=/tmp/glimesh.tv state=directory
- name: ensure tmp build dir exists
file:
path: /tmp/glimesh.tv
state: directory

- name: download glimesh.tv
git:
Expand All @@ -62,19 +64,41 @@
chdir: /tmp/glimesh.tv
register: glimesh_git_hash

- name: change version
- name: change version
lineinfile:
path: /tmp/glimesh.tv/mix.exs
regexp: '^\s+version: .*$'
line: "version: \"0.1.0+{{ glimesh_git_hash.stdout }}\","

- set_fact:
deploy_dest: "/opt/glimesh.tv-{{ glimesh_git_hash.stdout }}"

## Check we should deploy

- name: Get currently deployed hash
stat:
path: /opt/glimesh.tv
follow: no
get_checksum: no
register: current_deploy

- name: Same version deployed?
pause:
prompt: |
WARNING: Latest version is already deployed.
Pess Enter to continue
delegate_to: localhost
when: current_deploy.stat.exists and current_deploy.stat.lnk_target == deploy_dest
register: same_deploy

## Build the deploy

- name: install mix dependencies
command: mix do deps.get, deps.compile
command: mix do deps.get, deps.compile
args:
chdir: /tmp/glimesh.tv
environment:
MIX_ENV: prod
# when: glimesh.changed

- name: install npm asset deps
command: npm --prefix ./assets ci --progress=false --no-audit --loglevel=error
Expand All @@ -95,38 +119,62 @@
# when: glimesh.changed

- name: build glimesh.tv
command: mix do compile --force, release --force --overwrite
command: mix do compile --force, release --force --overwrite
args:
chdir: /tmp/glimesh.tv
environment:
MIX_ENV: prod
# when: glimesh.changed

- name: Ensure new directory exists
file:
path: "{{ deploy_dest }}"
state: directory
owner: nobody
recurse: yes

- name: Copy newly built files to new host
synchronize:
src: /tmp/glimesh.tv/_build/prod
dest: "{{ deploy_dest }}"
links: yes
delete: yes
delegate_to: "{{ inventory_hostname }}"

- name: Check permissions
file:
path: "{{ deploy_dest }}"
owner: nobody
recurse: yes

## Change the service

- name: setup unit file for glimesh.tv
template: src=glimesh.service.j2 dest=/etc/systemd/system/glimesh.service mode=644
template:
src: glimesh.service.j2
dest: /etc/systemd/system/glimesh.service
mode: 644
tags: config

- name: reload systemd immediately
systemd:
daemon_reload: yes

- name: gracefully shut down old glimesh app
systemd:
systemd:
name: glimesh
state: stopped

# Copying the file will automatically restart the daemon.
- name: copy built glimesh.tv
command: cp -Rf /tmp/glimesh.tv/_build/prod /opt/glimesh.tv

- name: permissions
- name: Change the symlink
file:
path: /opt/glimesh.tv
src: "{{ deploy_dest }}"
dest: /opt/glimesh.tv
state: link
owner: nobody
recurse: yes
force: yes

- name: start new glimesh app
systemd:
systemd:
name: glimesh
state: started

Expand All @@ -136,5 +184,52 @@
delay: 5

- name: pause to make sure the other node can take over
pause:
seconds: 15
pause:
seconds: 15

- name: Add a symlink to the old deploy for ease of rollback
file:
src: "{{ current_deploy.stat.lnk_target }}"
dest: /opt/glimesh.tv-old
state: link
owner: nobody
force: yes

- name: Cleanup old directories
block:
- name: Get currently deployed dest
stat:
path: /opt/glimesh.tv
follow: no
get_checksum: no
register: gtv_current

- name: Get old deployed dest
stat:
path: /opt/glimesh.tv-old
follow: no
get_checksum: no
register: gtv_old

# Cleanup
- name: Find all deploy folders
find:
paths: /opt
file_type: directory
use_regex: yes
patterns: "^glimesh.tv-([a-zA-Z0-9]+)$"
recurse: no
register: all_deploys

- name: Delete old directories
file:
path: "{{ item }}"
state: absent
when:
- item != '/opt/glimesh.tv-old'
- gtv_current.stat.exists == False or item != gtv_current.stat.lnk_target
- gtv_old.stat.exists == False or item != gtv_old.stat.lnk_target
with_items: "{{ all_deploys.files | map(attribute='path') | list }}"

tags:
- cleanup
34 changes: 34 additions & 0 deletions ansible/web-rollback.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
- name: web
hosts: web
serial: 1

tasks:
- name: Get old deployed hash
stat:
path: /opt/glimesh.tv-old
follow: no
get_checksum: no
register: old_deploy

- name: Change the symlink
file:
src: "{{ old_deploy.stat.lnk_target }}"
dest: /opt/glimesh.tv
state: link
owner: nobody
force: yes

- name: restart glimesh
systemd:
name: glimesh
daemon_reload: yes
state: restarted

- name: wait for service to be online
wait_for:
port: 8080
delay: 5

- name: pause to make sure the other node can take over
pause:
seconds: 15