Skip to main content

Скрипт для Debian 12

#!/usr/bin/env bash
# shellcheck disable=SC2059

# Copyright (C) 2015-2023 YunoHost
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# RUN INSTALL SCRIPT WITH -a FOR NON-INTERACTIVE MODE.

set -u

# Globals

YUNOHOST_LOG="/var/log/yunohost-installation_$(date +%Y%m%d_%H%M%S).log"
readonly YUNOHOST_LOG
export DEBIAN_FRONTEND=noninteractive

###############################################################################
# Main functions                                                              #
###############################################################################

function check_connection() {
    TIMEOUT=$1

    while [ "$TIMEOUT" -gt 0 ]; do
        ping -c 1 -W 2 yunohost.org > /dev/null 2>&1 && return 0
        sleep 1
        TIMEOUT=$((TIMEOUT - 1))
    done

    return 1
}

function usage() {
  cat << EOF
Usage :
  $(basename "$0") [-a] [-d <DISTRIB>] [-h]

Options :
  -a      Enable automatic mode. No questions are asked.
          This does not perform the post-install step.
  -d      Choose the distribution to install ('stable', 'testing', 'unstable').
          Defaults to 'stable'
  -f      Ignore checks before starting the installation. Use only if you know
          what you are doing.
  -h      Prints this help and exit
EOF
}

function parse_options()
{
    AUTOMODE=false
    DISTRIB=stable
    BUILD_IMAGE=false
    FORCE=false

    while getopts ":aid:fh" option; do
        case $option in
            a)
                AUTOMODE=true
                export DEBIAN_FRONTEND=noninteractive
                ;;
            d)
                DISTRIB=$OPTARG
                ;;
            f)
                FORCE=true
                ;;
            i)
                # This hidden option will allow to build generic image for Rpi/Olimex
                BUILD_IMAGE=true
                ;;
            h)
                usage
                exit 0
                ;;
            :)
                usage
                exit 1
                ;;
            \?)
                usage
                exit 1
                ;;
        esac
    done
}

function main()
{
    parse_options "$@"
    check_assertions              || exit 1
    confirm_installation          || exit 1
    upgrade_system                || die "Failed to upgrade the system"
    boring_workarounds            || die "Failed to run the boring workarounds"
    setup_package_source          || die "Setting up deb package sources failed"
    install_yunohost_packages     || die "Installation of Yunohost packages failed"

    # For some reason sometimes dbus is not properly started/enabled ...
    if [[ "$BUILD_IMAGE" == "false" ]] ; then
        systemctl is-active dbus >/dev/null || systemctl enable dbus --now
    fi

    if [[ "$BUILD_IMAGE" == "true" ]] ; then
        clean_image || die "Unable to clean image"
    fi

    if is_raspbian ; then

        # FIXME : add a proper conclusion + timer warning?

        # Reboot should be done before postinstall to be able to run iptables rules
        reboot
    fi

    conclusion
    exit 0
}

###############################################################################
# Helpers                                                                     #
###############################################################################

normal=$(printf '\033[0m')
bold=$(printf '\033[1m')
# faint=$(printf '\033[2m')
# underline=$(printf '\033[4m')
# negative=$(printf '\033[7m')
red=$(printf '\033[31m')
green=$(printf '\033[32m')
orange=$(printf '\033[33m')
blue=$(printf '\033[34m')
# yellow=$(printf '\033[93m')
# white=$(printf '\033[39m')
resetline=$(printf '\r\033[K')
readonly normal bold red green orange blue resetline

# shellcheck disable=SC2317
function success()
{
  local msg=${1}
  echo "[${bold}${green} OK ${normal}] ${msg}" | tee -a "$YUNOHOST_LOG"
}

function info()
{
  local msg=${1}
  echo "[${bold}${blue}INFO${normal}] ${msg}" | tee -a "$YUNOHOST_LOG"
}

# shellcheck disable=SC2317
function warn()
{
  local msg=${1}
  echo "[${bold}${orange}WARN${normal}] ${msg}" | tee -a "$YUNOHOST_LOG" >&2
}

