From 8b9c4f91f895ad3a44102c2cf80849af1befabf4 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Sat, 20 Jul 2019 11:28:19 +0200 Subject: [PATCH 01/17] Fixed a typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65cf620..d8d18d6 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Create a playbook requirements and inventory file: touch requirements.yml touch playbook.yml touch inventory.ini - ansible.cfg + touch ansible.cfg Add the following to `requirements.yml`: -- GitLab From def78bb28c8a371dbd8d68138ef9d9fa9bec15b0 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Mon, 22 Jul 2019 16:31:50 +0200 Subject: [PATCH 02/17] Sh installation script --- install.sh | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 install.sh diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..3a6e9a6 --- /dev/null +++ b/install.sh @@ -0,0 +1,203 @@ +#!/bin/sh +set -eu + +# This script is meant for quick & easy install via: +# $ sh -c "$(curl -sSL https://get.funkwhale.audio/)" +# +# 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 + +funkwhale_version="${FUNKWHALE_VERSION-funkwhale_version_placeholder}" +funkwhale_hostname="${FUNKWHALE_DOMAIN-}" +funkwhale_admin_email="${FUNKWHALE_ADMIN_EMAIL-}" +funkwhale_admin_username="${FUNKWHALE_ADMIN_USERNAME-}" +skip_confirm="${SKIP_CONFIRM-}" +is_dry_run=${DRY_RUN-false} +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" +total_steps="4" + +echo +if [ -z "$funkwhale_hostname" ]; then + read -p "Enter your desired Funkwhale domain (e.g funkwhale.example): " funkwhale_hostname +fi +if [ -z "$funkwhale_admin_username" ]; then + 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 +fi + +echo "Installation summary:" +echo "- version: $funkwhale_version" +echo "- domain: $funkwhale_hostname" +echo "- Admin username: $funkwhale_admin_username" +echo "- Admin email: $funkwhale_admin_email" +echo + +if [ "$is_dry_run" = "true" ]; then + echo "Running with dry-run mode, your system will be not be modified (apart from Ansible installation)." + echo "Rerun with DRY_RUN=false for a real install." +fi; +if [ -z "$skip_confirm" ]; then + while true + do + read -p "Do you want to proceed with the installation? [yes/no] " result + case $result in + [Yy]* ) break;; + [Nn]* ) echo "Aborting script."; exit 1;; + *) echo "Please answer yes or no";; + esac + done +fi + +echo + +semver_parse() { + major="${1%%.*}" + minor="${1#$major.}" + minor="${minor%%.*}" + patch="${1#$major.$minor.}" + patch="${patch%%[-.]*}" +} + +get_python_version () { + python_version="" + if [ -x "$(command -v python3)" ]; then + python_version=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:3])))') + fi +} +has_sufficient_python_version() { + python_ok="" + semver_parse "$1" + if [ "$major" -ge "$min_python_version_major" ] && [ "$minor" -ge "$min_python_version_minor" ]; then + python_ok="true" + fi +} +install_packages() { + package_manager="apt-get" + if [ "$package_manager" = 'apt-get' ]; then + $package_manager update + $package_manager install -y "$@" + fi +} + +do_install() { + echo '[Beginning installation]' + echo "[1/$total_steps] Checking python3 version" + get_python_version + should_install_python="1" + if [ ! -z "$python_version" ]; then + has_sufficient_python_version "$python_version" + if [ ! -z "$python_ok" ]; then + echo "[1/$total_steps] $python_version with sufficient version found, skipping" + should_install_python="0" + fi + fi + if [ -z "$python_version" ]; then + echo "[1/$total_steps] Python3 not found, installing" + install_packages python3 python3-pip + + elif [ "$should_install_python" -eq "1" ]; then + echo "[1/$total_steps] Python $python_version found, $min_python_version_major.$min_python_version_minor needed, upgrading" + install_packages python3 python3-pip + else + echo "[1/$total_steps] Found Python $python_version, skipping upgrade" + fi + init_ansible + run_playbook + configure_server + if [ "$is_dry_run" = "true" ]; then + echo "Rerun with DRY_RUN=false for a real install." + else + echo "Done!" + echo " - Everything was installed in the $base_path directory" + if [ ! -z "$funkwhale_admin_username" ]; then + echo " - Created a superuser account with username $funkwhale_admin_username and the password you supplied" + fi + echo " - Your Funkwhale server is now up and running at https://$funkwhale_hostname" + echo " - You can run management commands by calling /srv/funkwhale/manage, e.g /srv/funkwhale/manage import_files" + fi + +} + +init_ansible() { + echo "[2/$total_steps] Installing ansible dependencies..." + install_packages curl git python3-pip python3-apt sudo + echo "[2/$total_steps] Installing Ansible..." + pip3 install --user ansible psycopg2-binary + + 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: master +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 + cat <<EOF >playbook.yml +- hosts: funkwhale-servers + roles: + - role: funkwhale + funkwhale_hostname: $funkwhale_hostname + funkwhale_version: $funkwhale_version + funkwhale_letsencrypt_email: $funkwhale_admin_email + +EOF + cat <<EOF >inventory.ini +[funkwhale-servers] +127.0.0.1 ansible_connection=local ansible_python_interpreter=/usr/bin/python3 +EOF + echo "[2/$total_steps] Downloading Funkwhale playbook dependencies" + $ansible_bin_path/ansible-galaxy install -r requirements.yml + +} +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 inventory.ini playbook.yml -u root --diff" + if [ "$is_dry_run" = "true" ]; then + playbook_command="$playbook_command --check" + echo "[3/$total_steps] Skipping playbook because DRY_RUN=true" + return 0 + fi + + echo "[3/$total_steps] Applying playbook with:" + echo " $playbook_command" + $playbook_command +} + +configure_server() { + echo "[4/$total_steps] Running final server configuration…" + echo "[4/$total_steps] Creating simple management script at $base_path/manage" + cat <<EOF >$base_path/manage +#!/bin/sh +set -eu +sudo -u funkwhale -E $base_path/virtualenv/bin/python $base_path/api/manage.py \$@ +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…" + 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 \ + --email $funkwhale_admin_email \ + --username $funkwhale_admin_username \ + -v 0 + fi +} + +# wrapped up in a function so that we have some protection against only getting +# half the file during "curl | sh" +do_install -- GitLab From 27853db9e6beb8dd1d5956cbcd42f9147a989d6a Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 14:22:42 +0200 Subject: [PATCH 03/17] Composable installation (disable nginx/redis/postgresql) --- install.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/install.sh b/install.sh index 3a6e9a6..17d16f8 100644 --- a/install.sh +++ b/install.sh @@ -11,6 +11,7 @@ funkwhale_version="${FUNKWHALE_VERSION-funkwhale_version_placeholder}" funkwhale_hostname="${FUNKWHALE_DOMAIN-}" funkwhale_admin_email="${FUNKWHALE_ADMIN_EMAIL-}" funkwhale_admin_username="${FUNKWHALE_ADMIN_USERNAME-}" +customize_install="${CUSTOMIZE_INSTALL-}" skip_confirm="${SKIP_CONFIRM-}" is_dry_run=${DRY_RUN-false} min_python_version_major="3" @@ -20,6 +21,28 @@ ansible_conf_path="$base_path/ansible" ansible_bin_path="$HOME/.local/bin" total_steps="4" +if [ "$funkwhale_version" = 'funkwhale_version_placeholder' ]; then + echo "No FUNKWHALE_VERSION found and the script didn't include a default one." + echo "Relaunch the script with FUNKWHALE_VERSION=yourdesiredversion" + exit 1 +fi + + +yesno_prompt() { + local __resultvar=$1 + local result="" + while true + do + read -p "$2 [yes/no]: " result + case $result in + [Yy]* ) result="true"; break;; + [Nn]* ) result="false"; break;; + *) echo "Please answer [y]es or [n]o";; + esac + done + eval $__resultvar="'$result'" +} + echo if [ -z "$funkwhale_hostname" ]; then read -p "Enter your desired Funkwhale domain (e.g funkwhale.example): " funkwhale_hostname @@ -30,28 +53,40 @@ 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 fi +if [ -z "$customize_install" ]; then + yesno_prompt customize_install "The complete installation will setup Nginx, PostgresQL and Redis. Do you want to disable or manage some of those components yourself?" +fi + +if [ "$customize_install" = "true" ]; then + yesno_prompt funkwhale_nginx_managed 'Install and manage Nginx?' + yesno_prompt funkwhale_database_managed 'Install and manage PostgreSQL?' + yesno_prompt funkwhale_redis_managed 'Install and manage Redis?' +else + funkwhale_nginx_managed="true" + funkwhale_database_managed="true" + funkwhale_redis_managed="true" +fi echo "Installation summary:" echo "- version: $funkwhale_version" echo "- domain: $funkwhale_hostname" echo "- Admin username: $funkwhale_admin_username" echo "- Admin email: $funkwhale_admin_email" -echo +echo "- Manage nginx: $funkwhale_nginx_managed" +echo "- Manage redis: $funkwhale_redis_managed" +echo "- Manage PostgreSQL: $funkwhale_database_managed" + if [ "$is_dry_run" = "true" ]; then echo "Running with dry-run mode, your system will be not be modified (apart from Ansible installation)." echo "Rerun with DRY_RUN=false for a real install." fi; if [ -z "$skip_confirm" ]; then - while true - do - read -p "Do you want to proceed with the installation? [yes/no] " result - case $result in - [Yy]* ) break;; - [Nn]* ) echo "Aborting script."; exit 1;; - *) echo "Please answer yes or no";; - esac - done + yesno_prompt proceed 'Do you want to proceed with the installation?' + case $proceed in + [Nn]* ) echo "Aborting script."; exit 1;; + *) echo "Please answer yes or no";; + esac fi echo @@ -151,6 +186,9 @@ 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 EOF cat <<EOF >inventory.ini -- GitLab From d2f4960b28634d1d40801604690d9d5a3bd6770d Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 15:24:59 +0200 Subject: [PATCH 04/17] Fixed python install issues on system with no configured locale --- install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 17d16f8..e4eb06a 100644 --- a/install.sh +++ b/install.sh @@ -6,6 +6,7 @@ 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-}" @@ -161,7 +162,7 @@ do_install() { init_ansible() { echo "[2/$total_steps] Installing ansible dependencies..." - install_packages curl git python3-pip python3-apt sudo + install_packages curl git python3-pip python3-apt sudo locales locales-all echo "[2/$total_steps] Installing Ansible..." pip3 install --user ansible psycopg2-binary -- GitLab From 81bc647ada284060a2d0d3742717bb09e42b52e6 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 15:26:13 +0200 Subject: [PATCH 05/17] Minor UX enhancements (enter to confirm default choice, etc.) --- install.sh | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/install.sh b/install.sh index e4eb06a..79b6c29 100644 --- a/install.sh +++ b/install.sh @@ -30,14 +30,26 @@ fi yesno_prompt() { + local default="${3-}" local __resultvar=$1 local result="" + local options="yes/no" + if [ "$default" = "yes" ]; then + local options="YES/no" + fi + if [ "$default" = "no" ]; then + local options="yes/NO" + fi while true do - read -p "$2 [yes/no]: " result + read -p "$2 [$options]: " result + if [ ! -z "$default" ] && [ -z "$result" ]; then + result="$default" + fi case $result in [Yy]* ) result="true"; break;; [Nn]* ) result="false"; break;; + "" ) result="true"; break;; *) echo "Please answer [y]es or [n]o";; esac done @@ -55,13 +67,13 @@ if [ -z "$funkwhale_admin_email" ]; then 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 to disable or manage some of those components yourself?" + yesno_prompt customize_install "The complete installation will setup Nginx, PostgresQL and Redis. Do you want to disable or manage some of those components yourself?" "no" fi if [ "$customize_install" = "true" ]; then - yesno_prompt funkwhale_nginx_managed 'Install and manage Nginx?' - yesno_prompt funkwhale_database_managed 'Install and manage PostgreSQL?' - yesno_prompt funkwhale_redis_managed 'Install and manage Redis?' + yesno_prompt funkwhale_nginx_managed 'Install and manage Nginx?' 'yes' + yesno_prompt funkwhale_database_managed 'Install and manage PostgreSQL?' 'yes' + yesno_prompt funkwhale_redis_managed 'Install and manage Redis?' 'yes' else funkwhale_nginx_managed="true" funkwhale_database_managed="true" @@ -83,7 +95,7 @@ if [ "$is_dry_run" = "true" ]; then echo "Rerun with DRY_RUN=false for a real install." fi; if [ -z "$skip_confirm" ]; then - yesno_prompt proceed 'Do you want to proceed with the installation?' + yesno_prompt proceed 'Do you want to proceed with the installation?' 'yes' case $proceed in [Nn]* ) echo "Aborting script."; exit 1;; *) echo "Please answer yes or no";; @@ -144,8 +156,10 @@ do_install() { echo "[1/$total_steps] Found Python $python_version, skipping upgrade" fi init_ansible + if [ "$is_dry_run" = "false" ]; then run_playbook configure_server + fi if [ "$is_dry_run" = "true" ]; then echo "Rerun with DRY_RUN=false for a real install." else -- GitLab From 86a554dd51e7ac2d4ba9bba06138898484dea105 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 15:28:09 +0200 Subject: [PATCH 06/17] Pin ansible version to avoid surprises --- install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 79b6c29..4d33ae7 100644 --- a/install.sh +++ b/install.sh @@ -12,6 +12,7 @@ funkwhale_version="${FUNKWHALE_VERSION-funkwhale_version_placeholder}" funkwhale_hostname="${FUNKWHALE_DOMAIN-}" funkwhale_admin_email="${FUNKWHALE_ADMIN_EMAIL-}" funkwhale_admin_username="${FUNKWHALE_ADMIN_USERNAME-}" +ansible_version="${ANSIBLE_VERSION-2.8.2}" customize_install="${CUSTOMIZE_INSTALL-}" skip_confirm="${SKIP_CONFIRM-}" is_dry_run=${DRY_RUN-false} @@ -178,7 +179,7 @@ init_ansible() { echo "[2/$total_steps] Installing ansible dependencies..." install_packages curl git python3-pip python3-apt sudo locales locales-all echo "[2/$total_steps] Installing Ansible..." - pip3 install --user ansible psycopg2-binary + pip3 install --user ansible=="$ansible_version" psycopg2-binary echo "[2/$total_steps] Creating ansible configuration files in $ansible_conf_path..." mkdir -p "$ansible_conf_path" -- GitLab From 9156020a2496bd97089936f6810ac1039ccbc3af Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 15:28:31 +0200 Subject: [PATCH 07/17] Disable diff mode on ansible by default, for a less verbose output --- install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index 4d33ae7..05207f9 100644 --- a/install.sh +++ b/install.sh @@ -12,6 +12,7 @@ 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-}" ansible_version="${ANSIBLE_VERSION-2.8.2}" customize_install="${CUSTOMIZE_INSTALL-}" skip_confirm="${SKIP_CONFIRM-}" @@ -158,8 +159,8 @@ do_install() { fi init_ansible if [ "$is_dry_run" = "false" ]; then - run_playbook - configure_server + run_playbook + configure_server fi if [ "$is_dry_run" = "true" ]; then echo "Rerun with DRY_RUN=false for a real install." @@ -218,7 +219,7 @@ EOF 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 inventory.ini playbook.yml -u root --diff" + playbook_command="$ansible_bin_path/ansible-playbook -i inventory.ini 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" -- GitLab From d2e330e09c472257a11dd456b4150f2ed0fa172a Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 15:31:32 +0200 Subject: [PATCH 08/17] Suppressed an ansible warning --- install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 05207f9..ff4e7ed 100644 --- a/install.sh +++ b/install.sh @@ -197,7 +197,7 @@ EOF #allow_world_readable_tmpfiles=true EOF cat <<EOF >playbook.yml -- hosts: funkwhale-servers +- hosts: funkwhale_servers roles: - role: funkwhale funkwhale_hostname: $funkwhale_hostname @@ -209,7 +209,7 @@ EOF EOF cat <<EOF >inventory.ini -[funkwhale-servers] +[funkwhale_servers] 127.0.0.1 ansible_connection=local ansible_python_interpreter=/usr/bin/python3 EOF echo "[2/$total_steps] Downloading Funkwhale playbook dependencies" -- GitLab From 7bf03aedc94d795df18ab8a63f0612632ddb0906 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 15:31:48 +0200 Subject: [PATCH 09/17] Use absolute path in ansible command for easier copy-pasting --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index ff4e7ed..2c63a9f 100644 --- a/install.sh +++ b/install.sh @@ -219,7 +219,7 @@ EOF 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 inventory.ini playbook.yml -u root $ansible_flags" + playbook_command="$ansible_bin_path/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" -- GitLab From edb49fda7d7b1eb5b0769fc3ecfdc214878a283e Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 15:50:43 +0200 Subject: [PATCH 10/17] Make the ansible role version configurable --- install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 2c63a9f..76562ca 100644 --- a/install.sh +++ b/install.sh @@ -22,6 +22,7 @@ min_python_version_minor="5" base_path="/srv/funkwhale" ansible_conf_path="$base_path/ansible" ansible_bin_path="$HOME/.local/bin" +ansible_funkwhale_role_version="${ANSIBLE_FUNKWHALE_ROLE_VERSION-master}" total_steps="4" if [ "$funkwhale_version" = 'funkwhale_version_placeholder' ]; then @@ -188,7 +189,7 @@ init_ansible() { cat <<EOF >requirements.yml - src: git+https://dev.funkwhale.audio/funkwhale/ansible name: funkwhale - version: master + version: $ansible_funkwhale_role_version EOF cat <<EOF >ansible.cfg [defaults] -- GitLab From b5a738e46e9e1e9b876e49b8f43e38f1aad2ec45 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 16:25:31 +0200 Subject: [PATCH 11/17] Force update of ansible role --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 76562ca..e02225e 100644 --- a/install.sh +++ b/install.sh @@ -214,7 +214,7 @@ EOF 127.0.0.1 ansible_connection=local ansible_python_interpreter=/usr/bin/python3 EOF echo "[2/$total_steps] Downloading Funkwhale playbook dependencies" - $ansible_bin_path/ansible-galaxy install -r requirements.yml + $ansible_bin_path/ansible-galaxy install -r requirements.yml -f } run_playbook() { -- GitLab From c1ef02877e29df24032ac45adb7fd91a7d60c58c Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 23 Jul 2019 16:27:49 +0200 Subject: [PATCH 12/17] Prompt for database / cache URL when disabling redis/postgres during install --- install.sh | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/install.sh b/install.sh index e02225e..f5931e5 100644 --- a/install.sh +++ b/install.sh @@ -23,6 +23,7 @@ base_path="/srv/funkwhale" ansible_conf_path="$base_path/ansible" ansible_bin_path="$HOME/.local/bin" ansible_funkwhale_role_version="${ANSIBLE_FUNKWHALE_ROLE_VERSION-master}" +funkwhale_systemd_after="" total_steps="4" if [ "$funkwhale_version" = 'funkwhale_version_placeholder' ]; then @@ -70,33 +71,49 @@ if [ -z "$funkwhale_admin_email" ]; then 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 to disable or manage some of those components yourself?" "no" + yesno_prompt customize_install "The complete installation will setup Nginx, 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_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 + funkwhale_systemd_after="funkwhale_systemd_after: " + fi yesno_prompt funkwhale_redis_managed 'Install and manage Redis?' 'yes' + if [ "$funkwhale_redis_managed" = "false" ]; then + 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 else funkwhale_nginx_managed="true" funkwhale_database_managed="true" funkwhale_redis_managed="true" fi +echo echo "Installation summary:" +echo echo "- version: $funkwhale_version" echo "- domain: $funkwhale_hostname" echo "- Admin username: $funkwhale_admin_username" echo "- Admin email: $funkwhale_admin_email" echo "- Manage nginx: $funkwhale_nginx_managed" echo "- Manage redis: $funkwhale_redis_managed" +if [ "$funkwhale_redis_managed" = "false" ]; then + echo " - Custom redis configuration: $funkwhale_redis_url" +fi echo "- Manage PostgreSQL: $funkwhale_database_managed" - +if [ "$funkwhale_database_managed" = "false" ]; then + echo " - Custom PostgreSQL configuration: $funkwhale_database_url" +fi if [ "$is_dry_run" = "true" ]; then echo "Running with dry-run mode, your system will be not be modified (apart from Ansible installation)." echo "Rerun with DRY_RUN=false for a real install." fi; +echo if [ -z "$skip_confirm" ]; then yesno_prompt proceed 'Do you want to proceed with the installation?' 'yes' case $proceed in @@ -171,8 +188,13 @@ do_install() { if [ ! -z "$funkwhale_admin_username" ]; then echo " - Created a superuser account with username $funkwhale_admin_username and the password you supplied" fi - echo " - Your Funkwhale server is now up and running at https://$funkwhale_hostname" - echo " - You can run management commands by calling /srv/funkwhale/manage, e.g /srv/funkwhale/manage import_files" + if [ "$funkwhale_nginx_managed" = "true" ]; then + echo " - Your Funkwhale server is now up and running at https://$funkwhale_hostname" + else + echo " - To complete the installation, you need to setup an Nginx or Apache2 reverse proxy: https://docs.funkwhale.audio/installation/index.html#reverse-proxy" + fi + + echo " - You can run management commands by calling $base_path/manage, e.g $base_path/manage import_files" fi } @@ -207,8 +229,22 @@ EOF funkwhale_nginx_managed: $funkwhale_nginx_managed funkwhale_redis_managed: $funkwhale_redis_managed funkwhale_database_managed: $funkwhale_database_managed - EOF + if [ "$funkwhale_database_managed" = "false" ]; then + cat <<EOF >>playbook.yml + funkwhale_database_url: $funkwhale_database_url +EOF + fi + if [ "$funkwhale_redis_managed" = "false" ]; then + cat <<EOF >>playbook.yml + funkwhale_redis_url: $funkwhale_redis_url +EOF + fi + if [ ! -z "$funkwhale_systemd_after" ]; then + cat <<EOF >>playbook.yml + $funkwhale_systemd_after +EOF + fi cat <<EOF >inventory.ini [funkwhale_servers] 127.0.0.1 ansible_connection=local ansible_python_interpreter=/usr/bin/python3 -- GitLab From 66ac3eebcbab7f47d8fda819a670b798c68eb1bc Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Thu, 1 Aug 2019 15:04:59 +0200 Subject: [PATCH 13/17] Added missing packages to build cryptography python dependency --- tasks/packages.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tasks/packages.yml b/tasks/packages.yml index fc2d1b8..7fecfc0 100644 --- a/tasks/packages.yml +++ b/tasks/packages.yml @@ -6,7 +6,7 @@ - "python3" - "python3-dev" - "python3-pip" - - "python-virtualenv" # for ansible + - "python-virtualenv" # for ansible - "python3-virtualenv" - "libldap2-dev" - "libsasl2-dev" @@ -19,5 +19,8 @@ - "libmagic-dev" - "libpq-dev" - "postgresql-client" + # Needed to build cryptography wheel sometimes + - libssl-dev + - libffi-dev # not strictly needed but useful - "curl" -- GitLab From 6ed0db088cab944c342688ed48e30ea72721a417 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Thu, 1 Aug 2019 15:15:41 +0200 Subject: [PATCH 14/17] Moved configuration-related code in a function --- install.sh | 177 +++++++++++++++++++++++++++-------------------------- 1 file changed, 91 insertions(+), 86 deletions(-) diff --git a/install.sh b/install.sh index f5931e5..ea7602b 100644 --- a/install.sh +++ b/install.sh @@ -26,103 +26,107 @@ ansible_funkwhale_role_version="${ANSIBLE_FUNKWHALE_ROLE_VERSION-master}" funkwhale_systemd_after="" total_steps="4" -if [ "$funkwhale_version" = 'funkwhale_version_placeholder' ]; then - echo "No FUNKWHALE_VERSION found and the script didn't include a default one." - echo "Relaunch the script with FUNKWHALE_VERSION=yourdesiredversion" - exit 1 -fi +echo +setup() { + + if [ "$funkwhale_version" = 'funkwhale_version_placeholder' ]; then + echo "No FUNKWHALE_VERSION found and the script didn't include a default one." + echo "Relaunch the script with FUNKWHALE_VERSION=yourdesiredversion" + exit 1 + fi + + yesno_prompt() { + local default="${3-}" + local __resultvar=$1 + local result="" + local options="yes/no" + if [ "$default" = "yes" ]; then + local options="YES/no" + fi + if [ "$default" = "no" ]; then + local options="yes/NO" + fi + while true + do + read -p "$2 [$options]: " result + if [ ! -z "$default" ] && [ -z "$result" ]; then + result="$default" + fi + case $result in + [Yy]* ) result="true"; break;; + [Nn]* ) result="false"; break;; + "" ) result="true"; break;; + *) echo "Please answer [y]es or [n]o";; + esac + done + eval $__resultvar="'$result'" + } -yesno_prompt() { - local default="${3-}" - local __resultvar=$1 - local result="" - local options="yes/no" - if [ "$default" = "yes" ]; then - local options="YES/no" + echo + if [ -z "$funkwhale_hostname" ]; then + read -p "Enter your desired Funkwhale domain (e.g funkwhale.example): " funkwhale_hostname + fi + if [ -z "$funkwhale_admin_username" ]; then + read -p "Enter the username for the admin account (leave empty to skip account creation) " funkwhale_admin_username fi - if [ "$default" = "no" ]; then - local options="yes/NO" + if [ -z "$funkwhale_admin_email" ]; then + read -p "Enter the email used for the admin user and Let's Encrypt certificate: " funkwhale_admin_email fi - while true - do - read -p "$2 [$options]: " result - if [ ! -z "$default" ] && [ -z "$result" ]; then - result="$default" + 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" + fi + + if [ "$customize_install" = "true" ]; then + yesno_prompt funkwhale_nginx_managed 'Install and manage Nginx?' '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 + funkwhale_systemd_after="funkwhale_systemd_after: " fi - case $result in - [Yy]* ) result="true"; break;; - [Nn]* ) result="false"; break;; - "" ) result="true"; break;; - *) echo "Please answer [y]es or [n]o";; - esac - done - eval $__resultvar="'$result'" -} + yesno_prompt funkwhale_redis_managed 'Install and manage Redis?' 'yes' + if [ "$funkwhale_redis_managed" = "false" ]; then + 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 + else + funkwhale_nginx_managed="true" + funkwhale_database_managed="true" + funkwhale_redis_managed="true" + fi -echo -if [ -z "$funkwhale_hostname" ]; then - read -p "Enter your desired Funkwhale domain (e.g funkwhale.example): " funkwhale_hostname -fi -if [ -z "$funkwhale_admin_username" ]; then - 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 -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" -fi -if [ "$customize_install" = "true" ]; then - yesno_prompt funkwhale_nginx_managed 'Install and manage Nginx?' '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 - funkwhale_systemd_after="funkwhale_systemd_after: " - fi - yesno_prompt funkwhale_redis_managed 'Install and manage Redis?' 'yes' + echo + echo "Installation summary:" + echo + echo "- version: $funkwhale_version" + echo "- domain: $funkwhale_hostname" + echo "- Admin username: $funkwhale_admin_username" + echo "- Admin email: $funkwhale_admin_email" + echo "- Manage nginx: $funkwhale_nginx_managed" + echo "- Manage redis: $funkwhale_redis_managed" if [ "$funkwhale_redis_managed" = "false" ]; then - read -p "Enter your redis configuration, (e.g redis://127.0.0.1:6379/0): " funkwhale_redis_url - funkwhale_systemd_after="funkwhale_systemd_after: " + echo " - Custom redis configuration: $funkwhale_redis_url" + fi + echo "- Manage PostgreSQL: $funkwhale_database_managed" + if [ "$funkwhale_database_managed" = "false" ]; then + echo " - Custom PostgreSQL configuration: $funkwhale_database_url" fi -else - funkwhale_nginx_managed="true" - funkwhale_database_managed="true" - funkwhale_redis_managed="true" -fi - -echo -echo "Installation summary:" -echo -echo "- version: $funkwhale_version" -echo "- domain: $funkwhale_hostname" -echo "- Admin username: $funkwhale_admin_username" -echo "- Admin email: $funkwhale_admin_email" -echo "- Manage nginx: $funkwhale_nginx_managed" -echo "- Manage redis: $funkwhale_redis_managed" -if [ "$funkwhale_redis_managed" = "false" ]; then - echo " - Custom redis configuration: $funkwhale_redis_url" -fi -echo "- Manage PostgreSQL: $funkwhale_database_managed" -if [ "$funkwhale_database_managed" = "false" ]; then - echo " - Custom PostgreSQL configuration: $funkwhale_database_url" -fi -if [ "$is_dry_run" = "true" ]; then - echo "Running with dry-run mode, your system will be not be modified (apart from Ansible installation)." - echo "Rerun with DRY_RUN=false for a real install." -fi; -echo -if [ -z "$skip_confirm" ]; then - yesno_prompt proceed 'Do you want to proceed with the installation?' 'yes' - case $proceed in - [Nn]* ) echo "Aborting script."; exit 1;; - *) echo "Please answer yes or no";; - esac -fi + if [ "$is_dry_run" = "true" ]; then + echo "Running with dry-run mode, your system will be not be modified (apart from Ansible installation)." + echo "Rerun with DRY_RUN=false for a real install." + fi; + echo + if [ -z "$skip_confirm" ]; then + yesno_prompt proceed 'Do you want to proceed with the installation?' 'yes' + case $proceed in + [Nn]* ) echo "Aborting script."; exit 1;; + *) echo "Please answer yes or no";; + esac + fi -echo +} semver_parse() { major="${1%%.*}" @@ -154,6 +158,7 @@ install_packages() { } do_install() { + setup echo '[Beginning installation]' echo "[1/$total_steps] Checking python3 version" get_python_version -- GitLab From 0c2b5c3f6d33d44b54f87cb14b3e20e11898439d Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Thu, 1 Aug 2019 15:36:02 +0200 Subject: [PATCH 15/17] Restored verbose output --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index ea7602b..e38ea74 100644 --- a/install.sh +++ b/install.sh @@ -12,7 +12,7 @@ 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-}" +ansible_flags="${ANSIBLE_FLAGS- --diff}" ansible_version="${ANSIBLE_VERSION-2.8.2}" customize_install="${CUSTOMIZE_INSTALL-}" skip_confirm="${SKIP_CONFIRM-}" -- GitLab From e01e7f3b570dac6449180166e0e64425a4d6ef88 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Fri, 23 Aug 2019 11:35:19 +0200 Subject: [PATCH 16/17] Added upgrade script --- upgrade.sh | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100755 upgrade.sh diff --git a/upgrade.sh b/upgrade.sh new file mode 100755 index 0000000..0ab0d86 --- /dev/null +++ b/upgrade.sh @@ -0,0 +1,110 @@ +#!/bin/sh +set -eu + +# This script is meant for quick & easy upgrade of Funkwhale pods installed via: +# $ sh -c "$(curl -sSL https://get.funkwhale.audio/)" +# +# 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="${1-}" +ansible_flags="${ANSIBLE_FLAGS- --diff}" +skip_confirm="${SKIP_CONFIRM-}" +is_dry_run=${DRY_RUN-false} +base_path="/srv/funkwhale" +ansible_conf_path="$base_path/ansible" +ansible_bin_path="$HOME/.local/bin" +ansible_funkwhale_role_version="${ANSIBLE_FUNKWHALE_ROLE_VERSION-master}" +funkwhale_systemd_after="" +total_steps="4" +latest_version_url="https://docs.funkwhale.audio/latest.txt" +echo +yesno_prompt() { + local default="${3-}" + local __resultvar=$1 + local result="" + local options="yes/no" + if [ "$default" = "yes" ]; then + local options="YES/no" + fi + if [ "$default" = "no" ]; then + local options="yes/NO" + fi + while true + do + read -p "$2 [$options]: " result + if [ ! -z "$default" ] && [ -z "$result" ]; then + result="$default" + fi + case $result in + [Yy]* ) result="true"; break;; + [Nn]* ) result="false"; break;; + "" ) result="true"; break;; + *) echo "Please answer [y]es or [n]o";; + esac + done + eval $__resultvar="'$result'" +} + +do_upgrade() { + echo '[Beginning upgrade]' + playbook_path="$ansible_conf_path/playbook.yml" + echo "[1/$total_steps] Retrieving currently installed version from $playbook_path" + current_version=$(grep 'funkwhale_version:' $playbook_path | xargs | sed 's/funkwhale_version: //' | xargs) + if [ -z $current_version ]; then + echo "Could not retrieve the current installed version from $playbook_path, the file should exist and contain a 'funkwhale_version:' line" + exit 1 + fi + if [ -z "$funkwhale_version" ]; then + echo "[1/$total_steps] No target version specified, 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, ensure you have network connectivity" + exit 1 + fi + fi + echo + echo "Upgrade summary:" + echo + echo "- Current version: $current_version" + echo "- Target version: $funkwhale_version" + if [ "$is_dry_run" = "true" ]; then + echo "- Running with dry-run mode, your system will be not be modified" + echo " Rerun with DRY_RUN=false for a real upgrade." + else + echo "- Upgrading may cause temporary downtime on your pod" + fi; + echo + + if [ -z "$skip_confirm" ]; then + yesno_prompt proceed 'Do you want to proceed with the upgrade?' 'yes' + if [ "$proceed" = "false" ]; then + echo "Aborting upgrade"; + exit 1; + fi + fi + echo "[2/$total_steps] Replacing current version number in $playbook_path…" + if [ "$is_dry_run" = "false" ]; then + sed -i.bak -r "s/(funkwhale_version:)(.*)/\1 $funkwhale_version/" $playbook_path + fi + cd "$ansible_conf_path" + echo "[3/$total_steps] Upgrading ansible dependencies..." + playbook_command="$ansible_bin_path/ansible-playbook -i $ansible_conf_path/inventory.ini $ansible_conf_path/playbook.yml -u root $ansible_flags" + if [ "$is_dry_run" = "true" ]; then + echo "[3/$total_steps] Skipping playbook because DRY_RUN=true" + else + echo "[3/$total_steps] Upgrading Funkwhale using ansible playbook in $ansible_conf_path..." + $ansible_bin_path/ansible-galaxy install -r requirements.yml -f + echo "[3/$total_steps] Applying playbook with:" + echo " $playbook_command" + $playbook_command + fi + echo + echo "Upgrade to $funkwhale_version complete!" + exit +} + +# wrapped up in a function so that we have some protection against only getting +# half the file during "curl | sh" +do_upgrade -- GitLab From 790e3fa60aab1d63d0ac4f7a8d73cd540899535e Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Fri, 23 Aug 2019 11:51:56 +0200 Subject: [PATCH 17/17] =?UTF-8?q?Added=20CI=C2=A0script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..63bc02d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,30 @@ +stages: + - deploy + +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" + 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 + - mkdir -p public + - cp install.sh public/ + - cp install.sh public/index.html + - cp upgrade.sh public/upgrade.sh + + artifacts: + paths: + - public + only: + - master@funkwhale/ansible + tags: + - docker -- GitLab