Skip to content
This repository was archived by the owner on Oct 8, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
20774f6
Adding SquashFS option to syncing.
gregharvey Jun 13, 2022
7f3e750
Make 'tarball' the default mount type so nothing existing breaks.
gregharvey Jun 13, 2022
0b17bb5
Altering deploy_path so we can build in another location for SquashFS…
gregharvey Jun 14, 2022
0b380de
Ensuring the build dir exists if doing a SquashFS build.
gregharvey Jun 14, 2022
7d8a9ac
Force symlink creation as the deploy dir may not exist yet.
gregharvey Jun 14, 2022
307ac67
Running mount commands with sudo.
gregharvey Jun 15, 2022
4424413
Tweaking link command and destination for live links.
gregharvey Jun 15, 2022
7e39641
Slight bug in link path handling for SquashFS.
gregharvey Jun 15, 2022
2bb6459
Checking for existing mount and using remount operation.
gregharvey Jun 15, 2022
f076147
Stop ce-deploy trying to delete from read-only SquashFS mount.
gregharvey Jun 15, 2022
6c7d2c9
Formatting error, these special jinja2 things are not filters - no sp…
gregharvey Jun 15, 2022
5e145d4
Reloading services to make sure mounting doesn't fail.
gregharvey Jun 16, 2022
57ed6e3
Picking more sensible loop var name.
gregharvey Jun 16, 2022
1b66af2
Moving to shell for mount check and fixing jinja2 filter names.
gregharvey Jun 16, 2022
9db2899
Trying with the posix mount module instead of command.
gregharvey Jun 16, 2022
169a5f7
Working through user/sudo issues.
gregharvey Jun 16, 2022
e878aab
Altering symlink handling slightly so we have the deploy directory al…
gregharvey Jun 16, 2022
d56accb
Merge branch '1.x' into squashfs
gregharvey Jun 16, 2022
c45db1d
Simplifying 'when' checks.
gregharvey Jun 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 38 additions & 13 deletions roles/_init/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
---
# Ensure default values for common variables.
- name: Define deploy user.
set_fact:
ansible.builtin.set_fact:
deploy_user: "{{ deploy_user | default('deploy') }}"
- name: Define deploy base path.
set_fact:
ansible.builtin.set_fact:
deploy_base_path: "{{ deploy_base_path | default('/home/{{ deploy_user }}/deploy/{{ project_name }}_{{ build_type }}') }}"
- name: Define mounted directory for assets.
set_fact:
ansible.builtin.set_fact:
deploy_assets_base_path: "{{ deploy_assets_base_path | default('/home/{{ deploy_user }}/shared/{{ project_name }}_{{ build_type }}/assets') }}"
- name: Define webroot.
set_fact:
ansible.builtin.set_fact:
webroot: "{{ webroot | default('web') }}"
- name: Define build deploy path prefix.
set_fact:
ansible.builtin.set_fact:
deploy_path_prefix: "{{ deploy_base_path }}/{{ project_name }}_{{ build_type }}_build_"
- name: Define build deploy path.
set_fact:
ansible.builtin.set_fact:
deploy_path: "{{ deploy_path | default('{{ deploy_path_prefix }}{{ build_number }}') }}"
- name: Define live_symlink dest.
set_fact:
ansible.builtin.set_fact:
live_symlink_dest: "{{ live_symlink_dest | default('{{ deploy_base_path }}/live.{{ project_name }}_{{ build_type }}') }}"

# Manipulate variables for SquashFS builds.
- name: Define image builds base path.
ansible.builtin.set_fact:
build_base_path: "/home/{{ deploy_user }}/builds/{{ project_name }}_{{ build_type }}"
when: deploy_code.mount_type == "squashfs"
- name: Define image builds build path prefix.
ansible.builtin.set_fact:
build_path_prefix: "{{ build_base_path }}/{{ project_name }}_{{ build_type }}_build_"
when: deploy_code.mount_type == "squashfs"
- name: Define live_symlink dest for image builds.
ansible.builtin.set_fact:
live_symlink_build_dest: "{{ live_symlink_build_dest | default('{{ build_base_path }}/live.{{ project_name }}_{{ build_type }}') }}"
when: deploy_code.mount_type == "squashfs"
- name: Overwrite deploy and live_symlink paths if SquashFS deploy.
ansible.builtin.set_fact:
deploy_path: "{{ build_path | default('{{ build_path_prefix }}{{ build_number }}') }}"
when: deploy_code.mount_type == "squashfs"

# Gather last known good build directly from symlink.
# This can happen:
# - when the first builds failed,
Expand All @@ -42,7 +60,7 @@

# This is passed from caller.
- name: Gather last known good build number.
set_fact:
ansible.builtin.set_fact:
previous_build_number: "{{ previous_known_build_number }}"