function error()
{
  local msg=${1}
  echo "[${bold}${red}FAIL${normal}] ${msg}" | tee -a "$YUNOHOST_LOG" >&2
}

function die() {
    error "$1"
    info "Installation logs are available in $YUNOHOST_LOG"
    exit 1
}

trap trapint 2
# shellcheck disable=SC2317
function trapint {
    echo ""
    die "Aborted"
    exit 0
}

function show_apt_progress {

    local percent="$1"
    local title="$2"
    local message="$3"

    local done=$((${percent%.*}*40/100))
    local todo=$((39 - done))

    local done_sub_bar todo_sub_bar
    done_sub_bar="$(printf "%${done}s")"
    todo_sub_bar="$(printf "%${todo}s")"

    echo -ne "$resetline  $bold$blue$title$normal [${done_sub_bar// /=}>${todo_sub_bar}] ${percent:0:4}% ${message:0:40}"
}

function _apt_with_progress() {
    local wat percent message title
    apt-get "$@" -o 'APT::Status-Fd=3' 3>&1 >> "$YUNOHOST_LOG" 2>&1 \
        | while read -r line; do
            wat=$(echo "$line" | cut -d: -f1)
            percent=$(echo "$line" | cut -d: -f3)
            message=$(echo "$line" | cut -d: -f2)
            if [[ $wat == "dlstatus" ]]; then
                title="Downloading"
            else
                title="Installing"
            fi
            show_apt_progress "$percent" "$title" "$message";
        done
}

function _apt() {
    set -o pipefail
    cat << EOF >> "$YUNOHOST_LOG"
===================
Running: apt-get $*
===================
EOF
    if [[ "$AUTOMODE" == "true" ]]; then
        # Why we need pipefail : https://stackoverflow.com/a/6872163
        apt-get "$@" 2>&1 | tee -a "$YUNOHOST_LOG"
        ret="$?"
    else
        if _apt_with_progress "$@"; then
            ret=0
            printf "$resetline    $bold${green}Done$normal"
        else
            ret=1
            printf "$resetline    $bold${red}'apt-get $*' failed.$normal Please check $YUNOHOST_LOG for debugging\n\n";
        fi
    fi
    set +o pipefail
    return "$ret"
}

function apt_update() {
    _apt update --allow-releaseinfo-change
}

function apt_install() {
    _apt install --assume-yes -o Dpkg::Options::="--force-confold" "$@"
}

###############################################################################
# Installation steps                                                          #
###############################################################################

