mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge branch 'unstable' into default_version
This commit is contained in:
commit
3fbcd1f110
19 changed files with 173 additions and 93 deletions
22
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
22
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
## The problem
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
## PR Status
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
## How to test
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- [ ] Principle agreement 0/2 :
|
||||||
|
- [ ] Quick review 0/1 :
|
||||||
|
- [ ] Simple test 0/1 :
|
||||||
|
- [ ] Deep review 0/1 :
|
|
@ -22,12 +22,12 @@ ynh_use_logrotate () {
|
||||||
fi
|
fi
|
||||||
if [ $# -gt 0 ]; then
|
if [ $# -gt 0 ]; then
|
||||||
if [ "$(echo ${1##*.})" == "log" ]; then # Keep only the extension to check if it's a logfile
|
if [ "$(echo ${1##*.})" == "log" ]; then # Keep only the extension to check if it's a logfile
|
||||||
logfile=$1 # In this case, focus logrotate on the logfile
|
local logfile=$1 # In this case, focus logrotate on the logfile
|
||||||
else
|
else
|
||||||
logfile=$1/*.log # Else, uses the directory and all logfile into it.
|
local logfile=$1/*.log # Else, uses the directory and all logfile into it.
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
|
local logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
|
||||||
fi
|
fi
|
||||||
cat > ./${app}-logrotate << EOF # Build a config file for logrotate
|
cat > ./${app}-logrotate << EOF # Build a config file for logrotate
|
||||||
$logfile {
|
$logfile {
|
||||||
|
@ -97,7 +97,7 @@ ynh_add_systemd_config () {
|
||||||
#
|
#
|
||||||
# usage: ynh_remove_systemd_config
|
# usage: ynh_remove_systemd_config
|
||||||
ynh_remove_systemd_config () {
|
ynh_remove_systemd_config () {
|
||||||
finalsystemdconf="/etc/systemd/system/$app.service"
|
local finalsystemdconf="/etc/systemd/system/$app.service"
|
||||||
if [ -e "$finalsystemdconf" ]; then
|
if [ -e "$finalsystemdconf" ]; then
|
||||||
sudo systemctl stop $app
|
sudo systemctl stop $app
|
||||||
sudo systemctl disable $app
|
sudo systemctl disable $app
|
||||||
|
@ -124,7 +124,7 @@ ynh_add_nginx_config () {
|
||||||
# Substitute in a nginx config file only if the variable is not empty
|
# Substitute in a nginx config file only if the variable is not empty
|
||||||
if test -n "${path_url:-}"; then
|
if test -n "${path_url:-}"; then
|
||||||
# path_url_slash_less is path_url, or a blank value if path_url is only '/'
|
# path_url_slash_less is path_url, or a blank value if path_url is only '/'
|
||||||
path_url_slash_less=${path_url%/}
|
local path_url_slash_less=${path_url%/}
|
||||||
ynh_replace_string "__PATH__/" "$path_url_slash_less/" "$finalnginxconf"
|
ynh_replace_string "__PATH__/" "$path_url_slash_less/" "$finalnginxconf"
|
||||||
ynh_replace_string "__PATH__" "$path_url" "$finalnginxconf"
|
ynh_replace_string "__PATH__" "$path_url" "$finalnginxconf"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -258,7 +258,7 @@ ynh_backup_if_checksum_is_different () {
|
||||||
then # Proceed only if a value was stored into the app settings
|
then # Proceed only if a value was stored into the app settings
|
||||||
if ! echo "$checksum_value $file" | sudo md5sum -c --status
|
if ! echo "$checksum_value $file" | sudo md5sum -c --status
|
||||||
then # If the checksum is now different
|
then # If the checksum is now different
|
||||||
backup_file="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
|
local backup_file="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
|
||||||
sudo mkdir -p "$(dirname "$backup_file")"
|
sudo mkdir -p "$(dirname "$backup_file")"
|
||||||
sudo cp -a "$file" "$backup_file" # Backup the current file
|
sudo cp -a "$file" "$backup_file" # Backup the current file
|
||||||
echo "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file" >&2
|
echo "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file" >&2
|
||||||
|
@ -272,8 +272,8 @@ ynh_backup_if_checksum_is_different () {
|
||||||
# usage: ynh_secure_remove path_to_remove
|
# usage: ynh_secure_remove path_to_remove
|
||||||
# | arg: path_to_remove - File or directory to remove
|
# | arg: path_to_remove - File or directory to remove
|
||||||
ynh_secure_remove () {
|
ynh_secure_remove () {
|
||||||
path_to_remove=$1
|
local path_to_remove=$1
|
||||||
forbidden_path=" \
|
local forbidden_path=" \
|
||||||
/var/www \
|
/var/www \
|
||||||
/home/yunohost.app"
|
/home/yunohost.app"
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ ynh_validate_ip()
|
||||||
{
|
{
|
||||||
# http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python#319298
|
# http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python#319298
|
||||||
|
|
||||||
IP_ADDRESS_FAMILY=$1
|
local IP_ADDRESS_FAMILY=$1
|
||||||
IP_ADDRESS=$2
|
local IP_ADDRESS=$2
|
||||||
|
|
||||||
[ "$IP_ADDRESS_FAMILY" == "4" ] || [ "$IP_ADDRESS_FAMILY" == "6" ] || return 1
|
[ "$IP_ADDRESS_FAMILY" == "4" ] || [ "$IP_ADDRESS_FAMILY" == "6" ] || return 1
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,9 @@ ynh_mysql_execute_file_as_root() {
|
||||||
# | arg: user - the user to grant privilegies
|
# | arg: user - the user to grant privilegies
|
||||||
# | arg: pwd - the password to identify user by
|
# | arg: pwd - the password to identify user by
|
||||||
ynh_mysql_create_db() {
|
ynh_mysql_create_db() {
|
||||||
db=$1
|
local db=$1
|
||||||
|
|
||||||
sql="CREATE DATABASE ${db};"
|
local sql="CREATE DATABASE ${db};"
|
||||||
|
|
||||||
# grant all privilegies to user
|
# grant all privilegies to user
|
||||||
if [[ $# -gt 1 ]]; then
|
if [[ $# -gt 1 ]]; then
|
||||||
|
@ -159,6 +159,6 @@ ynh_mysql_remove_db () {
|
||||||
# | arg: name - name to correct/sanitize
|
# | arg: name - name to correct/sanitize
|
||||||
# | ret: the corrected name
|
# | ret: the corrected name
|
||||||
ynh_sanitize_dbid () {
|
ynh_sanitize_dbid () {
|
||||||
dbid=${1//[-.]/_} # We should avoid having - and . in the name of databases. They are replaced by _
|
local dbid=${1//[-.]/_} # We should avoid having - and . in the name of databases. They are replaced by _
|
||||||
echo $dbid
|
echo $dbid
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
# usage: ynh_normalize_url_path path_to_normalize
|
# usage: ynh_normalize_url_path path_to_normalize
|
||||||
# | arg: url_path_to_normalize - URL path to normalize before using it
|
# | arg: url_path_to_normalize - URL path to normalize before using it
|
||||||
ynh_normalize_url_path () {
|
ynh_normalize_url_path () {
|
||||||
path_url=$1
|
local path_url=$1
|
||||||
test -n "$path_url" || ynh_die "ynh_normalize_url_path expect a URL path as first argument and received nothing."
|
test -n "$path_url" || ynh_die "ynh_normalize_url_path expect a URL path as first argument and received nothing."
|
||||||
if [ "${path_url:0:1}" != "/" ]; then # If the first character is not a /
|
if [ "${path_url:0:1}" != "/" ]; then # If the first character is not a /
|
||||||
path_url="/$path_url" # Add / at begin of path variable
|
path_url="/$path_url" # Add / at begin of path variable
|
||||||
|
@ -29,7 +29,7 @@ ynh_normalize_url_path () {
|
||||||
# usage: ynh_find_port begin_port
|
# usage: ynh_find_port begin_port
|
||||||
# | arg: begin_port - port to start to search
|
# | arg: begin_port - port to start to search
|
||||||
ynh_find_port () {
|
ynh_find_port () {
|
||||||
port=$1
|
local port=$1
|
||||||
test -n "$port" || ynh_die "The argument of ynh_find_port must be a valid port."
|
test -n "$port" || ynh_die "The argument of ynh_find_port must be a valid port."
|
||||||
while netcat -z 127.0.0.1 $port # Check if the port is free
|
while netcat -z 127.0.0.1 $port # Check if the port is free
|
||||||
do
|
do
|
||||||
|
|
|
@ -80,15 +80,15 @@ ynh_package_autopurge() {
|
||||||
# usage: ynh_package_install_from_equivs controlfile
|
# usage: ynh_package_install_from_equivs controlfile
|
||||||
# | arg: controlfile - path of the equivs control file
|
# | arg: controlfile - path of the equivs control file
|
||||||
ynh_package_install_from_equivs () {
|
ynh_package_install_from_equivs () {
|
||||||
controlfile=$1
|
local controlfile=$1
|
||||||
|
|
||||||
# Check if the equivs package is installed. Or install it.
|
# Check if the equivs package is installed. Or install it.
|
||||||
ynh_package_is_installed 'equivs' \
|
ynh_package_is_installed 'equivs' \
|
||||||
|| ynh_package_install equivs
|
|| ynh_package_install equivs
|
||||||
|
|
||||||
# retrieve package information
|
# retrieve package information
|
||||||
pkgname=$(grep '^Package: ' $controlfile | cut -d' ' -f 2) # Retrieve the name of the debian package
|
local pkgname=$(grep '^Package: ' $controlfile | cut -d' ' -f 2) # Retrieve the name of the debian package
|
||||||
pkgversion=$(grep '^Version: ' $controlfile | cut -d' ' -f 2) # And its version number
|
local pkgversion=$(grep '^Version: ' $controlfile | cut -d' ' -f 2) # And its version number
|
||||||
[[ -z "$pkgname" || -z "$pkgversion" ]] \
|
[[ -z "$pkgname" || -z "$pkgversion" ]] \
|
||||||
&& echo "Invalid control file" && exit 1 # Check if this 2 variables aren't empty.
|
&& echo "Invalid control file" && exit 1 # Check if this 2 variables aren't empty.
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ ynh_package_install_from_equivs () {
|
||||||
ynh_package_update
|
ynh_package_update
|
||||||
|
|
||||||
# Build and install the package
|
# Build and install the package
|
||||||
TMPDIR=$(mktemp -d)
|
local TMPDIR=$(mktemp -d)
|
||||||
# Note that the cd executes into a sub shell
|
# Note that the cd executes into a sub shell
|
||||||
# Create a fake deb package with equivs-build and the given control file
|
# Create a fake deb package with equivs-build and the given control file
|
||||||
# Install the fake package without its dependencies with dpkg
|
# Install the fake package without its dependencies with dpkg
|
||||||
|
@ -118,16 +118,17 @@ ynh_package_install_from_equivs () {
|
||||||
# usage: ynh_install_app_dependencies dep [dep [...]]
|
# usage: ynh_install_app_dependencies dep [dep [...]]
|
||||||
# | arg: dep - the package name to install in dependence
|
# | arg: dep - the package name to install in dependence
|
||||||
ynh_install_app_dependencies () {
|
ynh_install_app_dependencies () {
|
||||||
dependencies=$@
|
local dependencies=$@
|
||||||
manifest_path="../manifest.json"
|
local manifest_path="../manifest.json"
|
||||||
if [ ! -e "$manifest_path" ]; then
|
if [ ! -e "$manifest_path" ]; then
|
||||||
manifest_path="../settings/manifest.json" # Into the restore script, the manifest is not at the same place
|
manifest_path="../settings/manifest.json" # Into the restore script, the manifest is not at the same place
|
||||||
fi
|
fi
|
||||||
version=$(grep '\"version\": ' "$manifest_path" | cut -d '"' -f 4) # Retrieve the version number in the manifest file.
|
|
||||||
|
local version=$(grep '\"version\": ' "$manifest_path" | cut -d '"' -f 4) # Retrieve the version number in the manifest file.
|
||||||
if [ ${#version} -eq 0 ]; then
|
if [ ${#version} -eq 0 ]; then
|
||||||
version="1.0"
|
version="1.0"
|
||||||
fi
|
fi
|
||||||
dep_app=${app//_/-} # Replace all '_' by '-'
|
local dep_app=${app//_/-} # Replace all '_' by '-'
|
||||||
|
|
||||||
cat > /tmp/${dep_app}-ynh-deps.control << EOF # Make a control file for equivs-build
|
cat > /tmp/${dep_app}-ynh-deps.control << EOF # Make a control file for equivs-build
|
||||||
Section: misc
|
Section: misc
|
||||||
|
@ -151,6 +152,6 @@ EOF
|
||||||
#
|
#
|
||||||
# usage: ynh_remove_app_dependencies
|
# usage: ynh_remove_app_dependencies
|
||||||
ynh_remove_app_dependencies () {
|
ynh_remove_app_dependencies () {
|
||||||
dep_app=${app//_/-} # Replace all '_' by '-'
|
local dep_app=${app//_/-} # Replace all '_' by '-'
|
||||||
ynh_package_autopurge ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used.
|
ynh_package_autopurge ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used.
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ ynh_die() {
|
||||||
# Simply duplicate the log, execute the yunohost command and replace the log without the result of this command
|
# Simply duplicate the log, execute the yunohost command and replace the log without the result of this command
|
||||||
# It's a very badly hack...
|
# It's a very badly hack...
|
||||||
ynh_no_log() {
|
ynh_no_log() {
|
||||||
ynh_cli_log=/var/log/yunohost/yunohost-cli.log
|
local ynh_cli_log=/var/log/yunohost/yunohost-cli.log
|
||||||
sudo cp -a ${ynh_cli_log} ${ynh_cli_log}-move
|
sudo cp -a ${ynh_cli_log} ${ynh_cli_log}-move
|
||||||
eval $@
|
eval $@
|
||||||
exit_code=$?
|
local exit_code=$?
|
||||||
sudo mv ${ynh_cli_log}-move ${ynh_cli_log}
|
sudo mv ${ynh_cli_log}-move ${ynh_cli_log}
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,27 @@ ynh_string_random() {
|
||||||
# (see sed manual page for more information)
|
# (see sed manual page for more information)
|
||||||
ynh_replace_string () {
|
ynh_replace_string () {
|
||||||
local delimit=@
|
local delimit=@
|
||||||
|
local match_string=$1
|
||||||
|
local replace_string=$2
|
||||||
|
local workfile=$
|
||||||
|
|
||||||
|
# Escape the delimiter if it's in the string.
|
||||||
|
match_string=${match_string//${delimit}/"\\${delimit}"}
|
||||||
|
replace_string=${replace_string//${delimit}/"\\${delimit}"}
|
||||||
|
|
||||||
|
sudo sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$workfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Substitute/replace a special string by another in a file
|
||||||
|
#
|
||||||
|
# usage: ynh_replace_special_string match_string replace_string target_file
|
||||||
|
# | arg: match_string - String to be searched and replaced in the file
|
||||||
|
# | arg: replace_string - String that will replace matches
|
||||||
|
# | arg: target_file - File in which the string will be replaced.
|
||||||
|
#
|
||||||
|
# This helper will use ynh_replace_string, but as you can use special
|
||||||
|
# characters, you can't use some regular expressions and sub-expressions.
|
||||||
|
ynh_replace_special_string () {
|
||||||
local match_string=$1
|
local match_string=$1
|
||||||
local replace_string=$2
|
local replace_string=$2
|
||||||
local workfile=$3
|
local workfile=$3
|
||||||
|
@ -34,9 +55,5 @@ ynh_replace_string () {
|
||||||
match_string=${match_string//&/"\&"}
|
match_string=${match_string//&/"\&"}
|
||||||
replace_string=${replace_string//&/"\&"}
|
replace_string=${replace_string//&/"\&"}
|
||||||
|
|
||||||
# Escape the delimiter if it's in the string.
|
ynh_replace_string "$match_string" "$replace_string" "$workfile"
|
||||||
match_string=${match_string//${delimit}/"\\${delimit}"}
|
|
||||||
replace_string=${replace_string//${delimit}/"\\${delimit}"}
|
|
||||||
|
|
||||||
sudo sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$workfile"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# Usage: ynh_exit_properly is used only by the helper ynh_abort_if_errors.
|
# Usage: ynh_exit_properly is used only by the helper ynh_abort_if_errors.
|
||||||
# You must not use it directly.
|
# You must not use it directly.
|
||||||
ynh_exit_properly () {
|
ynh_exit_properly () {
|
||||||
exit_code=$?
|
local exit_code=$?
|
||||||
if [ "$exit_code" -eq 0 ]; then
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
exit 0 # Exit without error if the script ended correctly
|
exit 0 # Exit without error if the script ended correctly
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -48,9 +48,9 @@ ynh_system_user_create () {
|
||||||
if ! ynh_system_user_exists "$1" # Check if the user exists on the system
|
if ! ynh_system_user_exists "$1" # Check if the user exists on the system
|
||||||
then # If the user doesn't exist
|
then # If the user doesn't exist
|
||||||
if [ $# -ge 2 ]; then # If a home dir is mentioned
|
if [ $# -ge 2 ]; then # If a home dir is mentioned
|
||||||
user_home_dir="-d $2"
|
local user_home_dir="-d $2"
|
||||||
else
|
else
|
||||||
user_home_dir="--no-create-home"
|
local user_home_dir="--no-create-home"
|
||||||
fi
|
fi
|
||||||
sudo useradd $user_home_dir --system --user-group $1 --shell /usr/sbin/nologin || ynh_die "Unable to create $1 system account"
|
sudo useradd $user_home_dir --system --user-group $1 --shell /usr/sbin/nologin || ynh_die "Unable to create $1 system account"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
# usage: ynh_get_plain_key key [subkey [subsubkey ...]]
|
# usage: ynh_get_plain_key key [subkey [subsubkey ...]]
|
||||||
# | ret: string - the key's value
|
# | ret: string - the key's value
|
||||||
ynh_get_plain_key() {
|
ynh_get_plain_key() {
|
||||||
prefix="#"
|
local prefix="#"
|
||||||
founded=0
|
local founded=0
|
||||||
key=$1
|
local key=$1
|
||||||
shift
|
shift
|
||||||
while read line; do
|
while read line; do
|
||||||
if [[ "$founded" == "1" ]] ; then
|
if [[ "$founded" == "1" ]] ; then
|
||||||
|
@ -36,7 +36,7 @@ ynh_get_plain_key() {
|
||||||
#
|
#
|
||||||
ynh_restore_upgradebackup () {
|
ynh_restore_upgradebackup () {
|
||||||
echo "Upgrade failed." >&2
|
echo "Upgrade failed." >&2
|
||||||
app_bck=${app//_/-} # Replace all '_' by '-'
|
local app_bck=${app//_/-} # Replace all '_' by '-'
|
||||||
|
|
||||||
# Check if an existing backup can be found before removing and restoring the application.
|
# Check if an existing backup can be found before removing and restoring the application.
|
||||||
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number
|
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number
|
||||||
|
@ -64,9 +64,9 @@ ynh_backup_before_upgrade () {
|
||||||
echo "This app doesn't have any backup script." >&2
|
echo "This app doesn't have any backup script." >&2
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
backup_number=1
|
local backup_number=1
|
||||||
old_backup_number=2
|
local old_backup_number=2
|
||||||
app_bck=${app//_/-} # Replace all '_' by '-'
|
local app_bck=${app//_/-} # Replace all '_' by '-'
|
||||||
|
|
||||||
# Check if a backup already exists with the prefix 1
|
# Check if a backup already exists with the prefix 1
|
||||||
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade1
|
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade1
|
||||||
|
@ -216,10 +216,11 @@ ynh_setup_source () {
|
||||||
# | arg: ... - (Optionnal) More POST keys and values
|
# | arg: ... - (Optionnal) More POST keys and values
|
||||||
ynh_local_curl () {
|
ynh_local_curl () {
|
||||||
# Define url of page to curl
|
# Define url of page to curl
|
||||||
full_page_url=https://localhost$path_url$1
|
local full_page_url=https://localhost$path_url$1
|
||||||
|
|
||||||
# Concatenate all other arguments with '&' to prepare POST data
|
# Concatenate all other arguments with '&' to prepare POST data
|
||||||
POST_data=""
|
local POST_data=""
|
||||||
|
local arg=""
|
||||||
for arg in "${@:2}"
|
for arg in "${@:2}"
|
||||||
do
|
do
|
||||||
POST_data="${POST_data}${arg}&"
|
POST_data="${POST_data}${arg}&"
|
||||||
|
|
|
@ -66,6 +66,9 @@ PrintLastLog yes
|
||||||
TCPKeepAlive yes
|
TCPKeepAlive yes
|
||||||
#UseLogin no
|
#UseLogin no
|
||||||
|
|
||||||
|
# keep ssh sessions fresh
|
||||||
|
ClientAliveInterval 60
|
||||||
|
|
||||||
#MaxStartups 10:30:60
|
#MaxStartups 10:30:60
|
||||||
Banner /etc/issue.net
|
Banner /etc/issue.net
|
||||||
|
|
||||||
|
|
|
@ -16,24 +16,26 @@
|
||||||
"app_change_url_success": "Successfully changed {app:s} url to {domain:s}{path:s}",
|
"app_change_url_success": "Successfully changed {app:s} url to {domain:s}{path:s}",
|
||||||
"app_extraction_failed": "Unable to extract installation files",
|
"app_extraction_failed": "Unable to extract installation files",
|
||||||
"app_id_invalid": "Invalid app id",
|
"app_id_invalid": "Invalid app id",
|
||||||
"app_incompatible": "The app is incompatible with your YunoHost version",
|
"app_incompatible": "The app {app} is incompatible with your YunoHost version",
|
||||||
"app_install_files_invalid": "Invalid installation files",
|
"app_install_files_invalid": "Invalid installation files",
|
||||||
"app_location_already_used": "An app is already installed in this location",
|
"app_location_already_used": "The app '{app}' is already installed on that location ({path})",
|
||||||
"app_location_install_failed": "Unable to install the app in this location",
|
"app_make_default_location_already_used": "Can't make the app '{app}' the default on the domain {domain} is already used by the other app '{other_app}'",
|
||||||
|
"app_location_install_failed": "Unable to install the app in this location because it conflit with the app '{other_app}' already installed on '{other_path}'",
|
||||||
"app_location_unavailable": "This url is not available or conflicts with an already installed app",
|
"app_location_unavailable": "This url is not available or conflicts with an already installed app",
|
||||||
"app_manifest_invalid": "Invalid app manifest: {error}",
|
"app_manifest_invalid": "Invalid app manifest: {error}",
|
||||||
"app_no_upgrade": "No app to upgrade",
|
"app_no_upgrade": "No app to upgrade",
|
||||||
"app_not_correctly_installed": "{app:s} seems to be incorrectly installed",
|
"app_not_correctly_installed": "{app:s} seems to be incorrectly installed",
|
||||||
"app_not_installed": "{app:s} is not installed",
|
"app_not_installed": "{app:s} is not installed",
|
||||||
"app_not_properly_removed": "{app:s} has not been properly removed",
|
"app_not_properly_removed": "{app:s} has not been properly removed",
|
||||||
"app_package_need_update": "The app package needs to be updated to follow YunoHost changes",
|
"app_package_need_update": "The app {app} package needs to be updated to follow YunoHost changes",
|
||||||
"app_removed": "{app:s} has been removed",
|
"app_removed": "{app:s} has been removed",
|
||||||
"app_requirements_checking": "Checking required packages...",
|
"app_requirements_checking": "Checking required packages for {app}...",
|
||||||
"app_requirements_failed": "Unable to meet requirements: {error}",
|
"app_requirements_failed": "Unable to meet requirements for {app}: {error}",
|
||||||
"app_requirements_unmeet": "Requirements are not met, the package {pkgname} ({version}) must be {spec}",
|
"app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}",
|
||||||
"app_sources_fetch_failed": "Unable to fetch sources files",
|
"app_sources_fetch_failed": "Unable to fetch sources files",
|
||||||
"app_unknown": "Unknown app",
|
"app_unknown": "Unknown app",
|
||||||
"app_unsupported_remote_type": "Unsupported remote type used for the app",
|
"app_unsupported_remote_type": "Unsupported remote type used for the app",
|
||||||
|
"app_upgrade_app_name": "Upgrading app {app}...",
|
||||||
"app_upgrade_failed": "Unable to upgrade {app:s}",
|
"app_upgrade_failed": "Unable to upgrade {app:s}",
|
||||||
"app_upgrade_some_app_failed": "Unable to upgrade some applications",
|
"app_upgrade_some_app_failed": "Unable to upgrade some applications",
|
||||||
"app_upgraded": "{app:s} has been upgraded",
|
"app_upgraded": "{app:s} has been upgraded",
|
||||||
|
|
|
@ -330,6 +330,9 @@ def app_info(app, show_status=False, raw=False):
|
||||||
if not _is_installed(app):
|
if not _is_installed(app):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('app_not_installed', app=app))
|
m18n.n('app_not_installed', app=app))
|
||||||
|
|
||||||
|
app_setting_path = APPS_SETTING_PATH + app
|
||||||
|
|
||||||
if raw:
|
if raw:
|
||||||
ret = app_list(filter=app, raw=True)[app]
|
ret = app_list(filter=app, raw=True)[app]
|
||||||
ret['settings'] = _get_app_settings(app)
|
ret['settings'] = _get_app_settings(app)
|
||||||
|
@ -345,11 +348,10 @@ def app_info(app, show_status=False, raw=False):
|
||||||
upgradable = "no"
|
upgradable = "no"
|
||||||
|
|
||||||
ret['upgradable'] = upgradable
|
ret['upgradable'] = upgradable
|
||||||
|
ret['change_url'] = os.path.exists(os.path.join(app_setting_path, "scripts", "change_url"))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
app_setting_path = APPS_SETTING_PATH + app
|
|
||||||
|
|
||||||
# Retrieve manifest and status
|
# Retrieve manifest and status
|
||||||
with open(app_setting_path + '/manifest.json') as f:
|
with open(app_setting_path + '/manifest.json') as f:
|
||||||
manifest = json.loads(str(f.read()))
|
manifest = json.loads(str(f.read()))
|
||||||
|
@ -555,6 +557,7 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
logger.info("Upgrading apps %s", ", ".join(app))
|
logger.info("Upgrading apps %s", ", ".join(app))
|
||||||
|
|
||||||
for app_instance_name in apps:
|
for app_instance_name in apps:
|
||||||
|
logger.warning(m18n.n('app_upgrade_app_name', app=app_instance_name))
|
||||||
installed = _is_installed(app_instance_name)
|
installed = _is_installed(app_instance_name)
|
||||||
if not installed:
|
if not installed:
|
||||||
raise MoulinetteError(errno.ENOPKG,
|
raise MoulinetteError(errno.ENOPKG,
|
||||||
|
@ -580,7 +583,7 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Check requirements
|
# Check requirements
|
||||||
_check_manifest_requirements(manifest)
|
_check_manifest_requirements(manifest, app_instance_name=app_instance_name)
|
||||||
|
|
||||||
app_setting_path = APPS_SETTING_PATH + '/' + app_instance_name
|
app_setting_path = APPS_SETTING_PATH + '/' + app_instance_name
|
||||||
|
|
||||||
|
@ -621,10 +624,13 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
with open(app_setting_path + '/status.json', 'w+') as f:
|
with open(app_setting_path + '/status.json', 'w+') as f:
|
||||||
json.dump(status, f)
|
json.dump(status, f)
|
||||||
|
|
||||||
# Replace scripts and manifest
|
# Replace scripts and manifest and conf (if exists)
|
||||||
os.system('rm -rf "%s/scripts" "%s/manifest.json"' % (app_setting_path, app_setting_path))
|
os.system('rm -rf "%s/scripts" "%s/manifest.json %s/conf"' % (app_setting_path, app_setting_path, app_setting_path))
|
||||||
os.system('mv "%s/manifest.json" "%s/scripts" %s' % (extracted_app_folder, extracted_app_folder, app_setting_path))
|
os.system('mv "%s/manifest.json" "%s/scripts" %s' % (extracted_app_folder, extracted_app_folder, app_setting_path))
|
||||||
|
|
||||||
|
if os.path.exists(os.path.join(extracted_app_folder, "conf")):
|
||||||
|
os.system('cp -R %s/conf %s' % (extracted_app_folder, app_setting_path))
|
||||||
|
|
||||||
# So much win
|
# So much win
|
||||||
upgraded_apps.append(app_instance_name)
|
upgraded_apps.append(app_instance_name)
|
||||||
logger.success(m18n.n('app_upgraded', app=app_instance_name))
|
logger.success(m18n.n('app_upgraded', app=app_instance_name))
|
||||||
|
@ -683,7 +689,7 @@ def app_install(auth, app, label=None, args=None, no_remove_on_failure=False):
|
||||||
app_id = manifest['id']
|
app_id = manifest['id']
|
||||||
|
|
||||||
# Check requirements
|
# Check requirements
|
||||||
_check_manifest_requirements(manifest)
|
_check_manifest_requirements(manifest, app_id)
|
||||||
|
|
||||||
# Check if app can be forked
|
# Check if app can be forked
|
||||||
instance_number = _installed_instance_number(app_id, last=True) + 1
|
instance_number = _installed_instance_number(app_id, last=True) + 1
|
||||||
|
@ -733,6 +739,9 @@ def app_install(auth, app, label=None, args=None, no_remove_on_failure=False):
|
||||||
os.system('cp %s/manifest.json %s' % (extracted_app_folder, app_setting_path))
|
os.system('cp %s/manifest.json %s' % (extracted_app_folder, app_setting_path))
|
||||||
os.system('cp -R %s/scripts %s' % (extracted_app_folder, app_setting_path))
|
os.system('cp -R %s/scripts %s' % (extracted_app_folder, app_setting_path))
|
||||||
|
|
||||||
|
if os.path.exists(os.path.join(extracted_app_folder, "conf")):
|
||||||
|
os.system('cp -R %s/conf %s' % (extracted_app_folder, app_setting_path))
|
||||||
|
|
||||||
# Execute the app install script
|
# Execute the app install script
|
||||||
install_retcode = 1
|
install_retcode = 1
|
||||||
try:
|
try:
|
||||||
|
@ -1016,7 +1025,9 @@ def app_makedefault(auth, app, domain=None):
|
||||||
|
|
||||||
if '/' in app_map(raw=True)[domain]:
|
if '/' in app_map(raw=True)[domain]:
|
||||||
raise MoulinetteError(errno.EEXIST,
|
raise MoulinetteError(errno.EEXIST,
|
||||||
m18n.n('app_location_already_used'))
|
m18n.n('app_make_default_location_already_used',
|
||||||
|
app=app, domain=app_domain,
|
||||||
|
other_app=app_map(raw=True)[domain]["/"]["id"]))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
||||||
|
@ -1169,10 +1180,13 @@ def app_checkurl(auth, url, app=None):
|
||||||
continue
|
continue
|
||||||
if path == p:
|
if path == p:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('app_location_already_used'))
|
m18n.n('app_location_already_used',
|
||||||
|
app=a["id"], path=path))
|
||||||
|
# can't install "/a/b/" if "/a/" exists
|
||||||
elif path.startswith(p) or p.startswith(path):
|
elif path.startswith(p) or p.startswith(path):
|
||||||
raise MoulinetteError(errno.EPERM,
|
raise MoulinetteError(errno.EPERM,
|
||||||
m18n.n('app_location_install_failed'))
|
m18n.n('app_location_install_failed',
|
||||||
|
other_path=p, other_app=a['id']))
|
||||||
|
|
||||||
if app is not None and not installed:
|
if app is not None and not installed:
|
||||||
app_setting(app, 'domain', value=domain)
|
app_setting(app, 'domain', value=domain)
|
||||||
|
@ -1689,7 +1703,7 @@ def _encode_string(value):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def _check_manifest_requirements(manifest):
|
def _check_manifest_requirements(manifest, app_instance_name):
|
||||||
"""Check if required packages are met from the manifest"""
|
"""Check if required packages are met from the manifest"""
|
||||||
requirements = manifest.get('requirements', dict())
|
requirements = manifest.get('requirements', dict())
|
||||||
|
|
||||||
|
@ -1707,12 +1721,12 @@ def _check_manifest_requirements(manifest):
|
||||||
if (not yunohost_req or
|
if (not yunohost_req or
|
||||||
not packages.SpecifierSet(yunohost_req) & '>= 2.3.6'):
|
not packages.SpecifierSet(yunohost_req) & '>= 2.3.6'):
|
||||||
raise MoulinetteError(errno.EINVAL, '{0}{1}'.format(
|
raise MoulinetteError(errno.EINVAL, '{0}{1}'.format(
|
||||||
m18n.g('colon', m18n.n('app_incompatible')),
|
m18n.g('colon', m18n.n('app_incompatible'), app=app_instance_name),
|
||||||
m18n.n('app_package_need_update')))
|
m18n.n('app_package_need_update', app=app_instance_name)))
|
||||||
elif not requirements:
|
elif not requirements:
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info(m18n.n('app_requirements_checking'))
|
logger.info(m18n.n('app_requirements_checking', app=app_instance_name))
|
||||||
|
|
||||||
# Retrieve versions of each required package
|
# Retrieve versions of each required package
|
||||||
try:
|
try:
|
||||||
|
@ -1721,7 +1735,7 @@ def _check_manifest_requirements(manifest):
|
||||||
except packages.PackageException as e:
|
except packages.PackageException as e:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('app_requirements_failed',
|
m18n.n('app_requirements_failed',
|
||||||
error=str(e)))
|
error=str(e), app=app_instance_name))
|
||||||
|
|
||||||
# Iterate over requirements
|
# Iterate over requirements
|
||||||
for pkgname, spec in requirements.items():
|
for pkgname, spec in requirements.items():
|
||||||
|
@ -1730,7 +1744,7 @@ def _check_manifest_requirements(manifest):
|
||||||
raise MoulinetteError(
|
raise MoulinetteError(
|
||||||
errno.EINVAL, m18n.n('app_requirements_unmeet',
|
errno.EINVAL, m18n.n('app_requirements_unmeet',
|
||||||
pkgname=pkgname, version=version,
|
pkgname=pkgname, version=version,
|
||||||
spec=spec))
|
spec=spec, app=app_instance_name))
|
||||||
|
|
||||||
|
|
||||||
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
||||||
|
|
|
@ -188,17 +188,17 @@ def domain_dns_conf(domain, ttl=None):
|
||||||
|
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
result += "# Basic ipv4/ipv6 records"
|
result += "; Basic ipv4/ipv6 records"
|
||||||
for record in dns_conf["basic"]:
|
for record in dns_conf["basic"]:
|
||||||
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
||||||
|
|
||||||
result += "\n\n"
|
result += "\n\n"
|
||||||
result += "# XMPP"
|
result += "; XMPP"
|
||||||
for record in dns_conf["xmpp"]:
|
for record in dns_conf["xmpp"]:
|
||||||
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
||||||
|
|
||||||
result += "\n\n"
|
result += "\n\n"
|
||||||
result += "# Mail"
|
result += "; Mail"
|
||||||
for record in dns_conf["mail"]:
|
for record in dns_conf["mail"]:
|
||||||
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
||||||
|
|
||||||
|
|
|
@ -498,15 +498,12 @@ def _run_service_command(action, service):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('service_unknown', service=service))
|
raise MoulinetteError(errno.EINVAL, m18n.n('service_unknown', service=service))
|
||||||
|
|
||||||
cmd = None
|
cmd = None
|
||||||
if action in ['start', 'stop', 'restart', 'reload']:
|
if action in ['start', 'stop', 'restart', 'reload', 'enable', 'disable']:
|
||||||
cmd = 'service %s %s' % (service, action)
|
cmd = 'systemctl %s %s' % (action, service)
|
||||||
elif action in ['enable', 'disable']:
|
|
||||||
arg = 'defaults' if action == 'enable' else 'remove'
|
|
||||||
cmd = 'update-rc.d %s %s' % (service, arg)
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown action '%s'" % action)
|
raise ValueError("Unknown action '%s'" % action)
|
||||||
|
|
||||||
need_lock = (services[service].get('need_lock') or False) \
|
need_lock = services[service].get('need_lock', False) \
|
||||||
and action in ['start', 'stop', 'restart', 'reload']
|
and action in ['start', 'stop', 'restart', 'reload']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -42,12 +42,13 @@ import apt.progress
|
||||||
from moulinette import msettings, msignals, m18n
|
from moulinette import msettings, msignals, m18n
|
||||||
from moulinette.core import MoulinetteError, init_authenticator
|
from moulinette.core import MoulinetteError, init_authenticator
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
from moulinette.utils.process import check_output
|
||||||
from moulinette.utils.filesystem import read_json, write_to_json
|
from moulinette.utils.filesystem import read_json, write_to_json
|
||||||
from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, app_list, _install_appslist_fetch_cron
|
from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, app_list, _install_appslist_fetch_cron
|
||||||
from yunohost.domain import domain_add, domain_list, get_public_ip, _get_maindomain, _set_maindomain
|
from yunohost.domain import domain_add, domain_list, get_public_ip, _get_maindomain, _set_maindomain
|
||||||
from yunohost.dyndns import _dyndns_available, _dyndns_provides
|
from yunohost.dyndns import _dyndns_available, _dyndns_provides
|
||||||
from yunohost.firewall import firewall_upnp
|
from yunohost.firewall import firewall_upnp
|
||||||
from yunohost.service import service_status, service_regen_conf, service_log
|
from yunohost.service import service_status, service_regen_conf, service_log, service_start, service_enable
|
||||||
from yunohost.monitor import monitor_disk, monitor_system
|
from yunohost.monitor import monitor_disk, monitor_system
|
||||||
from yunohost.utils.packages import ynh_packages_version
|
from yunohost.utils.packages import ynh_packages_version
|
||||||
|
|
||||||
|
@ -398,8 +399,8 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
||||||
os.system('touch /etc/yunohost/installed')
|
os.system('touch /etc/yunohost/installed')
|
||||||
|
|
||||||
# Enable and start YunoHost firewall at boot time
|
# Enable and start YunoHost firewall at boot time
|
||||||
os.system('update-rc.d yunohost-firewall enable')
|
service_enable("yunohost-firewall")
|
||||||
os.system('service yunohost-firewall start &')
|
service_start("yunohost-firewall")
|
||||||
|
|
||||||
service_regen_conf(force=True)
|
service_regen_conf(force=True)
|
||||||
logger.success(m18n.n('yunohost_configured'))
|
logger.success(m18n.n('yunohost_configured'))
|
||||||
|
@ -589,6 +590,9 @@ def tools_diagnosis(auth, private=False):
|
||||||
'swap': '%s (%s free)' % (system['memory']['swap']['total'], system['memory']['swap']['free']),
|
'swap': '%s (%s free)' % (system['memory']['swap']['total'], system['memory']['swap']['free']),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# nginx -t
|
||||||
|
diagnosis['nginx'] = check_output("nginx -t").strip().split("\n")
|
||||||
|
|
||||||
# Services status
|
# Services status
|
||||||
services = service_status()
|
services = service_status()
|
||||||
diagnosis['services'] = {}
|
diagnosis['services'] = {}
|
||||||
|
|
|
@ -414,13 +414,29 @@ def get_installed_version(*pkgnames, **kwargs):
|
||||||
if strict:
|
if strict:
|
||||||
raise UnknownPackage(pkgname)
|
raise UnknownPackage(pkgname)
|
||||||
logger.warning(m18n.n('package_unknown', pkgname=pkgname))
|
logger.warning(m18n.n('package_unknown', pkgname=pkgname))
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
version = pkg.installed.version
|
version = pkg.installed.version
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if strict:
|
if strict:
|
||||||
raise UninstalledPackage(pkgname)
|
raise UninstalledPackage(pkgname)
|
||||||
version = None
|
version = None
|
||||||
versions[pkgname] = version
|
|
||||||
|
try:
|
||||||
|
# stable, testing, unstable
|
||||||
|
repo = pkg.installed.origins[0].component
|
||||||
|
except AttributeError:
|
||||||
|
if strict:
|
||||||
|
raise UninstalledPackage(pkgname)
|
||||||
|
repo = ""
|
||||||
|
|
||||||
|
versions[pkgname] = {
|
||||||
|
"version": version,
|
||||||
|
# when we don't have component it's because it's from a local
|
||||||
|
# install or from an image (like in vagrant)
|
||||||
|
"repo": repo if repo else "local",
|
||||||
|
}
|
||||||
|
|
||||||
if len(pkgnames) == 1 and not as_dict:
|
if len(pkgnames) == 1 and not as_dict:
|
||||||
return versions[pkgnames[0]]
|
return versions[pkgnames[0]]
|
||||||
|
@ -436,6 +452,9 @@ def meets_version_specifier(pkgname, specifier):
|
||||||
# YunoHost related methods ---------------------------------------------------
|
# YunoHost related methods ---------------------------------------------------
|
||||||
|
|
||||||
def ynh_packages_version(*args, **kwargs):
|
def ynh_packages_version(*args, **kwargs):
|
||||||
|
# from cli the received arguments are:
|
||||||
|
# (Namespace(_callbacks=deque([]), _tid='_global', _to_return={}), []) {}
|
||||||
|
# they don't seem to serve any purpose
|
||||||
"""Return the version of each YunoHost package"""
|
"""Return the version of each YunoHost package"""
|
||||||
return get_installed_version(
|
return get_installed_version(
|
||||||
'yunohost', 'yunohost-admin', 'moulinette', 'ssowat',
|
'yunohost', 'yunohost-admin', 'moulinette', 'ssowat',
|
||||||
|
|
Loading…
Add table
Reference in a new issue