From da3797c6213823f14ea917d2dc9f190624aaa7bd Mon Sep 17 00:00:00 2001 From: transcaffeine Date: Fri, 27 Jun 2025 23:25:43 +0200 Subject: [PATCH] feat(sharkey): add ansible role for deployment --- README.md | 3 + galaxy.yml | 1 + playbooks/sharkey.yml | 6 ++ roles/sharkey/README.md | 11 ++++ roles/sharkey/defaults/main/compose.yml | 39 +++++++++++ roles/sharkey/defaults/main/config.yml | 30 +++++++++ roles/sharkey/defaults/main/container.yml | 47 ++++++++++++++ roles/sharkey/defaults/main/main.yml | 9 +++ roles/sharkey/defaults/main/user.yml | 10 +++ roles/sharkey/tasks/check.yml | 14 ++++ .../tasks/configure-docker-compose.yml | 35 ++++++++++ roles/sharkey/tasks/configure-docker.yml | 8 +++ roles/sharkey/tasks/configure.yml | 64 +++++++++++++++++++ roles/sharkey/tasks/deploy-docker-compose.yml | 14 ++++ roles/sharkey/tasks/main.yml | 12 ++++ roles/sharkey/vars/main.yml | 6 ++ 16 files changed, 309 insertions(+) create mode 100644 playbooks/sharkey.yml create mode 100644 roles/sharkey/README.md create mode 100644 roles/sharkey/defaults/main/compose.yml create mode 100644 roles/sharkey/defaults/main/config.yml create mode 100644 roles/sharkey/defaults/main/container.yml create mode 100644 roles/sharkey/defaults/main/main.yml create mode 100644 roles/sharkey/defaults/main/user.yml create mode 100644 roles/sharkey/tasks/check.yml create mode 100644 roles/sharkey/tasks/configure-docker-compose.yml create mode 100644 roles/sharkey/tasks/configure-docker.yml create mode 100644 roles/sharkey/tasks/configure.yml create mode 100644 roles/sharkey/tasks/deploy-docker-compose.yml create mode 100644 roles/sharkey/tasks/main.yml create mode 100644 roles/sharkey/vars/main.yml diff --git a/README.md b/README.md index aa825b2..70d0e0a 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ available. - [`mastodon`](roles/mastodon/README.md): deployment using a container based setup, able to use webfinger delegation. +- [`sharkey`](roles/sharkey/README.md): deployment of sharkey, a misskey- + fork with full mastodon API compatability. + ## License [CNPLv7+](LICENSE.md): Cooperative Nonviolent Public License diff --git a/galaxy.yml b/galaxy.yml index 2e845fa..75feda8 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -15,5 +15,6 @@ repository: https://git.finally.coffee/finallycoffee/fediverse issues: https://codeberg.org/finallycoffee/ansible-collection-fediverse/issues tags: - fediwall + - sharkey - gotosocial - mastodon diff --git a/playbooks/sharkey.yml b/playbooks/sharkey.yml new file mode 100644 index 0000000..93e879e --- /dev/null +++ b/playbooks/sharkey.yml @@ -0,0 +1,6 @@ +--- +- name: Deploy sharkey + hosts: "{{ sharkey_hosts | default('sharkey') }}" + become: "{{ sharkey_become | default(false) }}" + roles: + - role: finallycoffee.fediverse.sharkey diff --git a/roles/sharkey/README.md b/roles/sharkey/README.md new file mode 100644 index 0000000..fd5c097 --- /dev/null +++ b/roles/sharkey/README.md @@ -0,0 +1,11 @@ +# `finallycoffee.fediverse.sharkey` ansible role + +## Configuration + +## Behind a proxy + +The ansible role itself will respect system proxies (in the env var `HTTP_PROXY`/`https_proxy`). + +To use this role with a registry like Artifactory or Nexus3, +set `sharkey_repo_server` to your registry server with full +protocol, hostname, port. For example `sharkey_repo_server: "https://my.orgs.registry.local:8443/sharkey-internet-proxy/"` diff --git a/roles/sharkey/defaults/main/compose.yml b/roles/sharkey/defaults/main/compose.yml new file mode 100644 index 0000000..51422e5 --- /dev/null +++ b/roles/sharkey/defaults/main/compose.yml @@ -0,0 +1,39 @@ +--- +sharkey_compose_state: "{{ sharkey_state }}" +sharkey_compose_project_name: "sharkey" +sharkey_compose_project_src: "{{ sharkey_config_dir }}" +sharkey_compose_upstream_file: "{{ sharkey_compose_project_src }}/compose.upstream.yml" +sharkey_compose_file: "{{ sharkey_compose_project_src }}/compose.yml" +sharkey_compose_build: >-2 + {{ (sharkey_container_image_source == 'pull') | ternary('never', 'policy') }} + +sharkey_compose_redis_dir: "{{ sharkey_data_dir }}/redis" +sharkey_compose_database_dir: "{{ sharkey_data_dir }}/postgres" + +sharkey_repo_server: "https://activitypub.software" +sharkey_repo_path: "Transfem-org/Sharkey" +sharkey_repo_tag: "{{ sharkey_version }}" +sharkey_compose_file_url: >-2 + {{ sharkey_repo_server }}/{{ sharkey_repo_path }}/-/raw/{{ sharkey_version }}/compose_example.yml?ref_type=tags +sharkey_compose_file_overrides: + services: + web: + image: "{{ sharkey_container_image }}" + volumes: + - "{{ sharkey_file_dir }}:/sharkey/files:rw" + - "{{ sharkey_config_file }}:/sharkey/.config/default.yaml:ro" + - "{{ sharkey_container_env_file }}:/sharkey/.config/docker.env:ro" + db: + env_file: "{{ sharkey_container_env_file }}" + volumes: + - "{{ sharkey_compose_database_dir }}:/var/lib/postgresql/data:rw" + redis: + volumes: + - "{{ sharkey_compose_redis_dir }}:/data:rw" + # override net segment? +sharkey_compose_file_contents: >-2 + {{ + (sharkey_compose_upstream_file_contents['content'] | b64decode | from_yaml) + | combine(sharkey_compose_file_overrides, recursive=True) + | to_nice_yaml(indent=4) + }} diff --git a/roles/sharkey/defaults/main/config.yml b/roles/sharkey/defaults/main/config.yml new file mode 100644 index 0000000..8f8fe7d --- /dev/null +++ b/roles/sharkey/defaults/main/config.yml @@ -0,0 +1,30 @@ +--- +sharkey_config_url: ~ +sharkey_config_setup_password: ~ +sharkey_config_postgres_user: misskey +sharkey_config_postgres_password: "insecure_please_change_me!" +sharkey_config_postgres_db: misskey +sharkey_config_postgres_host: db +sharkey_config_postgres_port: 5432 +sharkey_config_postgres_db_url: >-2 + postgres://{{ sharkey_config_postgres_user }}:{{ sharkey_config_postgres_password }}@{{ sharkey_config_postgres_host }}:{{ sharkey_config_postgres_port }}/{{ sharkey_config_postgres_db }} + +sharkey_config: ~ +sharkey_config_file_overrides: + url: "{{ sharkey_config_url }}" + db: + host: "{{ sharkey_config_postgres_host }}" + db: "{{ sharkey_config_postgres_db }}" + user: "{{ sharkey_config_postgres_user }}" + pass: "{{ sharkey_config_postgres_password }}" +sharkey_config_file_contents: >-2 + {{ + (sharkey_config_upstream_file_contents['content'] | b64decode | from_yaml) + | combine(sharkey_config_file_overrides, recursive=True) + | combine(sharkey_config | default({}, true), recursive=True) + | to_nice_yaml(indent=4) + }} +sharkey_config_upstream_file: "{{ sharkey_config_dir }}/config.upstream.yaml" +sharkey_config_file: "{{ sharkey_config_dir }}/default.yaml" +sharkey_config_upstream_file_url: >-2 + {{ sharkey_repo_server }}/{{ sharkey_repo_path }}/-/raw/{{ sharkey_version }}/.config/docker_example.yml?ref=tags diff --git a/roles/sharkey/defaults/main/container.yml b/roles/sharkey/defaults/main/container.yml new file mode 100644 index 0000000..3b1bf95 --- /dev/null +++ b/roles/sharkey/defaults/main/container.yml @@ -0,0 +1,47 @@ +--- +sharkey_container_name: sharkey +sharkey_container_image_registry: "registry.activitypub.software" +sharkey_container_iamge_namespace: "transfem-org" +sharkey_container_image_name: "sharkey" +sharkey_container_image_repository: >-2 + {{ + [ + sharkey_container_image_registry | default([], true), + sharkey_container_iamge_namespace | default([], true), + sharkey_container_image_name + ] | flatten | join('/') + }} +sharkey_container_image_tag: ~ +sharkey_container_image_source: pull +sharkey_container_image_force_source: >-2 + {{ sharkey_container_image_tag | default(false, true) | bool }} +sharkey_container_image: >-2 + {{ + [ + sharkey_container_image_repository, + sharkey_container_image_tag | default(sharkey_version, true) + ] | join(':') + }} +sharkey_container_default_env: + MISSKEY_URL: "{{ sharkey_config_url }}" + POSTGRES_USER: "{{ sharkey_config_postgres_user }}" + POSTGRES_PASSWORD: "{{ sharkey_config_postgres_password }}" + POSTGRES_DB: "{{ sharkey_config_postgres_db }}" + DATABASE_URL: >-2 + {{ + (sharkey_config_postgres_user | default(false, true)) + | ternary(sharkey_config_postgres_db_url, '') + }} +sharkey_container_env: ~ +sharkey_container_merged_env: >-2 + {{ + sharkey_container_default_env | default({}, true) + | combine(sharkey_container_env | default({}, true), recursive=True) + }} +sharkey_container_env_file_contents: |2 + {% for entry in sharkey_container_merged_env | dict2items %} + {% if entry['value'] is string and entry['value'] | length > 0 %} + {{ entry['key'] }}={{ entry['value'] }} + {% endif %} + {% endfor %} +sharkey_container_env_file: "{{ sharkey_config_dir }}/docker.env" diff --git a/roles/sharkey/defaults/main/main.yml b/roles/sharkey/defaults/main/main.yml new file mode 100644 index 0000000..3282e98 --- /dev/null +++ b/roles/sharkey/defaults/main/main.yml @@ -0,0 +1,9 @@ +--- +sharkey_user: sharkey +sharkey_version: "2025.4.3" +sharkey_config_dir: "/etc/sharkey" +sharkey_data_dir: "/var/lib/sharkey" +sharkey_file_dir: "{{ sharkey_data_dir }}/files" + +sharkey_state: present +sharkey_deployment_method: "docker-compose" diff --git a/roles/sharkey/defaults/main/user.yml b/roles/sharkey/defaults/main/user.yml new file mode 100644 index 0000000..ff4aa7f --- /dev/null +++ b/roles/sharkey/defaults/main/user.yml @@ -0,0 +1,10 @@ +--- +sharkey_user_system: true +sharkey_user_create_home: false +sharkey_user_groups: ~ +sharkey_user_append_groups: >-2 + {{ sharkey_user_groups | default(omit, true) }} +sharkey_user_uid: >-2 + {{ sharkey_user_info.uid | default(sharkey_user) }} +sharkey_user_gid: >-2 + {{ sharkey_user_info.group | default(sharkey_user) }} diff --git a/roles/sharkey/tasks/check.yml b/roles/sharkey/tasks/check.yml new file mode 100644 index 0000000..f829304 --- /dev/null +++ b/roles/sharkey/tasks/check.yml @@ -0,0 +1,14 @@ +--- +- name: Ensure 'sharkey_state' is valid + ansible.builtin.fail: + msg: >-2 + Unsupported sharkey_state '{{ sharkey_state }}'. + Supported values are {{ sharkey_states | join(', ') }} + when: sharkey_state not in sharkey_states + +- name: Ensure 'sharkey_deployment_method' is valid + ansible.builtin.fail: + msg: >-2 + Unsupported sharkey_deployment_method '{{ sharkey_deployment_method }}. + Supported values are {{ sharkey_deployment_methods | join(', ') }} + when: sharkey_deployment_method not in sharkey_deployment_methods diff --git a/roles/sharkey/tasks/configure-docker-compose.yml b/roles/sharkey/tasks/configure-docker-compose.yml new file mode 100644 index 0000000..f8d9b02 --- /dev/null +++ b/roles/sharkey/tasks/configure-docker-compose.yml @@ -0,0 +1,35 @@ +--- +- name: Ensure directories for compose services are {{ sharkey_state }} + ansible.builtin.file: + name: "{{ file.path }}" + state: "{{ (sharkey_state == 'present') | ternary('directory', 'absent') }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0750" + loop: + - path: "{{ sharkey_compose_redis_dir }}" + - path: "{{ sharkey_compose_database_dir }}" + loop_control: + loop_var: file + label: "{{ file.path }}" + +- name: Ensure compose files are downloaded + ansible.builtin.get_url: + url: "{{ sharkey_compose_file_url }}" + dest: "{{ sharkey_compose_upstream_file }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0444" + +- name: Read compose file contents + ansible.builtin.slurp: + src: "{{ sharkey_compose_upstream_file }}" + register: sharkey_compose_upstream_file_contents + +- name: Ensure modified compose file is written + ansible.builtin.copy: + content: "{{ sharkey_compose_file_contents }}" + dest: "{{ sharkey_compose_file }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0644" diff --git a/roles/sharkey/tasks/configure-docker.yml b/roles/sharkey/tasks/configure-docker.yml new file mode 100644 index 0000000..d777805 --- /dev/null +++ b/roles/sharkey/tasks/configure-docker.yml @@ -0,0 +1,8 @@ +--- +- name: Ensure sharkey docker environment is templated + ansible.builtin.copy: + content: "{{ sharkey_container_env_file_contents }}" + dest: "{{ sharkey_container_env_file }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0640" diff --git a/roles/sharkey/tasks/configure.yml b/roles/sharkey/tasks/configure.yml new file mode 100644 index 0000000..4ae9f1b --- /dev/null +++ b/roles/sharkey/tasks/configure.yml @@ -0,0 +1,64 @@ +--- +- name: Ensure sharkey user '{{ sharkey_user }}' is {{ sharkey_state }} + ansible.builtin.user: + name: "{{ sharkey_user }}" + state: "{{ sharkey_state }}" + system: "{{ sharkey_user_system }}" + create_home: "{{ sharkey_user_create_home }}" + groups: "{{ sharkey_user_groups }}" + append: "{{ sharkey_user_append_groups }}" + register: sharkey_user_info + +- name: Ensure sharkey config directory '{{ sharkey_config_dir }}' is {{ sharkey_state }} + ansible.builtin.file: + path: "{{ sharkey_config_dir }}" + state: "{{ (sharkey_state == 'present') | ternary('directory', 'absent') }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0750" + +- name: Ensure sharkey data directory '{{ sharkey_data_dir }}' is {{ sharkey_state }} + ansible.builtin.file: + path: "{{ sharkey_data_dir }}" + state: "{{ (sharkey_state == 'present') | ternary('directory', 'absent') }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0750" + +- name: Ensure sharkey file directory '{{ sharkey_file_dir }}' is {{ sharkey_state }} + ansible.builtin.file: + path: "{{ sharkey_file_dir }}" + state: "{{ (sharkey_state == 'present') | ternary('directory', 'absent') }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0750" + +- name: Ensure sharkey upstream config file is present + ansible.builtin.get_url: + url: "{{ sharkey_config_upstream_file_url }}" + dest: "{{ sharkey_config_upstream_file }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0440" + +- name: Read upstream sharkey config file + ansible.builtin.slurp: + src: "{{ sharkey_config_upstream_file }}" + register: sharkey_config_upstream_file_contents + +- name: Ensure sharkey configuration file is {{ sharkey_state }} + ansible.builtin.copy: + content: "{{ sharkey_config_file_contents }}" + dest: "{{ sharkey_config_file }}" + owner: "{{ sharkey_user_uid }}" + group: "{{ sharkey_user_gid }}" + mode: "0640" + +- name: Run configure steps for deployment using containers + ansible.builtin.include_tasks: + file: "configure-docker.yml" + when: sharkey_deployment_method in ['docker-compose'] + +- name: Configure for {{ sharkey_deployment_method }} + ansible.builtin.include_tasks: + file: "configure-{{ sharkey_deployment_method }}.yml" diff --git a/roles/sharkey/tasks/deploy-docker-compose.yml b/roles/sharkey/tasks/deploy-docker-compose.yml new file mode 100644 index 0000000..0c12f51 --- /dev/null +++ b/roles/sharkey/tasks/deploy-docker-compose.yml @@ -0,0 +1,14 @@ +--- +- name: Ensure sharkey container image '{{ sharkey_container_image }}' is {{ sharkey_state }} + community.docker.docker_image: + name: "{{ sharkey_container_image }}" + state: "{{ sharkey_state }}" + source: "{{ sharkey_container_image_source }}" + force_source: "{{ sharkey_container_image_force_source }}" + +- name: Ensure docker compose project is {{ sharkey_compose_state }} + community.docker.docker_compose_v2: + project_name: "{{ sharkey_compose_project_name }}" + project_src: "{{ sharkey_compose_project_src }}" + state: "{{ sharkey_compose_state }}" + build: "{{ sharkey_compose_build }}" diff --git a/roles/sharkey/tasks/main.yml b/roles/sharkey/tasks/main.yml new file mode 100644 index 0000000..fc3ca77 --- /dev/null +++ b/roles/sharkey/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Check role prerequisites + ansible.builtin.include_tasks: + file: check.yml + +- name: Run common configuration tasks + ansible.builtin.include_tasks: + file: configure.yml + +- name: Deploy using {{ sharkey_deployment_method }} + ansible.builtin.include_tasks: + file: "deploy-{{ sharkey_deployment_method }}.yml" diff --git a/roles/sharkey/vars/main.yml b/roles/sharkey/vars/main.yml new file mode 100644 index 0000000..348169e --- /dev/null +++ b/roles/sharkey/vars/main.yml @@ -0,0 +1,6 @@ +--- +sharkey_states: + - present + - absent +sharkey_deployment_methods: + - "docker-compose"