function check_assertions()
{
    # Assert we're on Debian
    # Note : we do not rely on lsb_release to avoid installing a dependency
    # only to check this...
    if [[ ! -f "/etc/debian_version" ]]; then
        error "This script can only be ran on Debian 12 (Bookworm)."
        return 1
    fi

    # Assert we're on Bookworm
    # Note : we do not rely on lsb_release to avoid installing a dependency
    # only to check this...
    # TODO: remove the line with "bookworm/sid"
    debian_version=$(cat /etc/debian_version)
    if ! [[ "$debian_version" =~ ^12.*  ]] && ! [[ "$debian_version" =~ "bookworm/sid" ]]; then
        error "YunoHost is only available for the version 12 (Bookworm) of Debian, you are using '$(cat /etc/debian_version)'."
        return 1
    fi
    # Forbid people from installing on Ubuntu or Linux mint ...
    if [[ -f "/etc/lsb-release" ]];
    then
        if grep -q -i "Ubuntu\|Mint" /etc/lsb-release
        then
            error "Please don't try to install YunoHost on an Ubuntu or Linux Mint system ... You need a 'raw' Debian 12 (Bookworm)."
            return 1
        fi
    fi

    # Assert we're root
    if [[ "$(id -u)" != "0" ]]; then
        error "This script must be run as root. On most setups, the command 'sudo -i' can be run first to become root."
        return 1
    fi

    # Assert Internet is reachable
    if ! check_connection 30; then
        die "You need internet to use this script! yunohost.org did not respond to ping after more than 30s."
    fi

    # Assert curl is setup
    if ! command -v curl >/dev/null 2>&1 && ! apt_install curl; then
        error "Yunohost installer requires curl to be installed, but it failed to install it."
        return 1
    fi

    # Check PATH var
    if [[ "$PATH" != *"/sbin"* ]]; then
        error "Your environment PATH variable must contains /sbin directory. Maybe try running 'PATH=/sbin:\$PATH' to fix this."
        return 1
    fi

    # Assert systemd is installed
    if ! command -v systemctl > /dev/null; then
        error "YunoHost requires systemd to be installed."
        return 1
    fi

    # Check that kernel is >= 3.12, otherwise systemd won't work properly. Cf. https://github.com/systemd/systemd/issues/5236#issuecomment-277779394
    if dpkg --compare-versions "$(uname -r)" "lt" "3.12"; then
        error "YunoHost requires a kernel >= 3.12. Please consult your hardware documentation or VPS provider to learn how to upgrade your kernel."
        return 1
    fi

    # Check we aren't running in docker or other weird containers that we can't probably install on
    if systemd-detect-virt | grep -q -w "docker\|container-other" && [[ "$FORCE" != "true" ]]; then
        error "It seems like you are trying to install YunoHost in docker or a weird container technology which probably is not supported by this install script (or YunoHost as a whole). If you know what you are doing, you can run this script with -f."
        return 1
    fi
    # Check possible conflict with apache, bind9.
    if dpkg --get-selections | grep -v deinstall | grep -q 'bind9\s' && [[ "$FORCE" != "true" ]]; then
        error "Bind9 is installed on your system. Yunohost conflicts with Bind9 because it requires dnsmasq. To be able to run this script, you should first run 'apt remove bind9 --purge --autoremove'."
        return 1
    fi
    if dpkg --get-selections | grep -v deinstall | grep -q 'apache2\s' && [[ "$FORCE" != "true" ]]; then
        error "Apache is installed on your system. Yunohost conflicts with apache2 because it requires nginx. To be able to run this script, you should first run 'apt remove apache2 --purge --autoremove'."
        return 1
    fi

}