# - set_fact:
Expand All @@ -53,27 +71,34 @@

# Make sure the deploy target exists.
- name: Ensure deploy target directory exists.
file:
ansible.builtin.file:
path: "{{ deploy_base_path }}"
state: directory

# Make sure the build target exists.
- name: Ensure build target directory exists.
ansible.builtin.file:
path: "{{ build_base_path }}"
state: directory
when: deploy_code.mount_type == "squashfs"

# Check for project specific init tasks.
- name: Check that {{ project_type }}.yml exists.
stat:
ansible.builtin.stat:
path: "{{ role_path }}/tasks/{{ project_type }}.yml"
register: _project_type_task_result
delegate_to: "localhost"

# Project specific init tasks.
- name: Include project init tasks.
include_tasks: "{{ project_type }}.yml"
ansible.builtin.include_tasks: "{{ project_type }}.yml"
when:
- _project_type_task_result.stat.exists

- name: Define opcache cachetool path.
set_fact:
ansible.builtin.set_fact:
cachetool_bin: "{{ cachetool_bin | default('/home/{{ deploy_user }}/.bin/cachetool.phar') }}"

- name: Ensure we have a cachetool binary.
import_role:
ansible.builtin.import_role:
name: cli/cachetool
13 changes: 11 additions & 2 deletions roles/deploy_code/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ deploy_code:
# Specify any additional symlink to create, with src (target) and dest (link).
# src: can be either absolute or relative to the dest (eg. '/var/my_data', '/home/deploy/simplesaml', '../../../myconfig')
# dest: can only be relative to the root of your repository (eg. 'www/themes/myassets', 'var/cache')
# create: wether to create the target if it does not exists.
# create: whether to create the target if it does not exists.
# - src: '/home/{{ deploy_user }}//{{ project_name }}_{{ build_type }}/simplesaml'
# dest: 'vendor/simplesamlphp/simplesamlphp/config'
# - src: '/var/simplesaml/etc'
Expand All @@ -15,12 +15,21 @@ deploy_code:
templates: []
# Number of builds to keep. Note this is independant of databases/dump.
keep: 10
# Wether to sync the local deploy base to a shared destination, after successful build.
# Whether to sync the local deploy base to a shared destination, after successful build.
mount_sync: ""
# mount_sync: "/home/{{ deploy_user }}/shared/{{ project_name }}_{{ build_type }}/deploy"
# Type of file to use for sync - 'squashfs' or 'tarball'
# @see the _init role for SquashFS build dir paths
# @see the squashfs role in ce-provision which installs the special conditions required by the deploy user to use this behaviour
mount_type: "tarball"
# Path that you want to make sure has 755 permissions. Make sure to include the webroot WITHOUT the slash.
perms_fix_path: ""
# perms_fix_path: "www/sites/default"
# List of services to reload to free the loop device for 'squashfs' builds, post lazy umount.
# @see the squashfs role in ce-provision where special permissions for deploy user to manipulate services get granted.
services: []
# services:
# - php8.0-fpm
# Trigger an API call to rebuild infra after a deploy, e.g. if you need to repack an AMI.
rebuild_infra: false
# Details of API call to trigger. See api_call role.
Expand Down
108 changes: 105 additions & 3 deletions roles/deploy_code/tasks/cleanup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,66 @@
become: true
when: "www_user != deploy_user"

