fix: improve script + add ansible variant (draft)

This commit is contained in:
Glenn Y. Rolland 2024-07-10 18:22:47 +02:00
parent 7c1a0bbcf2
commit c0f3fbb841
5 changed files with 415 additions and 29 deletions

10
config.yml Normal file
View file

@ -0,0 +1,10 @@
source:
host: source.example.com
user: source_user
port: 22
destination:
host: destination.example.com
user: destination_user
port: 22

View file

@ -4,51 +4,99 @@
set -e
set -u
LOCAL="danaos.infra.glenux.net"
REMOTE="dinlas.infra.glenux.net"
SSH_REMOTE="root@$REMOTE"
SSH_KEY="$HOME/.ssh/dinlas-to-danaos_rsync2022_ed25519"
# Generate SSH keypair on control machine (in temporary directory)
TEMP_DIR=$(mktemp -d)
MIGRATION_SSH_KEY="$TEMP_DIR/dokku-sync-migration_ed25519"
SSH_KEY="/path/to/control/key"
ssh-keygen -t ed25519 -f "$SSH_KEY" -N ""
sshrun() {
ssh -i "$SSH_KEY" root@dinlas.infra.glenux.net "$*"
usage() {
echo "Usage: $0 --src USER@HOSTNAME --dest USER@HOSTNAME --privkey PATH_TO_PRIVATE_KEY"
echo
echo "Options:"
echo " --src Source SSH address in the format USER@HOSTNAME"
echo " --dest Destination SSH address in the format USER@HOSTNAME"
echo " --privkey Path to the private SSH key"
echo " -h, --help Show this help message"
}
# mkdir -p /srv/backup
# APPS=$ (sshrun "dokku ls" |awk '/^[^--]/ { print $1; }')
dest_run() {
ssh -i "$SSH_KEY" "$SOURCE_SSH_ADDR" "$*"
}
source_run() {
ssh -i "$SSH_KEY" "$SOURCE_SSH_ADDR" "$*"
}
## ENTRYPOINT
# Loop and parse command line arguments
while [ "$#" -gt 0 ]; do
case "$1" in
--src)
SRC_SSH_ADDR="$2"
shift 2
;;
--dest)
DEST_SSH_ADDR="$2"
shift 2
;;
--privkey)
SSH_KEY="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
# Split values for SRC and DEST
DEST_HOST=$(echo "$DEST_SSH_ADDR" | cut -d'@' -f2)
DEST_USER=$(echo "$DEST_SSH_ADDR" | cut -d'@' -f1)
SOURCE_HOST=$(echo "$SRC_SSH_ADDR" | cut -d'@' -f2)
SOURCE_USER=$(echo "$SRC_SSH_ADDR" | cut -d'@' -f1)
# Stop all remote services
sshrun "dokku ps:stop --all"
source_run "dokku ps:stop --all"
sshrun "dokku mariadb:list |tail -n+2 |xargs -iSERVICE -- dokku mariadb:stop SERVICE"
sshrun "dokku postgres:list |tail -n+2 |xargs -iSERVICE -- dokku postgres:stop SERVICE"
sshrun "dokku redis:list |tail -n+2 |xargs -iSERVICE -- dokku redis:stop SERVICE"
sshrun "dokku mongo:list |tail -n+2 |xargs -iSERVICE -- dokku mongo:stop SERVICE"
source_run "dokku mariadb:list |tail -n+2 |xargs -iSERVICE -- dokku mariadb:stop SERVICE"
source_run "dokku postgres:list |tail -n+2 |xargs -iSERVICE -- dokku postgres:stop SERVICE"
source_run "dokku redis:list |tail -n+2 |xargs -iSERVICE -- dokku redis:stop SERVICE"
source_run "dokku mongo:list |tail -n+2 |xargs -iSERVICE -- dokku mongo:stop SERVICE"
sshrun "systemctl stop docker"
sshrun "systemctl stop docker.socket"
source_run "systemctl stop docker"
source_run "systemctl stop docker.socket"
# Stop all local services
dokku ps:stop --all
systemctl stop docker
systemctl stop docker.socket
dest_run "dokku ps:stop --all"
dest_run "systemctl stop docker"
dest_run "systemctl stop docker.socket"
# Prepare directories
dest_run "mkdir -p /home/dokku/"
dest_run "mkdir -p /home/data/"
dest_run "mkdir -p /var/lib/dokku/"
# Copy all data
mkdir -p /home/dokku/
mkdir -p /home/data/
mkdir -p /var/lib/dokku/
rsync -avz --delete "$SOURCE_SSH_ADDR:/home/dokku/" "$DEST_SSH_ADDR:/home/dokku/"
rsync -avz --delete "$SOURCE_SSH_ADDR:/var/lib/dokku/" "$DEST_SSH_ADDR:/var/lib/dokku/"
rsync -avz --delete "$SOURCE_SSH_ADDR:/home/data/" "$DEST_SSH_ADDR:/home/data/"
rsync -avz --delete "$SOURCE_SSH_ADDR:/home/git/" "$DEST_SSH_ADDR:/home/git/"
rsync -avz --delete "$SSH_REMOTE:/home/dokku/" /home/dokku/
rsync -avz --delete "$SSH_REMOTE:/var/lib/dokku/" /var/lib/dokku/
rsync -avz --delete "$SSH_REMOTE:/home/data/" /home/data/
rsync -avz --delete "$SSH_REMOTE:/home/git/" /home/git/
# FIXME: check if rsync succeeded
# Start all local services
dokku apps:list
dest_run "dokku apps:list"
# Patch URLs from imported domains
find /home/dokku/ -name VHOST -or -name URLS \
| xargs -iFILE -- \
sed -i "s/$REMOTE/$LOCAL/g" FILE
dest_run "find /home/dokku/ -name VHOST -or -name URLS -print0 | xargs -0 -iFILE -- sed -i \"s/$SOURCE_HOST/$DEST_HOST/g\" FILE"
echo "SUCCESS"

