Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • funkwhale/ansible
  • lfuelling/ansible
  • kevit/ansible
  • theorangepotato/ansible
  • popindavibe/ansible
  • xenofem/ansible
  • kippix/ansible
  • half-duplex/ansible
  • barslmn/ansible
  • sofubi/ansible
  • DannyBoy/ansible
11 results
Select Git revision
Show changes
Commits on Source (95)
ro
---
stages:
- test
- deploy
variables:
LATEST_VERSION_URL: https://docs.funkwhale.audio/latest.txt
pre-commit:
stage: test
image: python:3.12
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
PRE_COMMIT_HOME: "$CI_PROJECT_DIR/.cache/pre-commit"
cache:
paths:
- $CI_PROJECT_DIR/.cache/pip
- $CI_PROJECT_DIR/.cache/pre-commit
before_script:
- pip3 install pre-commit
script:
- pre-commit run --all --color=always --show-diff-on-failure
test-install-script:
stage: test
image: $TEST_IMAGE
parallel:
matrix:
- TEST_IMAGE: ["ubuntu:focal", "ubuntu:jammy", "debian:11", "debian:12"]
interruptible: true
variables:
FUNKWHALE_CLI_USER_PASSWORD: supersecurepassword
before_script:
- apt-get update && apt-get install -y curl
- |
echo "Retrieving latest version from $LATEST_VERSION_URL"
funkwhale_version=$(curl -sfL $LATEST_VERSION_URL || true)
if [ -z "$funkwhale_version" ]; then
echo "Could not retrieve latest version!"
exit 1
fi
- echo "Latest version is $funkwhale_version"
- sed -i "0,/funkwhale_version_placeholder/{s/funkwhale_version_placeholder/$funkwhale_version/}" install.sh
script:
- |
set -x
export ANSIBLE_FUNKWHALE_ROLE_PATH=$(pwd)
printf 'test.deployment\ntest1234\ncontact@test.deployment\nY\nN\n\n\n\N\n\n\n' | bash install.sh
tags:
- docker
test-install-script-develop:
extends: test-install-script
variables:
FUNKWHALE_VERSION: develop
before_script:
- apt-get update && apt-get install -y curl
pages:
stage: deploy
image: buildpack-deps
variables:
LATEST_VERSION_URL: https://docs.funkwhale.audio/latest.txt
script:
- |
echo "Retrieving latest version from $LATEST_VERSION_URL"
......
---
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: check-symlinks
- id: destroyed-symlinks
- id: check-yaml
- id: check-merge-conflict
- id: end-of-file-fixer
- id: mixed-line-ending
- id: trailing-whitespace
- id: requirements-txt-fixer
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
hooks:
- id: prettier
files: \.(md|yml|yaml|json)$
- repo: https://github.com/codespell-project/codespell
rev: v2.2.1
hooks:
- id: codespell
args: [--ignore-words=.codespellignore]
---
extends: default
rules:
......
# Contribute to funkwhale/ansible
Check out the [Funkwhale contributing guide](https://dev.funkwhale.audio/funkwhale/funkwhale/-/blob/develop/CONTRIBUTING.md) for information about how to contribute to the Funkwhale project.
## Development environment
### Pre-commit
The [`pre-commit`](https://pre-commit.com/) tool is used to ensure that the files you commit are properly formatted, follow best practice, and don't contain syntax or spelling errors.
You can install and setup pre-commit using the [quick-start guide on the pre-commit documentation](https://pre-commit.com/#quick-start). Make sure to [install pre-commit](https://pre-commit.com/#1-install-pre-commit) and [setup the git pre-commit hook](https://pre-commit.com/#3-install-the-git-hook-scripts) so pre-commit runs before you commit any changes to the repository.
This diff is collapsed.
Funkwhale ansible role
======================
# Funkwhale ansible role
An ansible role to install and update [Funkwhale](https://funkwhale.audio).
Summary
-------
## Summary
Using this role, you can install and upgrade a Funkwhale pod, closely matching our [standard installation guide](https://docs.funkwhale.audio/installation/debian.html). The role will take care of:
......@@ -13,8 +11,7 @@ Using this role, you can install and upgrade a Funkwhale pod, closely matching o
- Install and configure Funkwhale and it's dependencies
- Install and configure a SSL certificate with Let's Encrypt (optional)
Philosophy
----------
## Philosophy
This role strives to:
......@@ -25,13 +22,12 @@ This role strives to:
- Allow running multiple Funkwhale instances on the same host
- Avoid messing with existing software and apps on the server
Installation and usage
----------------------
## Installation and usage
Install ansible:
```
pip install --user ansible
pip3 install --user ansible
```
Create a directory for ansible files:
......@@ -76,7 +72,6 @@ Add the following to `playbook.yml`:
roles:
- role: funkwhale
funkwhale_hostname: yourdomain.funkwhale
funkwhale_version: 0.18.3
funkwhale_letsencrypt_email: contact@youremail.com
```
......@@ -94,81 +89,96 @@ Launch the installation (in check mode, so nothing is applied):
```
ansible-playbook --ask-become-pass -i inventory.ini playbook.yml --check --diff
```
*On some hosts, you may need to install the `python-apt` package for check mode to work*.
This command will show you the changes that would be applied to your system. If you are confortable with them,
_On some hosts, you may need to install the `python-apt` package for check mode to work_.
This command will show you the changes that would be applied to your system. If you are comfortable with them,
rerun the same command without the `--check` flag.
Once installation is complete, run `/srv/funkwhale/virtualenv/bin/funkwhale-manage createsuperuser` to create your admin account.
Role Variables
--------------
## Role Variables
**Required variables**
| name | Example | Description |
| ----------------------------- | ----------------------------- | --------------------------------------------- |
| ----------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `funkwhale_hostname` | `yourdomain.funkwhale` | The domain name of your Funkwhale pod |
| `funkwhale_version` | `0.18.3` | The version to install/upgrade to. You can also use `develop` to run the development branch |
| `funkwhale_letsencrypt_email` | `contact@youremail.com` | The email to associate with your Let's Encrypt certificate (not needed if you set `funkwhale_letsencrypt_enabled: false`, see below) |
**Optional variables**
| name | Default | Description |
| --------------------------------------- | ----------------------------- | --------------------------------------------- |
| `funkwhale_api_ip` | `127.0.0.1` | IP adress to bind the Funkwhale server to |
| `funkwhale_api_port` | `5000` | Port to bind the Funkwhale server to |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `funkwhale_api_ip` | `127.0.0.1` | IP address with which to bind the Funkwhale server |
| `funkwhale_api_port` | `5000` | Port with which to bind the Funkwhale server |
| `funkwhale_config_path` | `/srv/funkwhale/config` | Path to Funkwhale's configuration directory |
| `funkwhale_nginx_csp_policy` | `"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:"` | Content-Security-Policy header to us. You will need to tweak this if you're serving media files from a separate domain. |
| `funkwhale_database_managed` | `true` | If `true`, the role will manage the database server and Funkwhale's database |
| `funkwhale_database_name` | `funkwhale` | Name of the Funkwhale database to use |
| `funkwhale_database_user` | `funkwhale` | Postgresql username to login as |
| `funkwhale_env_vars` | `[]` | List of environment variables to append to the generated `.env` file. Example: `["AWS_ACCESS_KEY_ID=myawsid", "AWS_SECRET_ACCESS_KEY=myawskey"]` |
| `funkwhale_external_storage_enabled` | `false` | If `true`, set up the proper configuration to use an extenal storage for media files |
| `funkwhale_install_path` | `/srv/funkwhale` | Path were frontend, api and virtualenv files should be stored (**no trailing slash**) |
| `funkwhale_external_storage_enabled` | `false` | If `true`, set up the proper configuration to use an external storage for media files |
| `funkwhale_disable_django_admin` | `false` | If `true`, returns a 403 (Forbidden) for `/api/admin` |
| `funkwhale_gunicorn_extra_args` | `""` | Additional args to pass to gunicorn in the `funkwhale-server.service` file. Refer to [gunicorn's documentation](https://docs.gunicorn.org/en/stable/settings.html) for possible options |
| `funkwhale_install_path` | `/srv/funkwhale` | Path where frontend, api and virtualenv files should be stored (**no trailing slash**) |
| `funkwhale_letsencrypt_certbot_flags` | `null` | Additional flags to pass to `certbot` |
| `funkwhale_letsencrypt_enabled` | `true` | If `true`, will configure SSL with certbot and Let's Encrypt |
| `funkwhale_media_path` | `/srv/funkwhale/data/media` | Path were audio and uploaded files should be stored (**no trailing slash**) |
| `funkwhale_media_path` | `/srv/funkwhale/data/media` | Path where audio and uploaded files should be stored (**no trailing slash**) |
| `funkwhale_music_path` | `/srv/funkwhale/data/music` | Path to your existing music library, to use with [CLI import](https://docs.funkwhale.audio/admin/importing-music.html) (**no trailing slash**) |
| `funkwhale_nginx_additional_config` | `""` | Additional nginx configuration to add to the Funkwhale `server{}` block |
| `funkwhale_nginx_managed` | `true` | If `true`, will install and configure nginx |
| `funkwhale_nginx_tls_termination` | `true` | If `false`, disable SSL in nginx |
| `funkwhale_nginx_tls_configure_ciphers` | `true` | Set TLS ciphers, curves, etc, overriding any settings in http{} |
| `funkwhale_nginx_max_body_size` | `100M` | Value of nginx's `max_body_size` parameter to use |
| `funkwhale_protocol` | `https` | If set to `https`, will configure Funkwhale and Nginx to work behind HTTPS. Use `http` to completely disable SSL. |
| `funkwhale_redis_managed` | `true` | If `true`, will install and configure redis |
| `funkwhale_ssl_cert_path` | `` | Path to an existing SSL certificate to use (use in combination with `funkwhale_letsencrypt_enabled: false`) |
| `funkwhale_ssl_key_path` | `` | Path to an existing SSL key to use (use in combination with `funkwhale_letsencrypt_enabled: false`) |
| `funkwhale_static_path` | `/srv/funkwhale/data/static` | Path were Funkwhale static files should be stored |
| `funkwhale_ssl_cert_path` | `""` | Path to an existing SSL certificate to use (use in combination with `funkwhale_letsencrypt_enabled: false`) |
| `funkwhale_ssl_key_path` | `""` | Path to an existing SSL key to use (use in combination with `funkwhale_letsencrypt_enabled: false`) |
| `funkwhale_static_path` | `/srv/funkwhale/data/static` | Path where Funkwhale static files should be stored |
| `funkwhale_systemd_managed` | `true` | If `true`, will configure Funkwhale systemd services |
| `funkwhale_systemd_after` | `redis.service postgresql.service` | Configuration used for Systemd `After=` directive. Modify it if you have a database or redis server on a separate host |
| `funkwhale_systemd_service_name` | `funkwhale` | Name of the generated Systemd service, e.g when calling `systemctl start <xxx>` |
| `funkwhale_username` | `funkwhale` | Username of the system user and owner of Funkwhale data, files and configuration |
| `funkwhale_version` | `latest` | The version to install/upgrade to. You can also use `develop` to run the development branch |
| `funkwhale_custom_pip_packages` | `[]` | A list of additional python packages to download |
| `funkwhale_custom_settings` | `""` | Some Python code to append to `api/config/settings/production.py`. Use `funkwhale_custom_settings: \| ` for multiline code. |
**Installing from source**
If you want to install Funkwhale from source (e.g to try a nonproduction branch, or use your own fork), you use the
following variables:
| name | Default | Description |
| ------------------------------- | ----------------------------------------------------- | --------------------------------------- |
| `funkwhale_install_from_source` | `false` | Install and build Funkwhale from source |
| `funkwhale_source_url` | `https://dev.funkwhale.audio/funkwhale/funkwhale.git` | URL to the git repository to use |
Use the `funkwhale_version` variable to control the git tag/branch to checkout.
Supported platforms
-------------------
## Supported platforms
- Debian 9
- More to come
Dependencies
------------
## Dependencies
This roles has no other dependencies.
Tests
-----
## Tests
This role is tested using [molecule](https://molecule.readthedocs.io/en/stable/).
We don't have CI yet, but you can run the tests with `molecule test`.
Todo
----
## Todo
- Backups
- Superuser creation
License
-------
## License
AGPL3
Author Information
------------------
## Author Information
Contact us at https://funkwhale.audio/community/
......@@ -6,24 +6,53 @@ funkwhale_static_path: /srv/funkwhale/data/static
funkwhale_music_path: /srv/funkwhale/data/music
funkwhale_config_path: /srv/funkwhale/config
funkwhale_external_storage_enabled: false
funkwhale_disable_django_admin: false
funkwhale_username: funkwhale
funkwhale_database_managed: true
funkwhale_frontend_managed: true
funkwhale_database_managed: true
funkwhale_database_local: true
funkwhale_database_name: funkwhale
funkwhale_database_user: funkwhale
# the DB host as per your ansible inventory. No delegation is used if left empty
funkwhale_database_host_ansible:
# the DB FQDN or IP for funkwhale connector configuration (ex: pg01.local)
funkwhale_database_host_app: localhost
funkwhale_database_port: 5432
# ↓ Only needed if 'funkwhale_database_managed' == false
# ↓ This is also assuming DB and user have already been set up, outside of the playbook.
# ↓ Considering the playbook handles both local and remote PostGreSQL server types, this should typically not be required.
# funkwhale_database_url: postgresql://{{ funkwhale_database_user }}[:{{ funkwhale_database_password }}]@[{{ funkwhale_database_host_app }}]:{{ funkwhale_database_port | default(5432) }}/{{ funkwhale_database_name }}
funkwhale_nginx_managed: true
# If you have an HTTPS reverse proxy higher up, set this to true
funkwhale_nginx_tls_termination: true
funkwhale_nginx_tls_configure_ciphers: true
funkwhale_nginx_max_body_size: 100M
funkwhale_nginx_use_compression: true
funkwhale_nginx_additional_config:
funkwhale_ssl_cert_path:
funkwhale_ssl_key_path:
funkwhale_protocol: https
funkwhale_letsencrypt_certbot_flags:
funkwhale_letsencrypt_enabled: true
funkwhale_letsencrypt_skip_cert: false
funkwhale_nginx_csp_policy: "default-src 'self'; connect-src https: wss: http: ws: 'self' 'unsafe-eval'; script-src 'self' 'wasm-unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; media-src https: http: 'self' data:; object-src 'none'"
funkwhale_redis_managed: true
funkwhale_api_ip: 127.0.0.1
funkwhale_api_port: 5000
funkwhale_web_workers: 1
funkwhale_protocol: https
funkwhale_gunicorn_extra_args: ""
funkwhale_settings_module: config.settings.production
funkwhale_env_vars: []
funkwhale_systemd_managed: true
funkwhale_systemd_after: redis.service postgresql.service
funkwhale_systemd_service_name: funkwhale
funkwhale_letsencrypt_certbot_flags:
funkwhale_letsencrypt_enabled: true
funkwhale_letsencrypt_skip_cert: false
funkwhale_ssl_cert_path:
funkwhale_ssl_key_path:
funkwhale_custom_settings:
funkwhale_custom_pip_packages: []
funkwhale_install_from_source: false
funkwhale_source_url: https://dev.funkwhale.audio/funkwhale/funkwhale.git
funkwhale_node_version: "13"
---
- name: restart funkwhale
become: true
when: funkwhale_systemd_managed
service:
name: "{{ funkwhale_systemd_service_name }}.target"
state: restarted
- name: reload funkwhale
become: true
when: funkwhale_systemd_managed
shell: |
systemctl kill -s HUP {{ funkwhale_systemd_service_name }}-server
systemctl kill -s HUP {{ funkwhale_systemd_service_name }}-worker
......
......@@ -7,13 +7,12 @@ set -eu
# If Ansible step fails with ascii decore error, ensure you have a locale properly set on
# your system e.g apt-get install -y locales locales-all
export LANG="en_US.UTF-8"
funkwhale_version="${FUNKWHALE_VERSION-funkwhale_version_placeholder}"
funkwhale_hostname="${FUNKWHALE_DOMAIN-}"
funkwhale_admin_email="${FUNKWHALE_ADMIN_EMAIL-}"
funkwhale_admin_username="${FUNKWHALE_ADMIN_USERNAME-}"
ansible_flags="${ANSIBLE_FLAGS- --diff}"
ansible_version="${ANSIBLE_VERSION-2.8.2}"
ansible_version="${ANSIBLE_VERSION-4.10.0}"
customize_install="${CUSTOMIZE_INSTALL-}"
skip_confirm="${SKIP_CONFIRM-}"
is_dry_run=${DRY_RUN-false}
......@@ -21,8 +20,9 @@ min_python_version_major="3"
min_python_version_minor="5"
base_path="/srv/funkwhale"
ansible_conf_path="$base_path/ansible"
ansible_bin_path="$HOME/.local/bin"
ansible_venv_path="$HOME/.local/ansible"
ansible_funkwhale_role_version="${ANSIBLE_FUNKWHALE_ROLE_VERSION-master}"
ansible_funkwhale_role_path="${ANSIBLE_FUNKWHALE_ROLE_PATH-}"
funkwhale_systemd_after=""
total_steps="4"
......@@ -71,14 +71,14 @@ setup() {
read -p "Enter the username for the admin account (leave empty to skip account creation) " funkwhale_admin_username
fi
if [ -z "$funkwhale_admin_email" ]; then
read -p "Enter the email used for the admin user and Let's Encrypt certificate: " funkwhale_admin_email
read -p "Enter the email used for the admin user (and Let's Encrypt certificate): " funkwhale_admin_email
fi
if [ -z "$customize_install" ]; then
yesno_prompt customize_install "The complete installation will setup Nginx, PostgresQL and Redis. Do you want customize what is installed?" "no"
yesno_prompt customize_install "The complete installation will setup Nginx, Certbot, PostgresQL and Redis. Do you want customize what is installed?" "no"
fi
if [ "$customize_install" = "true" ]; then
yesno_prompt funkwhale_nginx_managed 'Install and manage Nginx?' 'yes'
yesno_prompt funkwhale_nginx_managed 'Install and manage Nginx and Certbot?' 'yes'
yesno_prompt funkwhale_database_managed 'Install and manage PostgreSQL?' 'yes'
if [ "$funkwhale_database_managed" = "false" ]; then
read -p "Enter your database configuration, (e.g postgresql://user@localhost:5432/database_name): " funkwhale_database_url
......@@ -89,10 +89,14 @@ setup() {
read -p "Enter your redis configuration, (e.g redis://127.0.0.1:6379/0): " funkwhale_redis_url
funkwhale_systemd_after="funkwhale_systemd_after: "
fi
yesno_prompt funkwhale_systemd_managed 'Install and manage systemd services files?' 'yes'
yesno_prompt funkwhale_disable_django_admin 'Disable access to API admin dashboard?' 'no'
else
funkwhale_nginx_managed="true"
funkwhale_database_managed="true"
funkwhale_redis_managed="true"
funkwhale_disable_django_admin="false"
funkwhale_systemd_managed="true"
fi
......@@ -103,8 +107,9 @@ setup() {
echo "- domain: $funkwhale_hostname"
echo "- Admin username: $funkwhale_admin_username"
echo "- Admin email: $funkwhale_admin_email"
echo "- Manage nginx: $funkwhale_nginx_managed"
echo "- Manage nginx and certbot: $funkwhale_nginx_managed"
echo "- Manage redis: $funkwhale_redis_managed"
echo "- Manage systemd unit files: $funkwhale_systemd_managed"
if [ "$funkwhale_redis_managed" = "false" ]; then
echo " - Custom redis configuration: $funkwhale_redis_url"
fi
......@@ -112,6 +117,9 @@ setup() {
if [ "$funkwhale_database_managed" = "false" ]; then
echo " - Custom PostgreSQL configuration: $funkwhale_database_url"
fi
if [ "$funkwhale_disable_django_admin" = "true" ]; then
echo "- Disabled access to API admin dashboard"
fi
if [ "$is_dry_run" = "true" ]; then
echo "Running with dry-run mode, your system will be not be modified (apart from Ansible installation)."
......@@ -200,31 +208,42 @@ do_install() {
fi
echo " - You can run management commands by calling $base_path/manage, e.g $base_path/manage import_files"
echo ' - To upgrade to the latest version, run: sh -c "$(curl -sSL https://get.funkwhale.audio/upgrade.sh)"'
echo " - Edit your pod configuration in $ansible_conf_path/playbook.yml and apply the changes with: sudo $ansible_conf_path/reconfigure"
echo ' - To upgrade to the latest version, run: sudo sh -c "$(curl -sSL https://get.funkwhale.audio/upgrade.sh)"'
fi
}
init_ansible() {
echo "[2/$total_steps] Installing ansible dependencies..."
install_packages curl git python3-pip python3-apt sudo locales locales-all
install_packages curl git python3-pip python3-venv python3-apt python3-psycopg2 sudo locales locales-all
echo "[2/$total_steps] Installing Ansible..."
pip3 install --user ansible=="$ansible_version" psycopg2-binary
python3 -m venv $ansible_venv_path
$ansible_venv_path/bin/pip3 install --upgrade pip
$ansible_venv_path/bin/pip3 install ansible=="$ansible_version"
echo "[2/$total_steps] Creating ansible configuration files in $ansible_conf_path..."
mkdir -p "$ansible_conf_path"
cd "$ansible_conf_path"
cat <<EOF >requirements.yml
- src: git+https://dev.funkwhale.audio/funkwhale/ansible
name: funkwhale
version: $ansible_funkwhale_role_version
EOF
cat <<EOF >ansible.cfg
[defaults]
# Needed to use become with unprevileged users,
# see https://docs.ansible.com/ansible/latest/user_guide/become.html#becoming-an-unprivileged-user
#allow_world_readable_tmpfiles=true
EOF
if [ "$ansible_funkwhale_role_path" = '' ]; then
cat <<EOF >requirements.yml
- src: git+https://dev.funkwhale.audio/funkwhale/ansible
name: funkwhale
version: $ansible_funkwhale_role_version
EOF
else
mkdir -p "$ansible_conf_path/roles"
echo "roles_path = $ansible_conf_path/roles" >> ansible.cfg
echo "Symlinking local version of the ansible role: $ansible_funkwhale_role_path to $ansible_conf_path/roles/funkwhale"
rm -f "$ansible_conf_path/roles/funkwhale"
ln -s "$ansible_funkwhale_role_path" "$ansible_conf_path/roles/funkwhale"
fi
cat <<EOF >playbook.yml
- hosts: funkwhale_servers
roles:
......@@ -232,15 +251,47 @@ EOF
funkwhale_hostname: $funkwhale_hostname
funkwhale_version: $funkwhale_version
funkwhale_letsencrypt_email: $funkwhale_admin_email
funkwhale_nginx_managed: $funkwhale_nginx_managed
funkwhale_redis_managed: $funkwhale_redis_managed
funkwhale_database_managed: $funkwhale_database_managed
# Add any environment variables to the generated .env by uncommenting and editing the lines below
# then execute ./reconfigure
# funkwhale_env_vars:
# - "EMAIL_CONFIG=smtp+tls://user@:password@youremail.host:587"
# - "MYCUSTOM_ENV_VAR=test"
EOF
if [ "$funkwhale_nginx_managed" = "false" ]; then
cat <<EOF >>playbook.yml
funkwhale_nginx_managed: false
EOF
fi
if [ "$funkwhale_database_managed" = "false" ]; then
cat <<EOF >>playbook.yml
funkwhale_database_managed: false
funkwhale_database_url: $funkwhale_database_url
EOF
fi
if [ "$funkwhale_redis_managed" = "false" ]; then
cat <<EOF >>playbook.yml
funkwhale_redis_managed: false
funkwhale_redis_url: $funkwhale_redis_url
EOF
fi
if [ "$funkwhale_systemd_managed" = "false" ]; then
cat <<EOF >>playbook.yml
funkwhale_systemd_managed: false
EOF
fi
if [ "$(lsb_release -sc)" = "focal" ]; then
cat <<EOF >>playbook.yml
funkwhale_custom_pip_packages:
- twisted==22.4.0
EOF
fi
cat <<EOF >reconfigure
#!/bin/sh
# reapply playbook with existing parameter
# Useful if you changed some variables in playbook.yml
exec $ansible_venv_path/bin/ansible-playbook -i $ansible_conf_path/inventory.ini $ansible_conf_path/playbook.yml -u root $ansible_flags
EOF
chmod +x ./reconfigure
if [ "$funkwhale_redis_managed" = "false" ]; then
cat <<EOF >>playbook.yml
funkwhale_redis_url: $funkwhale_redis_url
......@@ -255,14 +306,17 @@ EOF
[funkwhale_servers]
127.0.0.1 ansible_connection=local ansible_python_interpreter=/usr/bin/python3
EOF
if [ "$ansible_funkwhale_role_path" = '' ]; then
echo "[2/$total_steps] Downloading Funkwhale playbook dependencies"
$ansible_bin_path/ansible-galaxy install -r requirements.yml -f
$ansible_venv_path/bin/ansible-galaxy install -r requirements.yml -f
else
echo "[2/$total_steps] Skipping playbook dependencies, using local role instead"
fi
}
run_playbook() {
cd "$ansible_conf_path"
echo "[3/$total_steps] Installing Funkwhale using ansible playbook in $ansible_conf_path..."
playbook_command="$ansible_bin_path/ansible-playbook -i $ansible_conf_path/inventory.ini $ansible_conf_path/playbook.yml -u root $ansible_flags"
playbook_command="$ansible_venv_path/bin/ansible-playbook -i $ansible_conf_path/inventory.ini $ansible_conf_path/playbook.yml -u root $ansible_flags"
if [ "$is_dry_run" = "true" ]; then
playbook_command="$playbook_command --check"
echo "[3/$total_steps] Skipping playbook because DRY_RUN=true"
......@@ -280,19 +334,20 @@ configure_server() {
cat <<EOF >$base_path/manage
#!/bin/sh
set -eu
sudo -u funkwhale -E $base_path/virtualenv/bin/python $base_path/api/manage.py \$@
sudo -u funkwhale -E $base_path/virtualenv/bin/funkwhale-manage \$@
EOF
chmod +x $base_path/manage
if [ -z "$funkwhale_admin_username" ]; then
echo "[4/$total_steps] Skipping superuser account creation"
else
echo "[4/$total_steps] Creating superuser account…"
if [ -z "$FUNKWHALE_CLI_USER_PASSWORD" ]; then
echo " Please input the password for the admin account password"
LOGLEVEL=error sudo -u funkwhale -E $base_path/virtualenv/bin/python \
$base_path/api/manage.py createsuperuser \
fi
LOGLEVEL=error sudo -u funkwhale -E \
$base_path/virtualenv/bin/funkwhale-manage fw users create --superuser \
--email $funkwhale_admin_email \
--username $funkwhale_admin_username \
-v 0
--username $funkwhale_admin_username
fi
}
......
......@@ -6,7 +6,7 @@ FROM {{ item.registry.url }}/{{ item.image }}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python3 python3-setuptools sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \
......
......@@ -12,7 +12,6 @@
funkwhale_ssl_cert_path: /certs/test.crt
funkwhale_ssl_key_path: /certs/test.key
funkwhale_hostname: yourdomain.funkwhale
funkwhale_version: 0.19.0-rc2
funkwhale_env_vars:
- EMAIL_CONFIG=smtp+tls://user@:password@youremail.host:587
- DEFAULT_FROM_EMAIL=noreply@yourdomain.funkwhale
......
......@@ -3,11 +3,13 @@ dependency:
name: galaxy
driver:
name: docker
lint:
name: yamllint
lint: |
yamllint .
ansible-lint
#flake8
platforms:
- name: debian-stretch
image: alehaa/debian-systemd:stretch
- name: debian-buster
image: alehaa/debian-systemd:buster
command: /sbin/init
tmpfs:
- /run
......@@ -17,11 +19,10 @@ platforms:
provisioner:
name: ansible
lint:
name: ansible-lint
inventory:
host_vars:
debian-buster:
ansible_python_interpreter: "/usr/bin/python3"
verifier:
name: testinfra
lint:
name: flake8
enabled: False
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}
---
- name: "Install postgresql"
become: true
when: funkwhale_database_managed
when: funkwhale_database_managed and funkwhale_database_local
package:
name:
- postgresql
- python3-psycopg2
- name: "Start Postgresql"
when: funkwhale_database_managed
when: funkwhale_database_managed and funkwhale_database_local
service:
name: postgresql
state: started
- name: "Create {{ funkwhale_database_name }} database"
- name: "Create {{ funkwhale_database_user }} database user on {{ funkwhale_database_host_ansible or inventory_hostname }} (local / passwordless)"
become: true
become_user: postgres
when: funkwhale_database_managed
postgresql_db:
name: "{{ funkwhale_database_name }}"
encoding: UTF-8
when: funkwhale_database_managed and funkwhale_database_host_ansible == none
postgresql_user:
name: "{{ funkwhale_database_user }}"
login_user: postgres
- name: "Create {{ funkwhale_database_user }} database user"
- name: "Create {{ funkwhale_database_user }} database user on {{ funkwhale_database_host_ansible }} (remote / with password)"
become: true
become_user: postgres
when: funkwhale_database_managed
when: funkwhale_database_managed and funkwhale_database_host_ansible != none
postgresql_user:
db: "{{ funkwhale_database_name }}"
name: "{{ funkwhale_database_user }}"
password: "{{ funkwhale_database_password }}"
login_user: postgres
delegate_to: "{{ funkwhale_database_host_ansible or inventory_hostname }}"
- name: "Grant privileges on database {{ funkwhale_database_name }} to {{ funkwhale_database_user }} user"
when: funkwhale_database_managed
- name: "Create {{ funkwhale_database_name }} database on {{ funkwhale_database_host_ansible or inventory_hostname }}"
become: true
become_user: postgres
command: psql -c "GRANT ALL PRIVILEGES ON DATABASE {{ funkwhale_database_name }} TO {{ funkwhale_database_user }}"
- name: "Create db extensions"
when: funkwhale_database_managed
become: true
postgresql_db:
name: "{{ funkwhale_database_name }}"
login_user: postgres
owner: "{{ funkwhale_database_user }}"
encoding: UTF-8
template: template0
delegate_to: "{{ funkwhale_database_host_ansible or inventory_hostname }}"
- name: set up pgsql extensions
become: yes
become_user: postgres
command: psql {{ funkwhale_database_name }} -c "CREATE EXTENSION IF NOT EXISTS {{ item }}"
with_items:
- unaccent
- citext
when: funkwhale_database_managed
postgresql_ext:
db: "{{ funkwhale_database_name }}"
name: "{{ myext }}"
login_user: postgres
loop: ["unaccent", "citext"]
loop_control:
loop_var: myext
delegate_to: "{{ funkwhale_database_host_ansible or inventory_hostname }}"
---
- name: Check latest version
when: funkwhale_version is not defined or funkwhale_version == "latest"
uri:
url: https://docs.funkwhale.audio/latest.txt
return_content: yes
register: latest_version
- name: Set version to install
set_fact:
funkwhale_install_version: "{{ latest_version.get('content', funkwhale_version) | trim }}"
- name: Ensure home folder can be created
become: true
file:
path: "{{ funkwhale_install_path | dirname }}"
state: directory
- name: "Create funkwhale user"
become: true
......@@ -7,12 +23,23 @@
shell: /bin/false
home: "{{ funkwhale_install_path }}"
- name: "Delete old source files"
become: true
file:
path: "{{ item }}"
state: absent
with_items:
- "{{ funkwhale_install_path }}/front"
- "{{ funkwhale_install_path }}/api"
- name: "Create funkwhale directories"
become: true
file:
path: "{{ item }}"
owner: "{{ funkwhale_username }}"
group: "{{ funkwhale_username }}"
state: directory
mode: "755"
with_items:
- "{{ funkwhale_install_path }}"
- "{{ funkwhale_media_path }}"
......@@ -26,19 +53,20 @@
register: "result_django_secret_key"
- name: "Generate a random secret key"
when: result_django_secret_key.stat.exists == False
when: not result_django_secret_key.stat.exists
become: true
become_user: "{{ funkwhale_username }}"
command: "openssl rand -hex 25"
register: result_secret_key_generation
- name: "Create django_secret_key file"
when: not ansible_check_mode and result_django_secret_key.stat.exists == False
when: not ansible_check_mode and not result_django_secret_key.stat.exists
become: true
become_user: "{{ funkwhale_username }}"
copy:
content: "{{ result_secret_key_generation.stdout }}"
dest: "{{ funkwhale_config_path }}/django_secret_key"
mode: "600"
- name: "Setup a dummy secret key"
when: ansible_check_mode
......@@ -70,9 +98,9 @@
- name: Download front-end files
become: true
become_user: "{{ funkwhale_username }}"
when: funkwhale_frontend_managed
when: funkwhale_frontend_managed and not funkwhale_install_from_source
unarchive:
src: https://dev.funkwhale.audio/funkwhale/funkwhale/builds/artifacts/{{ funkwhale_version }}/download?job=build_front
src: https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/{{ funkwhale_install_version }}/download?job=build_front
dest: "{{ funkwhale_install_path }}"
remote_src: true
notify:
......@@ -81,22 +109,121 @@
- name: Download api files
become: true
become_user: "{{ funkwhale_username }}"
when: not funkwhale_install_from_source
unarchive:
src: https://dev.funkwhale.audio/funkwhale/funkwhale/builds/artifacts/{{ funkwhale_version }}/download?job=build_api
src: https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/{{ funkwhale_install_version }}/download?job=build_api
dest: "{{ funkwhale_install_path }}"
remote_src: true
notify:
- reload funkwhale
# Install from source
- name: "Download Funkwhale source"
when: funkwhale_install_from_source
become: true
become_user: "{{ funkwhale_username }}"
git:
repo: "{{ funkwhale_source_url }}"
dest: "{{ funkwhale_install_path }}/src"
version: "{{ funkwhale_install_version }}"
force: true
notify:
- reload funkwhale
- name: Create /front symlink to source
when: funkwhale_frontend_managed and funkwhale_install_from_source
become: true
become_user: "{{ funkwhale_username }}"
file:
src: "{{ funkwhale_install_path }}/src/front"
dest: "{{ funkwhale_install_path }}/front"
state: link
- name: Create /api symlink to source
when: funkwhale_install_from_source
become: true
become_user: "{{ funkwhale_username }}"
file:
src: "{{ funkwhale_install_path }}/src/api"
dest: "{{ funkwhale_install_path }}/api"
state: link
- name: Create /config symlink in source
when: funkwhale_install_from_source
become: true
become_user: "{{ funkwhale_username }}"
file:
src: "{{ funkwhale_config_path }}"
dest: "{{ funkwhale_install_path }}/src/config"
state: link
- name: "Add frontend apt repositories GPG key"
become: true
when: funkwhale_frontend_managed and funkwhale_install_from_source
apt_key:
url: "{{ item }}"
state: present
with_items:
- https://dl.yarnpkg.com/debian/pubkey.gpg
- https://deb.nodesource.com/gpgkey/nodesource.gpg.key
- name: "Install frontend apt repositories"
become: true
when: funkwhale_frontend_managed and funkwhale_install_from_source
apt_repository:
repo: deb https://dl.yarnpkg.com/debian/ stable main
state: present
with_items:
- "deb https://dl.yarnpkg.com/debian/ stable main"
- "deb https://deb.nodesource.com/node_{{ funkwhale_node_version }}.x {{ ansible_distribution_release }} main"
- name: "Install frontend dependencies"
become: true
when: funkwhale_frontend_managed and funkwhale_install_from_source
package:
name:
- nodejs
- yarn
- gettext
- jq
- name: "Install frontend javascript dependencies"
become: true
become_user: "{{ funkwhale_username }}"
when: funkwhale_frontend_managed and funkwhale_install_from_source
yarn:
path: "{{ funkwhale_install_path }}/src/front"
- name: "Build front-end"
become: true
become_user: "{{ funkwhale_username }}"
when: funkwhale_frontend_managed and funkwhale_install_from_source
command: "yarn build"
args:
chdir: "{{ funkwhale_install_path }}/src/front"
notify:
- reload funkwhale
# end of from source related stuff
- name: "Setup virtualenv"
become: true
become_user: "{{ funkwhale_username }}"
pip:
name: wheel
name:
- "wheel"
- "pip>=21.3"
- "setuptools>=64"
virtualenv: "{{ funkwhale_install_path }}/virtualenv"
virtualenv_python: python3
- name: "Install python dependencies"
# Deprecated, not required anymore after funkwhale 1.3
- name: "Check if requirements.txt exists"
stat:
path: "{{ funkwhale_install_path }}/api/requirements.txt"
register: "requirements_file"
- name: "Install python dependencies from requirements.txt"
become: true
become_user: "{{ funkwhale_username }}"
pip:
......@@ -105,6 +232,30 @@
virtualenv_python: python3
notify:
- reload funkwhale
when: requirements_file.stat.exists
- name: "Install python dependencies from pyproject.toml"
become: true
become_user: "{{ funkwhale_username }}"
pip:
name: "{{ funkwhale_install_path }}/api"
editable: true
virtualenv: "{{ funkwhale_install_path }}/virtualenv"
virtualenv_python: python3
notify:
- reload funkwhale
when: not requirements_file.stat.exists
- name: "Install custom python dependencies, if any"
when: funkwhale_custom_pip_packages is defined and (funkwhale_custom_pip_packages|length>0)
become: true
become_user: "{{ funkwhale_username }}"
pip:
name: "{{ funkwhale_custom_pip_packages }}"
virtualenv: "{{ funkwhale_install_path }}/virtualenv"
virtualenv_python: python3
notify:
- reload funkwhale
- name: "Install gunicorn/uvicorn"
become: true
......@@ -112,14 +263,23 @@
pip:
name:
- gunicorn
- uvicorn
- uvicorn[standard]
virtualenv: "{{ funkwhale_install_path }}/virtualenv"
virtualenv_python: python3
notify:
- restart funkwhale
- name: Append custom settings to production.py, if any
become: true
become_user: "{{ funkwhale_username }}"
when: "funkwhale_custom_settings != none"
blockinfile:
path: "{{ funkwhale_install_path }}/api/config/settings/production.py"
insertafter: "EOF"
block: "{{ funkwhale_custom_settings }}"
- name: "Collect static files"
command: "{{ funkwhale_install_path }}/virtualenv/bin/python api/manage.py collectstatic --no-input"
command: "{{ funkwhale_install_path }}/virtualenv/bin/funkwhale-manage collectstatic --no-input"
become: true
become_user: "{{ funkwhale_username }}"
args:
......@@ -128,6 +288,6 @@
- name: "Apply database migrations"
become: true
become_user: "{{ funkwhale_username }}"
command: "{{ funkwhale_install_path }}/virtualenv/bin/python api/manage.py migrate --no-input"
command: "{{ funkwhale_install_path }}/virtualenv/bin/funkwhale-manage migrate --no-input"
args:
chdir: "{{ funkwhale_install_path }}"
---
- name: set a password for postgresql DB (remote psql server only)
tags: [db]
set_fact:
# Look up for the key 'vault_funkwhale_database_password' (for you to create, ideally in a vault).
# If no key is found,it will search inside ./pgsql_funkwhale.credentials.txt.
# If ./pgsql_funkwhale.credentials.txt does not exist, it generates a random password and write it there.
funkwhale_database_password: "{{ vault_funkwhale_database_password | default(lookup('password', './%s.credentials.txt chars=ascii_letters,digits length=20' % 'pgsql_funkwhale')) }}"
# If 'funkwhale_database_local:' == true, funkwhale will connect via unix socket (no password needed).
when: not funkwhale_database_local
- name: "Set frontend path"
when: funkwhale_frontend_managed
tags: [funkwhale, nginx]
set_fact:
funkwhale_frontend_path: "{{ funkwhale_install_path }}/front/dist"
......
......@@ -14,23 +14,46 @@
state: started
# from https://gist.github.com/mattiaslundberg/ba214a35060d3c8603e9b1ec8627d349
- name: "Download certbot-auto"
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled
- name: Check if certbot is already installed
stat:
path: "/usr/bin/certbot"
register: "certbot_installed"
- name: Install snapd
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled and not certbot_installed.stat.exists
become: true
package:
name: snapd
state: present
- name: Prepare snapd for certbot installation
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled and not certbot_installed.stat.exists
become: true
command: snap install core
- name: Refresh core snap before installing certbot
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled and not certbot_installed.stat.exists
become: true
command: snap refresh core
- name: Install certbot snap
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled and not certbot_installed.stat.exists
become: true
get_url:
url: https://dl.eff.org/certbot-auto
dest: /usr/local/bin/certbot-auto
mode: 0750
command: snap install --classic certbot
- name: "Install certbot using certbot-auto"
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled
- name: Link certbot snap installation
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled and not certbot_installed.stat.exists
become: true
command: certbot-auto --install-only -n -v
file:
src: /snap/bin/certbot
dest: /usr/bin/certbot
state: link
- name: Create letsencrypt certificate
when: funkwhale_nginx_managed and funkwhale_letsencrypt_enabled and not funkwhale_letsencrypt_skip_cert
become: true
command: certbot-auto -v -n certonly --nginx -m {{ funkwhale_letsencrypt_email }} --agree-tos -d {{ funkwhale_hostname }} {{ funkwhale_letsencrypt_certbot_flags }}
command: certbot -v -n certonly --nginx -m {{ funkwhale_letsencrypt_email }} --agree-tos -d {{ funkwhale_hostname }} {{ funkwhale_letsencrypt_certbot_flags }}
args:
creates: /etc/letsencrypt/live/{{ funkwhale_hostname }}
......@@ -40,7 +63,7 @@
cron:
name: funkwhale_letsencrypt_renewal
special_time: weekly
job: certbot-auto -v -n --renew certonly --nginx -m {{ funkwhale_letsencrypt_email }} --agree-tos -d {{ funkwhale_hostname }} {{ funkwhale_letsencrypt_certbot_flags }}
job: /usr/bin/certbot -v -n certonly --nginx -m {{ funkwhale_letsencrypt_email }} --agree-tos -d {{ funkwhale_hostname }} {{ funkwhale_letsencrypt_certbot_flags }}
- name: "Create funkwhale proxy file"
when: funkwhale_nginx_managed
......@@ -48,6 +71,7 @@
template:
src: funkwhale_proxy.conf.j2
dest: "/etc/nginx/funkwhale_proxy.conf"
mode: "644"
notify:
- reload nginx
......@@ -57,5 +81,6 @@
template:
src: nginx.conf.j2
dest: "/etc/nginx/sites-enabled/{{ funkwhale_hostname }}.conf"
mode: "644"
notify:
- reload nginx
......@@ -6,7 +6,6 @@
- "python3"
- "python3-dev"
- "python3-pip"
- "python-virtualenv" # for ansible
- "python3-virtualenv"
- "libldap2-dev"
- "libsasl2-dev"
......@@ -24,3 +23,5 @@
- libffi-dev
# not strictly needed but useful
- "curl"
- "dbus"
- "virtualenv"