- name: Ensure permissions are set on directory.
- name: Ensure permissions are set on deploy directory.
ansible.builtin.shell:
cmd: "if [ -d {{ deploy_path_prefix }}{{ item }}/{{ deploy_code.perms_fix_path }} ]; then chmod 755 {{ deploy_path_prefix }}{{ item }}/{{ deploy_code.perms_fix_path }}; fi"
with_sequence: start={{ [previous_build_number | int - 50, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }}
when:
- deploy_code.perms_fix_path is defined
- deploy_code.perms_fix_path | length > 1
- deploy_code.mount_type != "squashfs"

- name: Delete codebases.
- name: Ensure permissions are set on builds directory.
ansible.builtin.shell:
cmd: "if [ -d {{ build_path_prefix }}{{ item }}/{{ deploy_code.perms_fix_path }} ]; then chmod 755 {{ build_path_prefix }}{{ item }}/{{ deploy_code.perms_fix_path }}; fi"
with_sequence: start={{ [previous_build_number | int - 50, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }}
when:
- deploy_code.perms_fix_path is defined
- deploy_code.perms_fix_path | length > 1
- deploy_code.mount_type == "squashfs"

- name: Delete codebases from deploy directory.
ansible.builtin.file:
name: "{{ deploy_path_prefix }}{{ item }}"
state: absent
with_sequence: start={{ [previous_build_number | int - 50, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }}
when:
- deploy_code.mount_type != "squashfs"

- name: Delete codebases from builds directory.
ansible.builtin.file:
name: "{{ build_path_prefix }}{{ item }}"
state: absent
with_sequence: start={{ [previous_build_number | int - 50, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }}
when:
- deploy_code.mount_type == "squashfs"

- name: Create a tarball of the deployed codebases.
ansible.builtin.command:
cmd: "tar -cvf /tmp/{{ project_name }}_{{ build_type }}.tar --owner=0 --group=0 {{ deploy_base_path }}"
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "tarball"
run_once: true

- name: Ensure older SquashFS images are deleted.
ansible.builtin.file:
path: "{{ build_base_path }}/deploy.sqsh"
state: absent
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "squashfs"
run_once: true

- name: Create a SquashFS image of the deployed codebases.
ansible.builtin.command:
cmd: "mksquashfs {{ build_base_path }} /tmp/{{ project_name }}_{{ build_type }}.sqsh"
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "squashfs"
run_once: true

- name: Create destination folder.
Expand All @@ -38,14 +78,76 @@
- deploy_code.mount_sync | length > 1
run_once: true

- name: Move to final destination.
- name: Move tar file to final destination.
ansible.builtin.command:
cmd: "mv /tmp/{{ project_name }}_{{ build_type }}.tar {{ deploy_code.mount_sync }}/{{ project_name }}_{{ build_type }}.tar"
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "tarball"
run_once: true

- name: Move SquashFS image to final destination.
ansible.builtin.command:
cmd: "mv /tmp/{{ project_name }}_{{ build_type }}.sqsh {{ deploy_code.mount_sync }}/{{ project_name }}_{{ build_type }}.sqsh"
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "squashfs"
run_once: true

- name: Copy SquashFS image to local server.
ansible.builtin.command:
cmd: "cp {{ deploy_code.mount_sync }}/{{ project_name }}_{{ build_type }}.sqsh {{ build_base_path }}/deploy.sqsh"
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "squashfs"

- name: Check if we have a mount already.
ansible.builtin.shell:
cmd: "mount | grep {{ deploy_base_path }}"
ignore_errors: true
register: _mount_check
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "squashfs"

- name: Unmount existing SquashFS image.
ansible.builtin.command:
cmd: "umount -l {{ deploy_base_path }}"
become: true
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "squashfs"
- _mount_check is succeeded

- name: Reload any services that might be keeping the loop device busy.
ansible.builtin.service:
name: "{{ www_service }}"
state: reloaded
with_items: "{{ deploy_code.services }}"
loop_control:
loop_var: www_service
become: true
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "squashfs"
- _mount_check is succeeded
- deploy_code.services | length > 0

- name: Mount new SquashFS image.
ansible.builtin.command:
cmd: "mount {{ build_base_path }}/deploy.sqsh {{ deploy_base_path }} -t squashfs -o loop"
become: true
when:
- deploy_code.mount_sync is defined
- deploy_code.mount_sync | length > 1
- deploy_code.mount_type == "squashfs"

- name: Trigger an infrastructure rebuild.
ansible.builtin.include_role:
name: api_call
Expand Down
23 changes: 17 additions & 6 deletions roles/live_symlink/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
---
- set_fact:
- ansible.builtin.set_fact:
_live_symlink_build_target: "{{ deploy_base_path }}/{{ project_name }}_{{ build_type }}_build_{{ build_number }}"

- set_fact:
- ansible.builtin.set_fact:
_live_symlink_build_target: "{{ deploy_base_path }}/{{ project_name }}_{{ build_type }}_build_{{ previous_build_number }}"
when: deploy_operation == 'revert'

- ansible.builtin.set_fact:
_live_symlink_dest_target: "{{ live_symlink_dest }}"

- ansible.builtin.set_fact:
_live_symlink_dest_target: "{{ live_symlink_build_dest }}"
when: deploy_code.mount_type == "squashfs"

- name: Symlink build.
file:
ansible.builtin.file:
src: "{{ _live_symlink_build_target }}"
dest: "{{ live_symlink_dest }}"
dest: "{{ _live_symlink_dest_target }}"
state: link
follow: false
force: true

- name: Generate additional templates.
template:
ansible.builtin.template:
src: "{{ template.src }}"
dest: "{{ deploy_path }}/{{ template.dest }}"
with_items: "{{ live_symlink.templates }}"
Expand All @@ -24,10 +33,12 @@
- deploy_operation == 'deploy'

- name: Create additional symlinks.
file:
ansible.builtin.file:
src: "{{ link.src }}"
dest: "{{ deploy_path }}/{{ link.dest }}"
state: link
follow: false
force: true
with_items: "{{ live_symlink.symlinks }}"
loop_control:
loop_var: link
Expand Down