0
main.yml Normal file
View file

134
playbook.yml Normal file
View file

@ -0,0 +1,134 @@
---
- name: Dokku migration playbook
hosts: localhost
gather_facts: 'no'
vars_files:
- config.yml
tasks:
- name: Create temporary directory for SSH keypair
tempfile:
state: directory
suffix: dokku_sync
register: temp_dir
- name: Generate SSH keypair
community.crypto.openssh_keypair:
path: "{{ temp_dir.path }}/dokku_sync_migration"
type: ed25519
owner: "{{ lookup('env', 'USER') }}"
group: "{{ lookup('env', 'USER') }}"
mode: '0600'
- name: Handle Source Server
hosts: source
gather_facts: 'yes'
vars_files:
- config.yml
tasks:
- name: Stop all Dokku apps
command: dokku ps:stop --all
- name: Stop all MariaDB services
shell: dokku mariadb:list | tail -n+2 | xargs -iSERVICE dokku mariadb:stop SERVICE
- name: Stop all PostgreSQL services
shell: dokku postgres:list | tail -n+2 | xargs -iSERVICE dokku postgres:stop SERVICE
- name: Stop all Redis services
shell: dokku redis:list | tail -n+2 | xargs -iSERVICE dokku redis:stop SERVICE
- name: Stop all MongoDB services
shell: dokku mongo:list | tail -n+2 | xargs -iSERVICE dokku mongo:stop SERVICE
- name: Stop Docker service
service:
name: docker
state: stopped
- name: Stop Docker socket service
service:
name: docker.socket
state: stopped
- name: Handle Destination Server
hosts: destination
gather_facts: yes
vars_files:
- config.yml
tasks:
- name: Stop all Dokku apps
command: dokku ps:stop --all
- name: Stop Docker service
service:
name: docker
state: stopped
- name: Stop Docker socket service
service:
name: docker.socket
state: stopped
- name: Create necessary directories
file:
path: "{{ item }}"
state: directory
owner: dokku
group: dokku
mode: '0755'
loop:
- /home/dokku/
- /home/data/
- /var/lib/dokku/
- name: Synchronize /home/dokku
synchronize:
src: "{{ source_host }}:/home/dokku/"
dest: /home/dokku/
archive: 'yes'
delete: 'yes'
- name: Synchronize /var/lib/dokku
synchronize:
src: "{{ source_host }}:/var/lib/dokku/"
dest: /var/lib/dokku/
archive: 'yes'
delete: 'yes'
- name: Synchronize /home/data
synchronize:
src: "{{ source_host }}:/home/data/"
dest: /home/data/
archive: 'yes'
delete: 'yes'
- name: Synchronize /home/git
synchronize:
src: "{{ source_host }}:/home/git/"
dest: /home/git/
archive: 'yes'
delete: 'yes'
- name: List Dokku apps
command: dokku apps:list
- name: Patch URLs in Dokku configuration files
find:
paths:
- /home/dokku/
patterns: ['VHOST', 'URLS']
recurse: 'yes'
register: dokku_config_files
- name: Replace source host with destination host in configuration files
lineinfile:
path: "{{ item.path }}"
regexp: "{{ source_host }}"
line: "{{ destination_host }}"
loop: "{{ dokku_config_files.files }}"
- name: Display success message
debug:
msg: "SUCCESS"

194
playbook2.yml Normal file
View file

