333 lines
9.8 KiB
YAML
333 lines
9.8 KiB
YAML
---
|
|
- name: Check if Airflow master deployment directory exists
|
|
stat:
|
|
path: "{{ airflow_master_dir }}"
|
|
register: master_dir_stat
|
|
|
|
- name: Ensure Airflow master deployment directory exists
|
|
file:
|
|
path: "{{ airflow_master_dir }}"
|
|
state: directory
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
mode: '0755'
|
|
become: yes
|
|
when: not master_dir_stat.stat.exists
|
|
|
|
- name: Ensure Airflow master configs directory exists
|
|
file:
|
|
path: "{{ airflow_master_dir }}/configs"
|
|
state: directory
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
mode: '0755'
|
|
become: yes
|
|
|
|
- name: Ensure Airflow master config directory exists
|
|
file:
|
|
path: "{{ airflow_master_dir }}/config"
|
|
state: directory
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
mode: '0755'
|
|
become: yes
|
|
|
|
- name: Ensure Airflow operational directories exist with correct permissions
|
|
file:
|
|
path: "{{ airflow_master_dir }}/{{ item }}"
|
|
state: directory
|
|
owner: "{{ airflow_uid }}"
|
|
group: "{{ deploy_group }}"
|
|
mode: '0775'
|
|
become: yes
|
|
loop:
|
|
- "dags"
|
|
- "logs"
|
|
- "plugins"
|
|
- "downloadfiles"
|
|
- "addfiles"
|
|
- "inputfiles"
|
|
|
|
- name: Check if source directories exist
|
|
stat:
|
|
path: "../{{ item }}"
|
|
register: source_dirs
|
|
loop:
|
|
- "airflow/plugins"
|
|
- "airflow/addfiles"
|
|
- "airflow/bgutil-ytdlp-pot-provider"
|
|
|
|
- name: "Log: Syncing Airflow core files"
|
|
debug:
|
|
msg: "Syncing DAGs, configs, and Python source code to the master node."
|
|
|
|
- name: Sync Airflow master files
|
|
synchronize:
|
|
src: "../{{ item }}"
|
|
dest: "{{ airflow_master_dir }}/"
|
|
archive: yes
|
|
recursive: yes
|
|
delete: yes
|
|
rsync_path: "sudo rsync"
|
|
rsync_opts: "{{ rsync_default_opts }}"
|
|
loop:
|
|
- "airflow/Dockerfile"
|
|
- "airflow/Dockerfile.caddy"
|
|
- "airflow/.dockerignore"
|
|
- "airflow/dags"
|
|
- "airflow/inputfiles"
|
|
- "setup.py"
|
|
- "yt_ops_services"
|
|
- "thrift_model"
|
|
- "VERSION"
|
|
- "airflow/update-yt-dlp.sh"
|
|
- "get_info_json_client.py"
|
|
- "proxy_manager_client.py"
|
|
- "utils"
|
|
|
|
- name: Copy custom Python config files to master
|
|
copy:
|
|
src: "../airflow/config/{{ item }}"
|
|
dest: "{{ airflow_master_dir }}/config/{{ item }}"
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
mode: '0644'
|
|
become: yes
|
|
loop:
|
|
- "custom_task_hooks.py"
|
|
- "airflow_local_settings.py"
|
|
|
|
- name: Ensure any existing airflow.cfg directory is removed
|
|
file:
|
|
path: "{{ airflow_master_dir }}/config/airflow.cfg"
|
|
state: absent
|
|
become: yes
|
|
ignore_errors: yes
|
|
|
|
- name: Copy airflow.cfg to master
|
|
copy:
|
|
src: "../airflow/airflow.cfg"
|
|
dest: "{{ airflow_master_dir }}/config/airflow.cfg"
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
mode: '0644'
|
|
become: yes
|
|
|
|
- name: Sync Airflow master config files
|
|
synchronize:
|
|
src: "../airflow/configs/{{ item }}"
|
|
dest: "{{ airflow_master_dir }}/configs/"
|
|
archive: yes
|
|
recursive: yes
|
|
rsync_path: "sudo rsync"
|
|
rsync_opts: "{{ rsync_default_opts }}"
|
|
loop:
|
|
- "nginx.conf"
|
|
- "Caddyfile"
|
|
|
|
- name: Sync optional directories if they exist
|
|
synchronize:
|
|
src: "../{{ item.item }}/"
|
|
dest: "{{ airflow_master_dir }}/{{ item.item | basename }}/"
|
|
archive: yes
|
|
recursive: yes
|
|
delete: yes
|
|
rsync_path: "sudo rsync"
|
|
rsync_opts: "{{ rsync_default_opts }}"
|
|
loop: "{{ source_dirs.results }}"
|
|
when: item.stat.exists
|
|
|
|
- name: Sync pangramia thrift files
|
|
synchronize:
|
|
src: "../thrift_model/gen_py/pangramia/"
|
|
dest: "{{ airflow_master_dir }}/pangramia/"
|
|
archive: yes
|
|
recursive: yes
|
|
delete: yes
|
|
rsync_path: "sudo rsync"
|
|
rsync_opts: "{{ rsync_default_opts }}"
|
|
|
|
- name: Template docker-compose file for master
|
|
template:
|
|
src: "{{ playbook_dir }}/../airflow/configs/docker-compose-master.yaml.j2"
|
|
dest: "{{ airflow_master_dir }}/configs/docker-compose-master.yaml"
|
|
mode: "{{ file_permissions }}"
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
become: yes
|
|
|
|
- name: Template Redis connection file
|
|
template:
|
|
src: "../airflow/config/redis_default_conn.json.j2"
|
|
dest: "{{ airflow_master_dir }}/config/redis_default_conn.json"
|
|
mode: "{{ file_permissions }}"
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
become: yes
|
|
|
|
- name: Template Minio connection file for master
|
|
template:
|
|
src: "../airflow/config/minio_default_conn.json.j2"
|
|
dest: "{{ airflow_master_dir }}/config/minio_default_conn.json"
|
|
mode: "{{ file_permissions }}"
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
become: yes
|
|
|
|
- name: Ensure config directory is group-writable for Airflow initialization
|
|
file:
|
|
path: "{{ airflow_master_dir }}/config"
|
|
state: directory
|
|
mode: '0775'
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
become: yes
|
|
|
|
- name: Ensure airflow.cfg is group-writable for Airflow initialization
|
|
file:
|
|
path: "{{ airflow_master_dir }}/config/airflow.cfg"
|
|
state: file
|
|
mode: '0664'
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
become: yes
|
|
|
|
- name: Create symlink for docker-compose.yaml
|
|
file:
|
|
src: "{{ airflow_master_dir }}/configs/docker-compose-master.yaml"
|
|
dest: "{{ airflow_master_dir }}/docker-compose.yaml"
|
|
state: link
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
force: yes
|
|
follow: no
|
|
|
|
- name: Ensure correct permissions for build context
|
|
file:
|
|
path: "{{ airflow_master_dir }}"
|
|
state: directory
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
recurse: yes
|
|
become: yes
|
|
|
|
- name: Ensure postgres-data directory exists on master and has correct permissions
|
|
file:
|
|
path: "{{ airflow_master_dir }}/postgres-data"
|
|
state: directory
|
|
owner: "999" # UID for the 'postgres' user in the official postgres image
|
|
group: "999" # GID for the 'postgres' group in the official postgres image
|
|
mode: '0700'
|
|
become: yes
|
|
|
|
- name: Set proper ownership and permissions on master logs directory contents
|
|
shell: |
|
|
chown -R {{ airflow_uid }}:{{ deploy_group }} {{ airflow_master_dir }}/logs
|
|
find {{ airflow_master_dir }}/logs -type d -exec chmod g+rws {} +
|
|
find {{ airflow_master_dir }}/logs -type f -exec chmod g+rw {} +
|
|
become: yes
|
|
|
|
- name: Verify Dockerfile exists in build directory
|
|
stat:
|
|
path: "{{ airflow_master_dir }}/Dockerfile"
|
|
register: dockerfile_stat
|
|
|
|
- name: Fail if Dockerfile is missing
|
|
fail:
|
|
msg: "Dockerfile not found in {{ airflow_master_dir }}. Cannot build image."
|
|
when: not dockerfile_stat.stat.exists
|
|
|
|
- name: "Log: Building Airflow Docker image"
|
|
debug:
|
|
msg: "Building the main Airflow Docker image ({{ airflow_image_name }}) locally on the master node. This may take a few minutes."
|
|
|
|
- name: Build Airflow master image
|
|
community.docker.docker_image:
|
|
name: "{{ airflow_image_name }}"
|
|
build:
|
|
path: "{{ airflow_master_dir }}"
|
|
dockerfile: "Dockerfile" # Explicitly specify the Dockerfile name
|
|
source: build
|
|
force_source: true
|
|
when: not fast_deploy | default(false)
|
|
|
|
- name: "Log: Preparing assets for Caddy image"
|
|
debug:
|
|
msg: "Extracting static assets from the Airflow image to build the Caddy reverse proxy."
|
|
when: not fast_deploy | default(false)
|
|
|
|
- name: Prepare Caddy asset extraction directory
|
|
file:
|
|
path: "{{ airflow_master_dir }}/caddy_build_assets"
|
|
state: "{{ item }}"
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
mode: '0755'
|
|
loop:
|
|
- absent
|
|
- directory
|
|
become: yes
|
|
when: not fast_deploy | default(false)
|
|
|
|
- name: Ensure subdirectories exist with correct permissions
|
|
file:
|
|
path: "{{ airflow_master_dir }}/caddy_build_assets/{{ item }}"
|
|
state: directory
|
|
owner: "{{ ssh_user }}"
|
|
group: "{{ deploy_group }}"
|
|
mode: '0755'
|
|
loop:
|
|
- "appbuilder"
|
|
- "dist"
|
|
become: yes
|
|
when: not fast_deploy | default(false)
|
|
|
|
- name: Extract static assets from Airflow image for Caddy build
|
|
shell: |
|
|
set -e
|
|
CONTAINER_ID=$(docker create {{ airflow_image_name }})
|
|
# Dynamically find paths inside the container
|
|
APPBUILDER_PATH=$(docker run --rm --entrypoint "" {{ airflow_image_name }} python -c 'import os, flask_appbuilder; print(os.path.join(os.path.dirname(flask_appbuilder.__file__), "static", "appbuilder"))')
|
|
AIRFLOW_DIST_PATH=$(docker run --rm --entrypoint "" {{ airflow_image_name }} python -c 'import os, airflow; print(os.path.join(os.path.dirname(airflow.__file__), "www/static/dist"))')
|
|
# Copy assets from container to host
|
|
docker cp "${CONTAINER_ID}:${APPBUILDER_PATH}/." "./caddy_build_assets/appbuilder"
|
|
docker cp "${CONTAINER_ID}:${AIRFLOW_DIST_PATH}/." "./caddy_build_assets/dist"
|
|
docker rm -f $CONTAINER_ID
|
|
# Pre-compress assets
|
|
find ./caddy_build_assets/appbuilder -type f -print0 | xargs -0 gzip -k -9
|
|
find ./caddy_build_assets/dist -type f -print0 | xargs -0 gzip -k -9
|
|
args:
|
|
chdir: "{{ airflow_master_dir }}"
|
|
executable: /bin/bash
|
|
become: yes
|
|
register: asset_extraction
|
|
changed_when: asset_extraction.rc == 0
|
|
when: not fast_deploy | default(false)
|
|
|
|
- name: "Log: Building Caddy reverse proxy image"
|
|
debug:
|
|
msg: "Building the Caddy image (pangramia/ytdlp-ops-caddy:latest) to serve static assets."
|
|
|
|
- name: Build Caddy image
|
|
community.docker.docker_image:
|
|
name: "pangramia/ytdlp-ops-caddy:latest"
|
|
build:
|
|
path: "{{ airflow_master_dir }}"
|
|
dockerfile: "Dockerfile.caddy"
|
|
source: build
|
|
force_source: true
|
|
when: not fast_deploy | default(false)
|
|
|
|
- name: "Log: Starting Airflow services"
|
|
debug:
|
|
msg: "Starting Airflow core services (webserver, scheduler, etc.) on the master node using docker-compose."
|
|
|
|
- name: Start Airflow master service
|
|
community.docker.docker_compose_v2:
|
|
project_src: "{{ airflow_master_dir }}"
|
|
files:
|
|
- "configs/docker-compose-master.yaml"
|
|
state: present
|
|
remove_orphans: true
|
|
pull: "{{ 'never' if fast_deploy | default(false) else 'missing' }}"
|