function confirm_installation() {

    [[ "$AUTOMODE" == "true" ]] && return 0

    cat << EOF | tee -a "$YUNOHOST_LOG"
$bold
  ╭───────────────────────╮
  │ YunoHost Installation │
  ╰───────────────────────╯
$normal
  • Installing YunoHost requires to install various important services,
    and possibly rework the configuration of some services that may already
    be installed (such as: nginx, postfix, dovecot, fail2ban, slapd)

EOF

    read -r -p "    Are you sure you want to proceed (y/n) ? " choice < /dev/tty
    choice="$(echo "$choice" | tr '[:upper:]' '[:lower:]')"
    [[ "$choice" == "yes" ]] || [[ "$choice" == "y" ]] || { error "Aborting"; return 1; }

    if [[ "$DISTRIB" == "unstable" ]]
    then
        cat << EOF | tee -a "$YUNOHOST_LOG"

  • You are installing the unstable/alpha version of YunoHost 12/Bookworm.

        You should be warned that THIS IS ALPHA-STAGE DEVELOPMENT.
            WE ABSOLUTELY DISCOURAGE ANY USE OF THIS VERSION
         IN A PRODUCTION CONTEXT, THIS IS ONLY MEANT FOR *TESTING*.

                        THINGS **WILL** BREAK.

EOF
        read -r -p "    Type 'Yes, I understand' if you understand: " choice < /dev/tty
        [[ "$choice" == "Yes, I understand" ]] || { error "Aborting"; return 1; }
    fi

    # SSH config warning
    if [[ -f /etc/ssh/sshd_config ]]
    then

        # If root login is currently enabled
        local root_login_warning=""
        if ! grep -E "^[[:blank:]]*PermitRootLogin[[:blank:]]+no" /etc/ssh/sshd_config ; then
            root_login_warning="      • SSH login using root will be disabled (except from local network).\n"
            root_login_warning+="        Instead, you should login using the first YunoHost user."

        fi

        # If current conf uses a custom ssh port
        local ssh_port_warning=""
        if grep -Ev "^[[:blank:]]*Port[[:blank:]]+22[[:blank:]]*(#.*)?$" /etc/ssh/sshd_config | grep -E "^[[:blank:]]*Port[[:blank:]]+[[:digit:]]+$" ; then
            ssh_port_warning="      • You will have to connect using port 22 instead of your custom SSH port,\n"
            ssh_port_warning+="        though you can reconfigure this from YunoHost after the postinstall."
        fi

        if [[ -n "$root_login_warning" ]] || [[ -n "$ssh_port_warning" ]]
        then
            cat << EOF | tee -a "$YUNOHOST_LOG"

  • Additionally, it is encouraged to let YunoHost manage the SSH configuration.
    However, you should be aware that:
$(test -n "$root_login_warning" && echo -e "$root_login_warning")
$(test -n "$ssh_port_warning" && echo -e "$ssh_port_warning")
    (Note that this will only be effective *after* you run YunoHost's postinstall)

EOF
            read -r -p "    Should YunoHost override the SSH configuration (y/n) ? " choice < /dev/tty
            choice="$(echo "$choice" | tr '[:upper:]' '[:lower:]')"
            if [[ "$choice" != "yes" ]] && [[ "$choice" != "y" ]]
            then
                # Keep a copy to be restored during the postinstall
                # so that the ssh confs behaves as manually modified.
                cp /etc/ssh/sshd_config /etc/ssh/sshd_config.before_yunohost
            fi
        fi
    fi

    cat << EOF | tee -a "$YUNOHOST_LOG"

  🚀 ${bold}Let's go !$normal

  📜 Detailed logs will be available in $YUNOHOST_LOG
EOF

    return 0
}

function upgrade_system() {

    echo "" | tee -a "$YUNOHOST_LOG"
    echo "$bold  1/5 • Running system upgrades$normal" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"

    apt_update || return 1

    # We need libtext-iconv-perl even before the dist-upgrade,
    # otherwise the dist-upgrade might fails on some setups because
    # perl is yolomacnuggets :|
    # Stuff like "Can't locate object method "new" via package "Text::Iconv""
    apt_install libtext-iconv-perl || return 1

    # Manually upgrade grub stuff in non-interactive mode,
    # otherwise a weird technical question is asked to the user
    # regarding how to upgrade grub's configuration...
    apt_install --only-upgrade grub-common grub2-common || true

    _apt dist-upgrade -y -o Dpkg::Options::="--force-confold" || return 1

    if is_raspbian ; then
        apt_install rpi-update || return 1

            if [[ "$BUILD_IMAGE" == "false" ]] ; then
                (rpi-update 2>&1 | tee -a "$YUNOHOST_LOG") || return 1
        fi
    fi
}

function boring_workarounds() {

    echo "" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"
    echo "$bold  2/5 • Install dependencies needed before the main install$normal" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"

    # ###################################################################### #
    # Dependencies that must be installed prior to the rest, for reasons ... #
    # (for example https://github.com/YunoHost/issues/issues/1382)           #
    # ###################################################################### #

    apt_install --no-install-recommends lsb-release dialog curl gnupg apt-transport-https adduser debconf debhelper dh-autoreconf locales

    echo "" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"
    echo "$bold  3/5 • Apply various tweaks to prepare installation$normal" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"

    # #################################### #
    # Attempt to fix the usual locale mess #
    # #################################### #

    # This function tries to fix the whole locale and perl mess about missing locale files

    # Generate at least en_US.UTF-8
    grep -q "^ *en_US.UTF-8" /etc/locale.gen || echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen

    # FIXME: here some day we should try to identify the user's lang from LANG or LC_ALL and generate the appropriate locale ...
    # (and set this lang as the default in /etc/env 3 lines below)

    locale-gen >/dev/null

    # If no /etc/environment exists, default to en_US.UTF-8
    grep -q LC_ALL /etc/environment || echo 'LC_ALL="en_US.UTF-8"' >> /etc/environment
    source /etc/environment
    export LC_ALL

    # ######################## #
    # Workarounds for fail2ban #
    # ######################## #

    # We need to create auth.log in case it does not exists, because in some situation,
    # this file does not exists, fail2ban will miserably fail to start because
    # the default fail2ban jail include the sshd jail ... >.>
    touch /var/log/auth.log

    # ######################## #
    # Workarounds for avahi    #
    # ######################## #

    # When attempting several installation of Yunohost on the same host
    # with a light VM system like LXC
    # we hit a bug with avahi-daemon postinstallation
    # This is described in detail in https://github.com/lxc/lxc/issues/25
    #
    # It makes the configure step of avahi-daemon fail, because the service does
    # start correctly. Then all other packages depending on avahi-daemon refuse to
    # configure themselves.
    #
    # The workaround we use is to generate a random uid for the avahi user, and
    # create the user with this id beforehand, so that the avahi-daemon postinst
    # script does not do it on its own. Our randomized uid has far less chances to
    # be already in use in another system than the automated one (which tries to use
    # consecutive uids).

    # Return without error if avahi already exists
    if ! id avahi > /dev/null 2>&1;
    then
        # Get a random unused uid between 500 and 999 (system-user)
        local avahi_id=$((500 + RANDOM % 500))
        while cut -d ':' -f 3 /etc/passwd | grep -q $avahi_id ;
        do
            avahi_id=$((500 + RANDOM % 500))
        done

        #info "Workaround for avahi : creating avahi user with uid $avahi_id"

        # Use the same adduser parameter as in the avahi-daemon postinst script
        # Just specify --uid explicitely
        adduser --disabled-password  --quiet --system     \
            --home /var/run/avahi-daemon --no-create-home \
            --gecos "Avahi mDNS daemon" --group avahi     \
            --uid $avahi_id
    fi

    # ########## #
    # Resolvconf #
    # ########## #

    # On some machines (e.g. OVH VPS), the /etc/resolv.conf is immutable
    # We need to make it mutable for the resolvconf dependency to be installed
    chattr -i /etc/resolv.conf 2>/dev/null || true

    # Done
    printf "$resetline    $bold${green}Done$normal"
}

function setup_package_source() {

    echo "" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"
    echo "$bold  4/5 • Adding YunoHost repository to apt$normal" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"

    local CUSTOMAPT=/etc/apt/sources.list.d/yunohost.list

    # Debian repository

    local CUSTOMDEB="deb [signed-by=/usr/share/keyrings/yunohost-bookworm.gpg] http://forge.yunohost.org/debian/ bookworm stable"

    if [[ "$DISTRIB" == "stable" ]] ; then
        echo "$CUSTOMDEB" > $CUSTOMAPT
    elif [[ "$DISTRIB" == "testing" ]] ; then
        echo "$CUSTOMDEB testing" > $CUSTOMAPT
    elif [[ "$DISTRIB" == "unstable" ]] ; then
        echo "$CUSTOMDEB testing unstable" > $CUSTOMAPT
    fi

    # Add YunoHost repository key to the keyring
    curl --fail --silent https://forge.yunohost.org/yunohost_bookworm.asc | gpg --dearmor > /usr/share/keyrings/yunohost-bookworm.gpg
    apt_update
}

function install_yunohost_packages() {

    echo "" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"
    echo "$bold  5/5 • Installing YunoHost$normal" | tee -a "$YUNOHOST_LOG"
    echo "" | tee -a "$YUNOHOST_LOG"

    debconf-set-selections << EOF
slapd slapd/password1      password yunohost
slapd slapd/password2      password yunohost
slapd slapd/domain         string   yunohost.org
slapd shared/organization  string   yunohost.org
slapd slapd/allow_ldap_v2  boolean  false
slapd slapd/invalid_config boolean  true
slapd slapd/backend        select   MDB
postfix postfix/main_mailer_type select Internet Site
postfix postfix/mailname         string /etc/mailname
nslcd nslcd/ldap-bindpw    password
nslcd nslcd/ldap-starttls  boolean   false
nslcd nslcd/ldap-reqcert   select
nslcd nslcd/ldap-uris      string    ldap://localhost/
nslcd nslcd/ldap-binddn    string
nslcd nslcd/ldap-base      string    dc=yunohost,dc=org
libnss-ldapd libnss-ldapd/nsswitch multiselect group, passwd, shadow
postsrsd postsrsd/domain string yunohost.org
EOF

    # Allow sudo removal even if no root password has been set (on some DO
    # droplet or Vagrant virtual machines), as YunoHost use sudo-ldap
    export SUDO_FORCE_REMOVE=yes

    # Install YunoHost
    # FIXME : do we still want to install recommends ?
    apt_install                              \
        -o APT::install-recommends=true      \
        yunohost yunohost-admin postfix      \
    || return 1

}

function conclusion() {
    # Get first local IP and global IP
    local local_ip
    local_ip=$(hostname --all-ip-address | tr ' ' '\n' | grep -v ":" | head -n1)
    local global_ip
    global_ip=$(curl https://ip.yunohost.org 2>/dev/null)
    local no_ip=""

    # Will ignore local ip if it's already the global IP (e.g. for some VPS)
    [[ "$local_ip" != "$global_ip" ]] || local_ip=""

    # Formatting
    local width=79
    [[ -z "$local_ip" ]] || {
        local_ip=$(echo -e "\n  │    - https://$local_ip/ (local IP, if self-hosting at home)")
        local nb_spaces=$(( width - ${#local_ip} ))
        local_ip+="$(printf "%${nb_spaces}s")│"
    }
    [[ -z "$global_ip" ]] || {
        global_ip=$(echo -e "\n  │    - https://$global_ip/ (global IP, if you're on a VPS)")
        local nb_spaces=$(( width - ${#global_ip} ))
        global_ip+="$(printf "%${nb_spaces}s")│"
    }
    [[ -n "$local_ip" ]] || [[ -n "$global_ip" ]] || {
        no_ip=$(echo -e "\n  │    - (no local nor global IP detected ?)")
        local nb_spaces=$(( width - ${#no_ip} ))
        no_ip+="$(printf "%${nb_spaces}s")│"
    }

    cat << EOF | tee -a "$YUNOHOST_LOG"


  🎉 ${bold}YunoHost installation completed!$normal

  ╭───────────────────────────────────────────────────────────────────────────╮
  │ You should now proceed with Yunohost post-installation.                   │
  │ This is where you will be asked for:                                      │
  │ • the main domain of your server ;                                        │
  │ • the administration password ;                                           │
  │ • the name and password of the first user, which will also be admin.      │
  │                                                                           │
  │ You can perform this step, either:                                        │
  │ • from the command line, by running 'yunohost tools postinstall' as root  │
  │ • or from your web browser, by accessing :                                │${local_ip}${global_ip}${no_ip}
  │                                                                           │
  │ If this is your first time with YunoHost, it is strongly recommended to   │
  │ take time to read the administator documentation and in particular the    │
  │ sections 'Finalizing your setup' and 'Getting to know YunoHost'.          │
  │                                                                           │
  │ It is available at the following URL : ➡️  https://yunohost.org/admindoc   │
  ╰───────────────────────────────────────────────────────────────────────────╯


EOF
}

###############################################################################
# Raspbian specific stuff                                                     #
###############################################################################

function is_raspbian() {
    # On Raspbian image lsb_release is available
    if [[ "$(lsb_release -i -s 2> /dev/null)" != "Raspbian" ]] ;
    then
        return 1
    fi
    return 0
}

###############################################################################
# Image building specific stuff                                               #
###############################################################################

function clean_image() {
    {
        # Delete SSH keys
        rm -f /etc/ssh/ssh_host_*
        yes | ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa
        yes | ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa
        yes | ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -N '' -t ecdsa -b 521

        # Deleting logs ...
        find /var/log -type f -exec rm {} \;

        # Purging apt ...
        apt-get clean
    } >> "$YUNOHOST_LOG" 2>&1
}


###############################################################################

main "$@"