@ -0,0 +1,194 @@
---
- name: Dokku migration playbook
hosts: localhost
gather_facts: no
vars_files:
- config.yml
tasks:
- name: Create temporary directory for SSH keypair
tempfile:
state: directory
suffix: dokku_sync
register: temp_dir
- name: Generate SSH keypair
community.crypto.openssh_keypair:
path: "{{ temp_dir.path }}/dokku_sync_migration"
type: ed25519
owner: "{{ lookup('env', 'USER') }}"
group: "{{ lookup('env', 'USER') }}"
mode: '0600'
- name: Handle Source Server
hosts: source
gather_facts: yes
vars_files:
- config.yml
tasks:
- name: Get list of Dokku MariaDB services
shell: dokku mariadb:list | tail -n+2
register: mariadb_services
- name: Get list of Dokku PostgreSQL services
shell: dokku postgres:list | tail -n+2
register: postgres_services
- name: Get list of Dokku Redis services
shell: dokku redis:list | tail -n+2
register: redis_services
- name: Get list of Dokku MongoDB services
shell: dokku mongo:list | tail -n+2
register: mongo_services
- name: Save Dokku service lists to disk
copy:
content: |
mariadb_services: {{ mariadb_services.stdout_lines }}
postgres_services: {{ postgres_services.stdout_lines }}
redis_services: {{ redis_services.stdout_lines }}
mongo_services: {{ mongo_services.stdout_lines }}
dest: /tmp/dokku_services.yml
- name: Stop all Dokku apps
command: dokku ps:stop --all
- name: Stop all MariaDB services
command: dokku mariadb:stop {{ item }}
loop: "{{ mariadb_services.stdout_lines }}"
- name: Stop all PostgreSQL services
command: dokku postgres:stop {{ item }}
loop: "{{ postgres_services.stdout_lines }}"
- name: Stop all Redis services
command: dokku redis:stop {{ item }}
loop: "{{ redis_services.stdout_lines }}"
- name: Stop all MongoDB services
command: dokku mongo:stop {{ item }}
loop: "{{ mongo_services.stdout_lines }}"
- name: Stop Docker service
service:
name: docker
state: stopped
- name: Stop Docker socket service
service:
name: docker.socket
state: stopped
- name: Fetch Dokku service lists to local
fetch:
src: /tmp/dokku_services.yml
dest: /tmp/dokku_services.yml
flat: yes
- name: Handle Destination Server
hosts: destination
gather_facts: yes
vars_files:
- config.yml
tasks:
- name: Copy Dokku service lists to destination
copy:
src: /tmp/dokku_services.yml
dest: /tmp/dokku_services.yml
- name: Load Dokku service lists
include_vars:
file: /tmp/dokku_services.yml
- name: Stop all Dokku apps
command: dokku ps:stop --all
- name: Stop Docker service
service:
name: docker
state: stopped
- name: Stop Docker socket service
service:
name: docker.socket
state: stopped
- name: Create necessary directories
file:
path: "{{ item }}"
state: directory
owner: dokku
group: dokku
mode: '0755'
loop:
- /home/dokku/
- /home/data/
- /var/lib/dokku/
- name: Synchronize /home/dokku
synchronize:
src: "{{ source_host }}:/home/dokku/"
dest: /home/dokku/
archive: yes
delete: yes
- name: Synchronize /var/lib/dokku
synchronize:
src: "{{ source_host }}:/var/lib/dokku/"
dest: /var/lib/dokku/
archive: yes
delete: yes
- name: Synchronize /home/data
synchronize:
src: "{{ source_host }}:/home/data/"
dest: /home/data/
archive: yes
delete: yes
- name: Synchronize /home/git
synchronize:
src: "{{ source_host }}:/home/git/"
dest: /home/git/
archive: yes
delete: yes
- name: Start all MariaDB services
command: dokku mariadb:start {{ item }}
loop: "{{ mariadb_services }}"
- name: Start all PostgreSQL services
command: dokku postgres:start {{ item }}
loop: "{{ postgres_services }}"
- name: Start all Redis services
command: dokku redis:start {{ item }}
loop: "{{ redis_services }}"
- name: Start all MongoDB services
command: dokku mongo:start {{ item }}
loop: "{{ mongo_services }}"
- name: List Dokku apps
command: dokku apps:list
- name: Patch URLs in Dokku configuration files
find:
paths:
- /home/dokku/
patterns: ['VHOST', 'URLS']
recurse: yes
register: dokku_config_files
- name: Replace source host with destination host in configuration files
lineinfile:
path: "{{ item.path }}"
regexp: "{{ source_host }}"
line: "{{ destination_host }}"
loop: "{{ dokku_config_files.files }}"
- name: Display success message
debug:
msg: "SUCCESS"