diff --git a/README.md b/README.md index 865fc0c..2ee59a9 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,36 @@ -Nextcloud for YunoHost ---------------------- +# Nextcloud for YunoHost + +[![Integration level](https://dash.yunohost.org/integration/nextcloud.svg)](https://dash.yunohost.org/appci/app/nextcloud) +[![Install Nextcloud with YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=nextcloud) + +> *This package allow you to install Nextcloud quickly and simply on a YunoHost server. +If you don't have YunoHost, please see [here](https://yunohost.org/#/install) to know how to install and enjoy it.* + +## Overview [Nextcloud](https://nextcloud.com) gives you freedom and control over your own data. A personal cloud which run on your own server. With Nextcloud you can synchronize your files over your devices. -**Shipped version:** 15.0.4 +**Shipped version:** 15.0.9 + +## Screenshots -[![Install Nextcloud with YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=nextcloud) ![](https://raw.githubusercontent.com/nextcloud/screenshots/master/files/Files%20Overview.png) -## Features +## Demo + +* [YunoHost demo](https://demo.yunohost.org/nextcloud/) +* [Official demo](https://demo.nextcloud.com/) + +## Configuration + +## Documentation + + * Official documentation: https://docs.nextcloud.com/server/15/user_manual/ + * YunoHost documentation: https://github.com/YunoHost/doc/blob/master/app_nextcloud_fr.md + +## YunoHost specific features In addition to Nextcloud core features, the following are made available with this package: @@ -23,6 +43,14 @@ this package: * Serve `/.well-known` paths for CalDAV and CardDAV on the domain only if it's not already served - i.e. by Baïkal +#### Multi-users support + +#### Supported architectures + +* x86-64b - [![Build Status](https://ci-apps.yunohost.org/ci/logs/nextcloud%20%28Apps%29.svg)](https://ci-apps.yunohost.org/ci/apps/nextcloud/) +* ARMv8-A - [![Build Status](https://ci-apps-arm.yunohost.org/ci/logs/nextcloud%20%28Apps%29.svg)](https://ci-apps-arm.yunohost.org/ci/apps/nextcloud/) +* Jessie x86-64b - [![Build Status](https://ci-stretch.nohost.me/ci/logs/nextcloud%20%28Apps%29.svg)](https://ci-stretch.nohost.me/ci/apps/nextcloud/) + ## Limitations To integrate the logout button to the SSO, we have to patch Nextcloud sources. @@ -38,7 +66,9 @@ Finally, the following error message in Nextcloud logs can be safely ignored: Following symlinks is not allowed ('/home/yunohost.multimedia/user/Share' -> '/home/yunohost.multimedia/share/' not inside '/home/yunohost.multimedia/user/') ``` -## Migrate from ownCloud +## Additionnal informations + +#### Migrate from ownCloud **This is not considered as stable yet, please do it with care and only for testing!** @@ -51,10 +81,10 @@ This can only be done from the command-line interface - e.g. through SSH. Once you're connected, you simply have to execute the following: ```bash -sudo yunohost app upgrade -u https://github.com/YunoHost-Apps/nextcloud_ynh owncloud --verbose +sudo yunohost app upgrade -u https://github.com/YunoHost-Apps/nextcloud_ynh owncloud --debug ``` -The `--verbose` option will let you see the full output. If you encounter any +The `--debug` option will let you see the full output. If you encounter any issue, please paste it. Note that a cron job will be executed at some time after the end of this @@ -72,6 +102,21 @@ sudo yunohost app ssowatconf ## Links - * Report a bug: https://dev.yunohost.org/projects/apps/issues + * Report a bug: https://github.com/YunoHost-Apps/nextcloud_ynh/issues * Nextcloud website: https://nextcloud.com/ + * Nextcloud repository: https://github.com/nextcloud/server * YunoHost website: https://yunohost.org/ + +--- + +Developers infos +---------------- + +Please do your pull request to the [testing branch](https://github.com/YunoHost-Apps/nextcloud_ynh/tree/testing). + +To try the testing branch, please proceed like that. +``` +sudo yunohost app install https://github.com/YunoHost-Apps/nextcloud_ynh/tree/testing --debug +or +sudo yunohost app upgrade nextcloud -u https://github.com/YunoHost-Apps/nextcloud_ynh/tree/testing --debug +``` diff --git a/check_process b/check_process index 1741c5c..8b4cff8 100644 --- a/check_process +++ b/check_process @@ -17,20 +17,9 @@ multi_instance=1 incorrect_path=1 port_already_use=0 - change_url=0 + change_url=1 ;;; Levels - Level 1=auto - Level 2=auto - Level 3=auto -# Level 4: LDAP and http auth - Level 4=1 -# Level 5: https://github.com/YunoHost-Apps/nextcloud_ynh/issues/58 - Level 5=1 - Level 6=auto - Level 7=auto - Level 8=0 - Level 9=0 - Level 10=0 + Level 5=auto ;;; Options Email= Notification=none diff --git a/conf/config_install.json b/conf/config_install.json index 52bff54..10db7cf 100644 --- a/conf/config_install.json +++ b/conf/config_install.json @@ -1,9 +1,9 @@ { "system": { - "datadirectory": "#DATADIR#", + "datadirectory": "__DATADIR__", "trusted_domains": [ "localhost", - "#DOMAIN#" + "__DOMAIN__" ] } } diff --git a/conf/nextcloud.cron b/conf/nextcloud.cron index 294325b..93fde63 100644 --- a/conf/nextcloud.cron +++ b/conf/nextcloud.cron @@ -1 +1 @@ -*/15 * * * * #USER# /usr/bin/php -f #DESTDIR#/cron.php +*/15 * * * * __USER__ /usr/bin/php -f __DESTDIR__/cron.php diff --git a/conf/nginx.conf b/conf/nginx.conf index 2e085c9..6c5d7ec 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -5,15 +5,19 @@ location = /.well-known/caldav { return 301 https://$server_name__PATH__/remote.php/dav; } -location ^~ __PATH__ { +#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; +location ^~ __PATH__/ { + + # Path to source alias __FINALPATH__/; + # Force usage of https if ($scheme = http) { rewrite ^ https://$server_name$request_uri? permanent; } # Add headers to serve security related headers - more_set_headers "Strict-Transport-Security: max-age=15768000"; + more_set_headers "Strict-Transport-Security: max-age=15768000; includeSubDomains; preload;"; more_set_headers "X-Content-Type-Options: nosniff"; more_set_headers "X-XSS-Protection: 1; mode=block"; more_set_headers "X-Robots-Tag: none"; @@ -42,7 +46,7 @@ location ^~ __PATH__ { #rewrite ^/.well-known/host-meta __PATH__/public.php?service=host-meta last; #rewrite ^/.well-known/host-meta.json __PATH__/public.php?service=host-meta-json last; - location __PATH__ { + location __PATH__/ { rewrite ^ __PATH__/index.php$request_uri; } @@ -59,7 +63,7 @@ location ^~ __PATH__ { deny all; } - location ~ ^__PATH__/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) { + location ~ ^__PATH__/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|ocm-provider/.+)\.php(/.*|)$ { include fastcgi_params; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param SCRIPT_FILENAME $request_filename; @@ -67,18 +71,19 @@ location ^~ __PATH__ { fastcgi_param HTTPS on; fastcgi_param modHeadersAvailable true; fastcgi_param REMOTE_USER $remote_user; - fastcgi_pass unix:/var/run/php5-fpm-__NAME__.sock; + fastcgi_pass unix:/var/run/php/php7.0-fpm-__NAME__.sock; fastcgi_intercept_errors on; } - location ~ ^__PATH__/(?:updater|ocs-provider)(?:$|/) { + location ~ ^__PATH__/(?:updater|ocs-provider|ocm-provider)(?:$|/) { try_files $uri/ =404; index index.php; } # Adding the cache control header for js and css files - location ~* \.(?:css|js)$ { - more_set_headers "Cache-Control: public, max-age=7200"; + location ~ ^__PATH__/.+[^/]\.(?:css|js|woff2?|svg|gif)$ { + try_files $uri __PATH__/index.php$request_uri; + more_set_headers "Cache-Control: public, max-age=15778463"; # Add headers to serve security related headers more_set_headers "Strict-Transport-Security: max-age=15768000"; more_set_headers "X-Content-Type-Options: nosniff"; @@ -92,7 +97,7 @@ location ^~ __PATH__ { access_log off; } - location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ { + location ~* \.(?:png|html|ttf|ico|jpg|jpeg)$ { # Optional: Don't log access to other assets access_log off; } diff --git a/conf/php-fpm.conf b/conf/php-fpm.conf index 2571613..f13ed6d 100644 --- a/conf/php-fpm.conf +++ b/conf/php-fpm.conf @@ -1,10 +1,11 @@ ; Start a new pool named 'www'. -; the variable $pool can we used in any directive and will be replaced by the +; the variable $pool can be used in any directive and will be replaced by the ; pool name ('www' here) [__NAMETOCHANGE__] ; Per pool prefix ; It only applies on the following directives: +; - 'access.log' ; - 'slowlog' ; - 'listen' (unixsocket) ; - 'chroot' @@ -24,28 +25,35 @@ group = __USER__ ; The address on which to accept FastCGI requests. ; Valid syntaxes are: -; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on +; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on ; a specific port; -; 'port' - to listen on a TCP socket to all addresses on a -; specific port; +; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on +; a specific port; +; 'port' - to listen on a TCP socket to all addresses +; (IPv6 and IPv4-mapped) on a specific port; ; '/path/to/unix/socket' - to listen on a unix socket. ; Note: This value is mandatory. -listen = /var/run/php5-fpm-__NAMETOCHANGE__.sock +listen = /var/run/php/php7.0-fpm-__NAMETOCHANGE__.sock -; Set listen(2) backlog. A value of '-1' means unlimited. -; Default Value: 128 (-1 on FreeBSD and OpenBSD) -;listen.backlog = 128 +; Set listen(2) backlog. +; Default Value: 511 (-1 on FreeBSD and OpenBSD) +;listen.backlog = 511 ; Set permissions for unix socket, if one is used. In Linux, read/write ; permissions must be set in order to allow connections from a web server. Many -; BSD-derived systems allow connections regardless of permissions. +; BSD-derived systems allow connections regardless of permissions. ; Default Values: user and group are set as the running user ; mode is set to 0660 listen.owner = www-data listen.group = www-data ;listen.mode = 0660 - -; List of ipv4 addresses of FastCGI clients which are allowed to connect. +; When POSIX Access Control Lists are supported you can set them using +; these options, value is a comma separated list of user/group names. +; When set, listen.owner and listen.group are ignored +;listen.acl_users = +;listen.acl_groups = + +; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. ; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original ; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address ; must be separated by a comma. If this value is left blank, connections will be @@ -59,7 +67,13 @@ listen.group = www-data ; - The pool processes will inherit the master process priority ; unless it specified otherwise ; Default Value: no set -; priority = -19 +; process.priority = -19 + +; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user +; or group is differrent than the master process user. It allows to create process +; core dump and ptrace the process for the pool user. +; Default Value: no +; process.dumpable = yes ; Choose how the process manager will control the number of child processes. ; Possible Values: @@ -117,12 +131,12 @@ pm.max_spare_servers = 3 ; Note: Used only when pm is set to 'ondemand' ; Default Value: 10s ;pm.process_idle_timeout = 10s; - + ; The number of requests each child process should execute before respawning. ; This can be useful to work around memory leaks in 3rd party libraries. For ; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. ; Default Value: 0 -pm.max_requests = 500 +;pm.max_requests = 500 ; The URI to view the FPM status page. If this value is not set, no URI will be ; recognized as a status page. It shows the following informations: @@ -170,7 +184,7 @@ pm.max_requests = 500 ; ; By default the status page only outputs short status. Passing 'full' in the ; query string will also return status for each pool process. -; Example: +; Example: ; http://www.foo.bar/status?full ; http://www.foo.bar/status?json&full ; http://www.foo.bar/status?html&full @@ -215,7 +229,7 @@ pm.max_requests = 500 ; last request memory: 0 ; ; Note: There is a real-time FPM status monitoring sample web page available -; It's available in: ${prefix}/share/fpm/status.html +; It's available in: /usr/share/php/7.0/fpm/status.html ; ; Note: The value must start with a leading slash (/). The value can be ; anything, but it may not be a good idea to use the .php extension or it @@ -275,7 +289,7 @@ pm.max_requests = 500 ; - %{megabytes}M ; - %{mega}M ; %n: pool name -; %o: ouput header +; %o: output header ; it must be associated with embraces to specify the name of the header: ; - %{Content-Type}o ; - %{X-Powered-By}o @@ -283,7 +297,7 @@ pm.max_requests = 500 ; - .... ; %p: PID of the child that serviced the request ; %P: PID of the parent of the child that serviced the request -; %q: the query string +; %q: the query string ; %Q: the '?' character if query string exists ; %r: the request URI (without the query string, see %q and %Q) ; %R: remote IP address @@ -291,47 +305,51 @@ pm.max_requests = 500 ; %t: server time the request was received ; it can accept a strftime(3) format: ; %d/%b/%Y:%H:%M:%S %z (default) +; The strftime(3) format must be encapsuled in a %{}t tag +; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t ; %T: time the log has been written (the request has finished) ; it can accept a strftime(3) format: ; %d/%b/%Y:%H:%M:%S %z (default) +; The strftime(3) format must be encapsuled in a %{}t tag +; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t ; %u: remote user ; ; Default: "%R - %u %t \"%m %r\" %s" ;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" - + ; The log file for slow requests ; Default Value: not set ; Note: slowlog is mandatory if request_slowlog_timeout is set -slowlog = /var/log/nginx/__NAMETOCHANGE__.slow.log - +;slowlog = log/$pool.log.slow + ; The timeout for serving a single request after which a PHP backtrace will be ; dumped to the 'slowlog' file. A value of '0s' means 'off'. ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) ; Default Value: 0 -request_slowlog_timeout = 5s - +;request_slowlog_timeout = 0 + ; The timeout for serving a single request after which the worker process will ; be killed. This option should be used when the 'max_execution_time' ini option ; does not stop script execution for some reason. A value of '0' means 'off'. ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) ; Default Value: 0 request_terminate_timeout = 1d - + ; Set open file descriptor rlimit. ; Default Value: system defined value ;rlimit_files = 1024 - + ; Set max core size rlimit. ; Possible Values: 'unlimited' or an integer greater or equal to 0 ; Default Value: system defined value ;rlimit_core = 0 - + ; Chroot to this directory at the start. This value must be defined as an ; absolute path. When this value is not set, chroot is not used. ; Note: you can prefix with '$prefix' to chroot to the pool prefix or one ; of its subdirectories. If the pool prefix is not set, the global prefix ; will be used instead. -; Note: chrooting is a great security feature and should be used whenever +; Note: chrooting is a great security feature and should be used whenever ; possible. However, all PHP paths will be relative to the chroot ; (error_log, sessions.save_path, ...). ; Default Value: not set @@ -347,16 +365,25 @@ chdir = __FINALPATH__ ; Note: on highloaded environement, this can cause some delay in the page ; process time (several ms). ; Default Value: no -catch_workers_output = yes +;catch_workers_output = yes + +; Clear environment in FPM workers +; Prevents arbitrary environment variables from reaching FPM worker processes +; by clearing the environment in workers before env vars specified in this +; pool configuration are added. +; Setting to "no" will make all environment variables available to PHP code +; via getenv(), $_ENV and $_SERVER. +; Default Value: yes +;clear_env = no ; Limits the extensions of the main script FPM will allow to parse. This can ; prevent configuration mistakes on the web server side. You should only limit ; FPM to .php extensions to prevent malicious users to use other extensions to -; exectute php code. +; execute php code. ; Note: set an empty value to allow all extensions. ; Default Value: .php -;security.limit_extensions = .php .php3 .php4 .php5 - +;security.limit_extensions = .php .php3 .php4 .php5 .php7 + ; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from ; the current environment. ; Default Value: clean env @@ -366,12 +393,11 @@ catch_workers_output = yes ;env[TMPDIR] = /tmp ;env[TEMP] = /tmp env[PATH] = $PATH - ; Additional php.ini defines, specific to this pool of workers. These settings ; overwrite the values previously defined in the php.ini. The directives are the ; same as the PHP SAPI: ; php_value/php_flag - you can set classic ini defines which can -; be overwritten from PHP call 'ini_set'. +; be overwritten from PHP call 'ini_set'. ; php_admin_value/php_admin_flag - these directives won't be overwritten by ; PHP call 'ini_set' ; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. @@ -392,11 +418,21 @@ env[PATH] = $PATH ;php_admin_flag[log_errors] = on ;php_admin_value[memory_limit] = 32M +; Common values to change to increase file upload limit +; php_admin_value[upload_max_filesize] = 50M +; php_admin_value[post_max_size] = 50M +; php_admin_flag[mail.add_x_header] = Off + +; Other common parameters +; php_admin_value[max_execution_time] = 600 +; php_admin_value[max_input_time] = 300 +; php_admin_value[memory_limit] = 256M +; php_admin_flag[short_open_tag] = On + ; Additional php.ini defines, specific to this pool of workers. php_value[upload_max_filesize] = 10G php_value[post_max_size] = 10G php_value[default_charset] = UTF-8 -php_value[always_populate_raw_post_data] = -1 php_value[opcache.enable]=1 php_value[opcache.enable_cli]=1 php_value[opcache.interned_strings_buffer]=8 @@ -404,4 +440,3 @@ php_value[opcache.max_accelerated_files]=10000 php_value[opcache.memory_consumption]=128 php_value[opcache.save_comments]=1 php_value[opcache.revalidate_freq]=1 - diff --git a/hooks/post_user_create b/hooks/post_user_create index f215f00..da6bb53 100644 --- a/hooks/post_user_create +++ b/hooks/post_user_create @@ -2,4 +2,4 @@ user=$1 -sudo setfacl -m g:#GROUP#:rwx /home/$user +sudo setfacl --modify g:__GROUP__:rwx /home/$user diff --git a/manifest.json b/manifest.json index 43bf976..07e7cac 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "en": "Access & share your files, calendars, contacts, mail & more from any device, on your terms", "fr": "Consultez et partagez vos fichiers, agendas, carnets d'adresses, emails et bien plus depuis les appareils de votre choix, sous vos conditions" }, - "version": "15.0.4~ynh1", + "version": "15.0.9~ynh1", "url": "https://nextcloud.com", "license": "AGPL-3.0", "maintainer": { @@ -14,12 +14,12 @@ "email": "apps@yunohost.org" }, "requirements": { - "yunohost": ">= 2.7.2" + "yunohost": ">= 3.5.0" }, "multi_instance": true, "services": [ "nginx", - "php5-fpm", + "php7.0-fpm", "mysql" ], "arguments": { diff --git a/pull_request_template.md b/pull_request_template.md index 2342905..da30b7b 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -19,7 +19,6 @@ - [ ] **Approval (LGTM)** : - [ ] **Approval (LGTM)** : - **CI succeeded** : -[![Build Status](https://ci-apps-dev.yunohost.org/jenkins/job/nextcloud_ynh%20-BRANCH-%20(Official)/badge/icon)](https://ci-apps-dev.yunohost.org/jenkins/job/nextcloud_ynh%20-BRANCH-%20(Official)/) *Please replace '-BRANCH-' in this link for a PR from a local branch.* -or -[![Build Status](https://ci-apps-dev.yunohost.org/jenkins/job/nextcloud_ynh%20PR-NUM-%20(Official_fork)/badge/icon)](https://ci-apps-dev.yunohost.org/jenkins/job/nextcloud_ynh%20PR-NUM-%20(Official_fork)/) *Replace '-NUM-' by the PR number in this link for a PR from a forked repository.* +[![Build Status](https://ci-apps-hq.yunohost.org/jenkins/job/nextcloud_ynh%20PR-NUM-/badge/icon)](https://ci-apps-hq.yunohost.org/jenkins/job/nextcloud_ynh%20PR-NUM-/) +*Please replace '-NUM-' in this link by the PR number.* When the PR is marked as ready to merge, you have to wait for 3 days before really merging it. diff --git a/scripts/_common.sh b/scripts/_common.sh index e523909..413f729 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -3,53 +3,10 @@ # COMMON VARIABLES #================================================= -pkg_dependencies="php5-gd php5-json php5-intl php5-mcrypt php5-curl php5-apcu php5-redis php5-ldap php5-imagick imagemagick acl tar smbclient at" +pkg_dependencies="php-gd php-json php-intl php-mcrypt php-curl php-apcu php-redis php-ldap php-imagick php-zip php-mbstring php-xml imagemagick acl tar smbclient at" -if [ "$(lsb_release --codename --short)" != "jessie" ]; then - pkg_dependencies="$pkg_dependencies php-zip php-apcu php-mbstring php-xml" -fi - -#================================================= -# COMMON HELPERS #================================================= - -# Execute a command with occ -exec_occ() { - (cd "$final_path" && exec_as "$app" \ - php occ --no-interaction --no-ansi "$@") -} - -# Create the external storage for the given folders and enable sharing -create_external_storage() { - local datadir="$1" - local mount_name="$2" - local mount_id=`exec_occ files_external:create --output=json \ - "$2" 'local' 'null::null' -c "datadir=$datadir" || true` - ! [[ $mount_id =~ ^[0-9]+$ ]] \ - && echo "Unable to create external storage" >&2 \ - || exec_occ files_external:option "$mount_id" enable_sharing true -} - -# Rename a MySQL database and user -# Usage: rename_mysql_db DBNAME DBUSER DBPASS NEW_DBNAME_AND_USER -rename_mysql_db() { - local db_name=$1 db_user=$2 db_pwd=$3 new_db_name=$4 - local sqlpath="/tmp/${db_name}-$(date '+%s').sql" - - # Dump the old database - mysqldump -u "$db_user" -p"$db_pwd" --no-create-db "$db_name" > "$sqlpath" - - # Create the new database and user - ynh_mysql_create_db "$new_db_name" "$new_db_name" "$db_pwd" - ynh_mysql_connect_as "$new_db_name" "$db_pwd" "$new_db_name" < "$sqlpath" - - # Remove the old database - ynh_mysql_remove_db $db_name $db_name - ynh_secure_remove "$sqlpath" -} - -#================================================= -# COMMON HELPERS -- SHOULD BE ADDED TO YUNOHOST +# EXPERIMENTAL HELPERS #================================================= # Execute a command as another user @@ -65,15 +22,40 @@ exec_as() { fi } +#================================================= + # Check if an URL is already handled # usage: is_url_handled URL is_url_handled() { - local output=($(curl -k -s -o /dev/null \ - -w 'x%{redirect_url} %{http_code}' "$1")) - # It's handled if it does not redirect to the SSO nor return 404 - [[ ! ${output[0]} =~ \/yunohost\/sso\/ && ${output[1]} != 404 ]] + # Declare an array to define the options of this helper. + declare -Ar args_array=( [u]=url= ) + local url + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # Try to get the url with curl, and keep the http code and an eventual redirection url. + local curl_output="$(curl --insecure --silent --output /dev/null \ + --write-out '%{http_code};%{redirect_url}' "$url")" + + # Cut the output and keep only the first part to keep the http code + local http_code="${curl_output%%;*}" + # Do the same thing but keep the second part, the redirection url + local redirection="${curl_output#*;}" + + # Return 1 if the url isn't handled. + # Which means either curl got a 404 (or the admin) or the sso. + # A handled url should redirect to a publicly accessible url. + # Return 1 if the url has returned 404 + if [ "$http_code" = "404" ] || [[ $redirection =~ "/yunohost/admin" ]]; then + return 1 + # Return 1 if the url is redirected to the SSO + elif [[ $redirection =~ "/yunohost/sso" ]]; then + return 1 + fi } +#================================================= + # Make the main steps to migrate an app to its fork. # # This helper has to be used for an app which needs to migrate to a new name or a new fork @@ -318,10 +300,49 @@ ynh_handle_app_migration () { fi } +#================================================= + +# Check available space before creating a temp directory. +# +# usage: ynh_smart_mktemp --min_size="Min size" +# +# | arg: -s, --min_size= - Minimal size needed for the temporary directory, in Mb +ynh_smart_mktemp () { + # Declare an array to define the options of this helper. + declare -Ar args_array=( [s]=min_size= ) + local min_size + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + min_size="${min_size:-300}" + # Transform the minimum size from megabytes to kilobytes + min_size=$(( $min_size * 1024 )) + + # Check if there's enough free space in a directory + is_there_enough_space () { + local free_space=$(df --output=avail "$1" | sed 1d) + test $free_space -ge $min_size + } + + if is_there_enough_space /tmp; then + local tmpdir=/tmp + elif is_there_enough_space /var; then + local tmpdir=/var + elif is_there_enough_space /; then + local tmpdir=/ + elif is_there_enough_space /home; then + local tmpdir=/home + else + ynh_die "Insufficient free space to continue..." + fi + + echo "$(sudo mktemp --directory --tmpdir="$tmpdir")" +} #================================================= -# EXPERIMENTAL HELPERS +# FUTURE OFFICIAL HELPERS #================================================= + #================================================= # YUNOHOST MULTIMEDIA INTEGRATION #================================================= @@ -330,16 +351,20 @@ ynh_handle_app_migration () { # # usage: ynh_multimedia_build_main_dir ynh_multimedia_build_main_dir () { - local ynh_media_release="v1.0" - local checksum="4852c8607db820ad51f348da0dcf0c88" + local ynh_media_release="v1.2" + local checksum="806a827ba1902d6911095602a9221181" # Download yunohost.multimedia scripts - wget -nv https://github.com/YunoHost-Apps/yunohost.multimedia/archive/${ynh_media_release}.tar.gz + wget -nv https://github.com/YunoHost-Apps/yunohost.multimedia/archive/${ynh_media_release}.tar.gz - # Verify checksum + # Check the control sum echo "${checksum} ${ynh_media_release}.tar.gz" | md5sum -c --status \ || ynh_die "Corrupt source" + # Check if the package acl is installed. Or install it. + ynh_package_is_installed 'acl' \ + || ynh_package_install acl + # Extract mkdir yunohost.multimedia-master tar -xf ${ynh_media_release}.tar.gz -C yunohost.multimedia-master --strip-components 1 @@ -356,29 +381,3 @@ ynh_multimedia_addaccess () { groupadd -f multimedia usermod -a -G multimedia $user_name } - -ynh_smart_mktemp () { - local min_size="${1:-300}" - # Transform the minimum size from megabytes to kilobytes - min_size=$(( $min_size * 1024 )) - - # Check if there's enough free space in a directory - is_there_enough_space () { - local free_space=$(df --output=avail "$1" | sed 1d) - test $free_space -ge $min_size - } - - if is_there_enough_space /tmp; then - local tmpdir=/tmp - elif is_there_enough_space /var; then - local tmpdir=/var - elif is_there_enough_space /; then - local tmpdir=/ - elif is_there_enough_space /home; then - local tmpdir=/home - else - ynh_die "Insufficient free space to continue..." - fi - - echo "$(sudo mktemp --directory --tmpdir="$tmpdir")" -} diff --git a/scripts/backup b/scripts/backup index 0a1f69c..5dbc43c 100755 --- a/scripts/backup +++ b/scripts/backup @@ -2,18 +2,11 @@ #================================================= # GENERIC START -#================================================= - #================================================= # IMPORT GENERIC HELPERS #================================================= -if [ ! -e _common.sh ]; then - # Get the _common.sh file if it's not in the current directory - cp ../settings/scripts/_common.sh ./_common.sh - chmod a+rx _common.sh -fi -source _common.sh +source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers #================================================= @@ -26,62 +19,76 @@ ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= +ynh_script_progression --message="Loading installation settings..." app=$YNH_APP_INSTANCE_NAME -final_path=$(ynh_app_setting_get $app final_path) -domain=$(ynh_app_setting_get $app domain) -db_name=$(ynh_app_setting_get $app db_name) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +domain=$(ynh_app_setting_get --app=$app --key=domain) +db_name=$(ynh_app_setting_get --app=$app --key=db_name) #================================================= # STANDARD BACKUP STEPS #================================================= # BACKUP THE APP MAIN DIR #================================================= +ynh_script_progression --message="Backing up the main app directory..." -ynh_backup "$final_path" +ynh_backup --src_path="$final_path" #================================================= # BACKUP THE NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Backing up nginx web server configuration..." -ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" +ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= # BACKUP THE PHP-FPM CONFIGURATION #================================================= +ynh_script_progression --message="Backing up php-fpm configuration..." -ynh_backup "/etc/php5/fpm/pool.d/$app.conf" +ynh_backup --src_path="/etc/php/7.0/fpm/pool.d/$app.conf" #================================================= # BACKUP THE MYSQL DATABASE #================================================= +ynh_script_progression --message="Backing up the MySQL database..." --weight=2 -ynh_mysql_dump_db "$db_name" > db.sql +ynh_mysql_dump_db --database="$db_name" > db.sql #================================================= # SPECIFIC BACKUP #================================================= # BACKUP LOGROTATE #================================================= +ynh_script_progression --message="Backing up logrotate configuration..." ynh_backup "/etc/logrotate.d/$app" +#================================================= +# BACKUP FAIL2BAN CONFIGURATION +#================================================= +ynh_script_progression --message="Backing up fail2ban configuration..." + +ynh_backup --src_path="/etc/fail2ban/jail.d/$app.conf" +ynh_backup --src_path="/etc/fail2ban/filter.d/$app.conf" + #================================================= # BACKUP THE CRON FILE #================================================= -ynh_backup "/etc/cron.d/$app" +ynh_backup --src_path="/etc/cron.d/$app" #================================================= # BACKUP THE DATA DIRECTORY #================================================= +ynh_script_progression --message="Backing up data directory..." + +ynh_backup --src_path="/home/yunohost.app/${app}/data" --is_big + +#================================================= +# END OF SCRIPT +#================================================= -backup_core_only=$(ynh_app_setting_get "$app" backup_core_only) -# If backup_core_only have any value in the settings.yml file, do not backup the data directory -if [ -z $backup_core_only ] -then - ynh_backup "/home/yunohost.app/${app}/data" -else - echo "Data dir will not be saved, because backup_core_only is set." >&2 -fi +ynh_script_progression --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." --last diff --git a/scripts/change_url b/scripts/change_url new file mode 100644 index 0000000..83bcb4e --- /dev/null +++ b/scripts/change_url @@ -0,0 +1,125 @@ +#!/bin/bash + +#================================================= +# GENERIC STARTING +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# RETRIEVE ARGUMENTS +#================================================= + +old_domain=$YNH_APP_OLD_DOMAIN +old_path=$YNH_APP_OLD_PATH + +new_domain=$YNH_APP_NEW_DOMAIN +new_path=$YNH_APP_NEW_PATH + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." + +# Needed for helper "ynh_add_nginx_config" +final_path=$(ynh_app_setting_get --app=$app --key=final_path) + +#================================================= +# CHECK WHICH PARTS SHOULD BE CHANGED +#================================================= + +change_domain=0 +if [ "$old_domain" != "$new_domain" ] +then + change_domain=1 +fi + +change_path=0 +if [ "$old_path" != "$new_path" ] +then + change_path=1 +fi + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# MODIFY URL IN NGINX CONF +#================================================= +ynh_script_progression --message="Updating nginx web server configuration..." --weight=2 + +nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf + +# Change the path in the nginx config file +if [ $change_path -eq 1 ] +then + # Make a backup of the original nginx config file if modified + ynh_backup_if_checksum_is_different --file="$nginx_conf_path" + # Set global variables for nginx helper + domain="$old_domain" + path_url="$new_path" + # Create a dedicated nginx config + ynh_add_nginx_config +fi + +# Change the domain for nginx +if [ $change_domain -eq 1 ] +then + # Delete file checksum for the old conf file location + ynh_delete_file_checksum --file="$nginx_conf_path" + mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf + # Store file checksum for the new config file location + ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" +fi + +#================================================= +# SPECIFIC MODIFICATIONS +#================================================= +ynh_script_progression --message="Applying Nextcloud specific modifications..." --weight=2 + +# Define a function to execute commands with `occ` +exec_occ() { + (cd "$final_path" && exec_as "$app" \ + php occ --no-interaction --no-ansi "$@") +} + +if [ $change_domain -eq 1 ] +then + # Change the trusted domain + exec_occ config:system:set trusted_domains 1 --value=$new_domain + + # Change hostname for activity notifications + ynh_replace_string --match_string="'overwrite.cli.url' => 'http://${old_domain}'," --replace_string="'overwrite.cli.url' => 'https://${new_domain}'," --target_file="${final_path}/config/config.php" +fi + +if [ $change_domain -eq 1 ] +then + # Check if .well-known is available for this domain + if is_url_handled --url="https://$domain/.well-known/caldav" || is_url_handled --url="https://$domain/.well-known/carddav" + then + ynh_print_warn --message="Another app already uses the domain $domain to serve a caldav/carddav feature. You may encounter issues when dealing with your calendar or address book." + + # Remove lines about .well-known/carddav and caldav with sed. + sed --in-place --regexp-extended '/^location = \/\.well\-known\/(caldav|carddav) \{/,/\}/d' "/etc/nginx/conf.d/$new_domain.d/$app.conf" + ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" + fi +fi + +#================================================= +# GENERIC FINALISATION +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading nginx web server..." + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Change of URL completed for $app" --last diff --git a/scripts/install b/scripts/install index 5bc37bf..7556b9d 100755 --- a/scripts/install +++ b/scripts/install @@ -30,74 +30,73 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= +ynh_script_progression --message="Validating installation parameters..." final_path=/var/www/$app -test ! -e "$final_path" || ynh_die "This path already contains a folder" +test ! -e "$final_path" || ynh_die --message="This path already contains a folder" -# Normalize the url path syntax -path_url=$(ynh_normalize_url_path $path_url) - -# Check web path availability -ynh_webpath_available $domain $path_url # Register (book) web path -ynh_webpath_register $app $domain $path_url +ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url #================================================= # STORE SETTINGS FROM MANIFEST #================================================= +ynh_script_progression --message="Storing installation settings..." -ynh_app_setting_set $app domain $domain -ynh_app_setting_set $app path $path_url -ynh_app_setting_set $app admin $admin -ynh_app_setting_set $app user_home $user_home +ynh_app_setting_set --app=$app --key=domain --value=$domain +ynh_app_setting_set --app=$app --key=path --value=$path_url +ynh_app_setting_set --app=$app --key=admin --value=$admin +ynh_app_setting_set --app=$app --key=user_home --value=$user_home #================================================= # STANDARD MODIFICATIONS #================================================= # INSTALL DEPENDENCIES #================================================= +ynh_script_progression --message="Installing dependencies..." --weight=60 ynh_install_app_dependencies $pkg_dependencies #================================================= # CREATE A MYSQL DATABASE #================================================= +ynh_script_progression --message="Creating a MySQL database..." --weight=2 -db_name=$(ynh_sanitize_dbid $app) -ynh_app_setting_set $app db_name $db_name -ynh_mysql_setup_db $db_name $db_name +db_name=$(ynh_sanitize_dbid --db_name=$app) +ynh_app_setting_set --app=$app --key=db_name --value=$db_name +ynh_mysql_setup_db --db_user=$db_name --db_name=$db_name #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= +ynh_script_progression --message="Setting up source files..."5 # Load the last available version source upgrade.d/upgrade.last.sh # Create an app.src for the last version of nextcloud cp ../conf/app.src.default ../conf/app.src -ynh_replace_string "__VERSION__" "$next_version" "../conf/app.src" -ynh_replace_string "__SHA256_SUM__" "$nextcloud_source_sha256" "../conf/app.src" +ynh_replace_string --match_string="__VERSION__" --replace_string="$next_version" --target_file="../conf/app.src" +ynh_replace_string --match_string="__SHA256_SUM__" --replace_string="$nextcloud_source_sha256" --target_file="../conf/app.src" -ynh_app_setting_set $app final_path $final_path +ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Enable YunoHost patches on Nextcloud sources cp -a ../sources/patches_last_version/* ../sources/patches # Download, check integrity, uncompress and patch the source from app.src -ynh_setup_source "$final_path" +ynh_setup_source --dest_dir="$final_path" #================================================= # NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Configuring nginx web server..." --weight=2 -# Do not serve .well-known if it's already served on the domain -if is_url_handled "https://${domain}/.well-known/caldav" ; then - sed -ri '/^location = \/\.well\-known\/(caldav|carddav) \{/,/\}/d' \ - "../conf/nginx.conf" -fi +# Check if .well-known is available for this domain +if is_url_handled --url="https://$domain/.well-known/caldav" || is_url_handled --url="https://$domain/.well-known/carddav" +then + ynh_print_warn --message="Another app already uses the domain $domain to serve a caldav/carddav feature. You may encounter issues when dealing with your calendar or address book." -# Handle root path, avoid double slash. -# Temporary fix, in waiting for an upgrade of the helper. (#361) -path_url_slash_less=${path_url%/} -ynh_replace_string "__PATH__/" "$path_url_slash_less/" "../conf/nginx.conf" + # Remove lines about .well-known/carddav and caldav with sed. + sed --in-place --regexp-extended '/^location = \/\.well\-known\/(caldav|carddav) \{/,/\}/d' "../conf/nginx.conf" +fi # Create a dedicated nginx config ynh_add_nginx_config @@ -105,13 +104,15 @@ ynh_add_nginx_config #================================================= # CREATE DEDICATED USER #================================================= +ynh_script_progression --message="Configuring system user..." --weight=3 # Create a system user -ynh_system_user_create $app +ynh_system_user_create --username=$app #================================================= # PHP-FPM CONFIGURATION #================================================= +ynh_script_progression --message="Configuring php-fpm..." --weight=2 # Create a dedicated php-fpm config ynh_add_fpm_config @@ -123,51 +124,63 @@ ynh_add_fpm_config #================================================= # Define app's data directory -datadir="/home/yunohost.app/${app}/data" +datadir="/home/yunohost.app/$app/data" # Create app folders mkdir -p "$datadir" #================================================= # INSTALL NEXTCLOUD #================================================= +ynh_script_progression --message="Installing nextcloud..." --weight=30 + +# Define a function to execute commands with `occ` +exec_occ() { + (cd "$final_path" && exec_as "$app" \ + php occ --no-interaction --no-ansi "$@") +} # Set write access for the following commands chown -R $app: "$final_path" "$datadir" # Install Nextcloud using a temporary admin user exec_occ maintenance:install \ - --database "mysql" --database-name "$db_name" \ - --database-user "$db_name" --database-pass "$db_pwd" \ - --admin-user "admin" --admin-pass "$(ynh_string_random 6)" \ + --database "mysql" --database-name $db_name \ + --database-user $db_name --database-pass "$db_pwd" \ + --admin-user "admin" --admin-pass "$(ynh_string_random --length=6)" \ --data-dir "$datadir" \ - || ynh_die "Unable to install Nextcloud" + || ynh_die --message="Unable to install Nextcloud" #================================================= # CONFIGURE NEXTCLOUD #================================================= +ynh_script_progression --message="Configuring nextcloud..." --weight=8 # Ensure that UpdateNotification app is disabled exec_occ app:disable updatenotification -# Enable plugins +# Enable ldap plugin exec_occ app:enable user_ldap exec_occ ldap:create-empty-config # Load the installation config file in nextcloud -nc_conf="${final_path}/config_install.json" +nc_conf="$final_path/config_install.json" cp ../conf/config_install.json "$nc_conf" -ynh_replace_string "#DOMAIN#" "$domain" "$nc_conf" -ynh_replace_string "#DATADIR#" "$datadir" "$nc_conf" + +ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$nc_conf" +ynh_replace_string --match_string="__DATADIR__" --replace_string="$datadir" --target_file="$nc_conf" exec_occ config:import "$nc_conf" -# Then remove it -rm -f "$nc_conf" + +# Then remove the config file +ynh_secure_remove --file="$nc_conf" # Load the additional config file (used also for upgrade) -nc_conf="${final_path}/config_install.json" +nc_conf="$final_path/config.json" cp ../conf/config.json "$nc_conf" + exec_occ config:import "$nc_conf" -# Then remove it -rm -f "$nc_conf" + +# Then remove the config file +ynh_secure_remove --file="$nc_conf" #================================================= # CHECK THE LDAP CONFIG @@ -175,19 +188,32 @@ rm -f "$nc_conf" # Check LDAP configuration to see if everything worked well exec_occ ldap:test-config \'\' \ - || ynh_die "An error occured during LDAP configuration" + || ynh_die --message="An error occured during LDAP configuration" #================================================= # MOUNT HOME FOLDERS AS EXTERNAL STORAGE #================================================= +# Define a function to add an external storage +# Create the external storage for the given folders and enable sharing +create_external_storage() { + local datadir="$1" + local mount_name="$2" + local mount_id=`exec_occ files_external:create --output=json \ + "$mount_name" 'local' 'null::null' -c "datadir=$datadir" || true` + ! [[ $mount_id =~ ^[0-9]+$ ]] \ + && ynh_print_warn --message="Unable to create external storage" \ + || exec_occ files_external:option "$mount_id" enable_sharing true +} + # Enable External Storage and create local mount to home folder -if [ $user_home -eq 1 ]; then +if [ $user_home -eq 1 ] +then exec_occ app:enable files_external create_external_storage "/home/\$user" "Home" # Iterate over users to extend their home folder permissions for u in $(ynh_user_list); do - setfacl -m g:$app:rwx "/home/$u" || true + setfacl --modify g:$app:rwx "/home/$u" || true done fi @@ -203,14 +229,20 @@ exec_occ config:system:get logout_url >/dev/null 2>&1 \ \$main_domain = exec('cat /etc/yunohost/current_host'); \$CONFIG['logout_url'] = 'https://'.\$main_domain.'/yunohost/sso/?action=logout'; //-YunoHost- -" >> "${final_path}/config/config.php" +" >> "$final_path/config/config.php" + +#================================================= +# CHANGE HOSTNAME FOR ACTIVITY NOTIFICATIONS +#================================================= + +ynh_replace_string --match_string="'overwrite.cli.url' => 'http://localhost'," --replace_string="'overwrite.cli.url' => 'https://${domain}'," --target_file="${final_path}/config/config.php" #================================================= # REMOVE THE TEMPORARY ADMIN AND SET THE TRUE ONE #================================================= # Set the user as admin -ynh_mysql_connect_as "$db_name" "$db_pwd" "$db_name" \ +ynh_mysql_connect_as --user=$db_name --password="$db_pwd" --database=$db_name \ <<< "INSERT INTO oc_group_user VALUES ('admin','$admin');" # And delete admin user exec_occ user:delete admin @@ -220,7 +252,7 @@ exec_occ user:delete admin #================================================= # Calculate and store the config file checksum into the app settings -ynh_store_file_checksum "${final_path}/config/config.php" +ynh_store_file_checksum --file="$final_path/config/config.php" #================================================= # ADD A CRON JOB @@ -231,14 +263,15 @@ cp -a ../conf/nextcloud.cron "$cron_path" chown root: "$cron_path" chmod 644 "$cron_path" -ynh_replace_string "#USER#" "$app" "$cron_path" -ynh_replace_string "#DESTDIR#" "$final_path" "$cron_path" +ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$cron_path" +ynh_replace_string --match_string="__DESTDIR__" --replace_string="$final_path" --target_file="$cron_path" exec_occ background:cron #================================================= # POST-INSTALL MAINTENANCE #================================================= + (cd /tmp ; at now + 10 minutes <<< "(cd $final_path ; sudo -u $app php occ db:add-missing-indices ; sudo -u $app php occ db:convert-filecache-bigint -n) > /tmp/${app}_maintenance.log") #================================================= @@ -246,11 +279,12 @@ exec_occ background:cron #================================================= # Set system group in hooks -ynh_replace_string "#GROUP#" "$app" ../hooks/post_user_create +ynh_replace_string --match_string="__GROUP__" --replace_string="$app" --target_file=../hooks/post_user_create #================================================= # YUNOHOST MULTIMEDIA INTEGRATION #================================================= +ynh_script_progression --message="Adding multimedia directories..." --weight=6 # Build YunoHost multimedia directories ynh_multimedia_build_main_dir @@ -269,30 +303,47 @@ ynh_multimedia_addaccess $app # Fix app ownerships & permissions chown -R $app: "$final_path" "$datadir" -find ${final_path}/ -type f -print0 | xargs -0 chmod 0644 -find ${final_path}/ -type d -print0 | xargs -0 chmod 0755 -find ${datadir}/ -type f -print0 | xargs -0 chmod 0640 -find ${datadir}/ -type d -print0 | xargs -0 chmod 0750 -chmod 640 "${final_path}/config/config.php" +find $final_path/ -type f -print0 | xargs -0 chmod 0644 +find $final_path/ -type d -print0 | xargs -0 chmod 0755 +find $datadir/ -type f -print0 | xargs -0 chmod 0640 +find $datadir/ -type d -print0 | xargs -0 chmod 0750 +chmod 640 "$final_path/config/config.php" chmod 755 /home/yunohost.app #================================================= # SETUP LOGROTATE #================================================= +ynh_script_progression --message="Configuring log rotation..." -# Use logrotate to manage application logfile -ynh_use_logrotate "${datadir}/nextcloud.log" +# Use logrotate to manage application logfile(s) +ynh_use_logrotate --logfile="$datadir/nextcloud.log" + +#================================================= +# SETUP FAIL2BAN +#================================================= +ynh_script_progression --message="Configuring fail2ban..." --weight=8 + +# Create a dedicated fail2ban config +ynh_add_fail2ban_config --logpath="/home/yunohost.app/$app/data/nextcloud.log" --failregex="^.*Login failed: '.*' \(Remote IP: ''.*$" --max_retry=5 #================================================= # SETUP SSOWAT #================================================= +ynh_script_progression --message="Configuring SSOwat..." -ynh_app_setting_set $app unprotected_uris "/" -ynh_app_setting_set $app skipped_regex \ - "$(sed 's/[\.\-]/\%&/g' <<< $domain)/%.well%-known/.*" +ynh_app_setting_set --app=$app --key=unprotected_uris --value="/" +ynh_app_setting_set --app=$app --key=skipped_regex \ + --value="$(sed 's/[\.\-]/\%&/g' <<< $domain)/%.well%-known/.*" #================================================= # RELOAD NGINX #================================================= +ynh_script_progression --message="Reloading nginx web server..." + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= -systemctl reload nginx +ynh_script_progression --message="Installation of $app completed" --last diff --git a/scripts/remove b/scripts/remove index b21d030..9ea5c15 100755 --- a/scripts/remove +++ b/scripts/remove @@ -12,18 +12,20 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= +ynh_script_progression --message="Loading installation settings..." --weight=2 app=$YNH_APP_INSTANCE_NAME -domain=$(ynh_app_setting_get $app domain) -db_name=$(ynh_app_setting_get $app db_name) -final_path=$(ynh_app_setting_get $app final_path) +domain=$(ynh_app_setting_get --app=$app --key=domain) +db_name=$(ynh_app_setting_get --app=$app --key=db_name) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # STANDARD REMOVE #================================================= # REMOVE DEPENDENCIES #================================================= +ynh_script_progression --message="Removing dependencies..." --weight=20 # Remove metapackage and its dependencies ynh_remove_app_dependencies @@ -31,20 +33,23 @@ ynh_remove_app_dependencies #================================================= # REMOVE THE MYSQL DATABASE #================================================= +ynh_script_progression --message="Removing the MySQL database..." --weight=5 # Remove a database if it exists, along with the associated user -ynh_mysql_remove_db $db_name $db_name +ynh_mysql_remove_db --db_user=$db_name --db_name=$db_name #================================================= # REMOVE APP MAIN DIR #================================================= +ynh_script_progression --message="Removing app main directory..." --weight=3 # Remove the app directory securely -ynh_secure_remove "$final_path" +ynh_secure_remove --file="$final_path" #================================================= # REMOVE NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Removing nginx web server configuration..." # Remove the dedicated nginx config ynh_remove_nginx_config @@ -52,6 +57,7 @@ ynh_remove_nginx_config #================================================= # REMOVE PHP-FPM CONFIGURATION #================================================= +ynh_script_progression --message="Removing php-fpm configuration..." --weight=2 # Remove the dedicated php-fpm config ynh_remove_fpm_config @@ -59,10 +65,19 @@ ynh_remove_fpm_config #================================================= # REMOVE LOGROTATE CONFIGURATION #================================================= +ynh_script_progression --message="Removing logrotate configuration..." # Remove the app-specific logrotate config ynh_remove_logrotate +#================================================= +# REMOVE FAIL2BAN CONFIGURATION +#================================================= +ynh_script_progression --message="Removing fail2ban configuration..." --weight=8 + +# Remove the dedicated fail2ban config +ynh_remove_fail2ban_config + #================================================= # SPECIFIC REMOVE #================================================= @@ -71,15 +86,16 @@ ynh_remove_logrotate # Remove a cron file # TODO: Ensure that cron job is not running (How !?) -ynh_secure_remove "/etc/cron.d/$app" +ynh_secure_remove --file="/etc/cron.d/$app" #================================================= # CLEAN ACL IN HOME DIRECTORIES #================================================= for i in $(ls /home); do + # Clean ACL in every directories in /home, except those which start with 'yunohost.' [[ ! $i == yunohost.* ]] \ - && setfacl -x g:$app:rwx 2>&1 + && setfacl --remove g:$app:rwx 2>&1 done #================================================= @@ -87,6 +103,13 @@ done #================================================= # REMOVE DEDICATED USER #================================================= +ynh_script_progression --message="Removing the dedicated system user..." # Delete a system user -ynh_system_user_delete $app +ynh_system_user_delete --username=$app + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Removal of $app completed" --last diff --git a/scripts/restore b/scripts/restore index 7f601db..c6c8e7e 100755 --- a/scripts/restore +++ b/scripts/restore @@ -2,18 +2,11 @@ #================================================= # GENERIC START -#================================================= - #================================================= # IMPORT GENERIC HELPERS #================================================= -if [ ! -e _common.sh ]; then - # Get the _common.sh file if it's not in the current directory - cp ../settings/scripts/_common.sh ./_common.sh - chmod a+rx _common.sh -fi -source _common.sh +source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers #================================================= @@ -26,22 +19,24 @@ ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= +ynh_script_progression --message="Loading settings..." app=$YNH_APP_INSTANCE_NAME -domain=$(ynh_app_setting_get $app domain) -path_url=$(ynh_app_setting_get $app path) -final_path=$(ynh_app_setting_get $app final_path) -db_name=$(ynh_app_setting_get $app db_name) +domain=$(ynh_app_setting_get --app=$app --key=domain) +path_url=$(ynh_app_setting_get --app=$app --key=path) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +db_name=$(ynh_app_setting_get --app=$app --key=db_name) #================================================= # CHECK IF THE APP CAN BE RESTORED #================================================= +ynh_script_progression --message="Validating restoration parameters..." --weight=4 -ynh_webpath_available $domain $path_url \ - || ynh_die "Path not available: ${domain}${path_url}" +ynh_webpath_available --domain=$domain --path_url=$path_url \ + || ynh_die --message="Path not available: ${domain}${path_url}" test ! -d $final_path \ - || ynh_die "There is already a directory: $final_path " + || ynh_die --message="There is already a directory: $final_path " #================================================= # STANDARD RESTORATION STEPS @@ -49,40 +44,53 @@ test ! -d $final_path \ # RESTORE THE NGINX CONFIGURATION #================================================= -ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf" +ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" + +# Check if .well-known is available for this domain +if is_url_handled --url="https://$domain/.well-known/caldav" || is_url_handled --url="https://$domain/.well-known/carddav" +then + ynh_print_warn --message="Another app already uses the domain $domain to serve a caldav/carddav feature. You may encounter issues when dealing with your calendar or address book." + + # Remove lines about .well-known/carddav and caldav with sed. + sed --in-place --regexp-extended '/^location = \/\.well\-known\/(caldav|carddav) \{/,/\}/d' "/etc/nginx/conf.d/$domain.d/$app.conf" +fi #================================================= # RESTORE THE APP MAIN DIR #================================================= +ynh_script_progression --message="Restoring the app main directory..." -ynh_restore_file "$final_path" +ynh_restore_file --origin_path="$final_path" #================================================= # RESTORE THE MYSQL DATABASE #================================================= +ynh_script_progression --message="Restoring the MySQL database..." --weight=9 -db_pwd=$(ynh_app_setting_get $app mysqlpwd) -ynh_mysql_setup_db $db_name $db_name $db_pwd -ynh_mysql_connect_as $db_name $db_pwd $db_name < ./db.sql +db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) +ynh_mysql_setup_db --db_user=$db_name --db_name=$db_name --db_pwd=$db_pwd +ynh_mysql_connect_as --user=$db_name --password=$db_pwd --database=$db_name < ./db.sql #================================================= # RECREATE THE DEDICATED USER #================================================= +ynh_script_progression --message="Recreating the dedicated system user..." --weight=3 # Create the dedicated user (if not existing) -ynh_system_user_create $app +ynh_system_user_create --username=$app #================================================= # RESTORE THE PHP-FPM CONFIGURATION #================================================= -ynh_restore_file "/etc/php5/fpm/pool.d/$app.conf" +ynh_restore_file --origin_path="/etc/php/7.0/fpm/pool.d/$app.conf" #================================================= # SPECIFIC RESTORATION #================================================= # REINSTALL DEPENDENCIES #================================================= +ynh_script_progression --message="Reinstalling dependencies..." --weight=60 # Define and install dependencies ynh_install_app_dependencies $pkg_dependencies @@ -91,31 +99,25 @@ ynh_install_app_dependencies $pkg_dependencies # RESTORE THE CRON FILE #================================================= -ynh_restore_file "/etc/cron.d/$app" +ynh_restore_file --origin_path="/etc/cron.d/$app" #================================================= # BACKUP THE LOGROTATE CONFIGURATION #================================================= -ynh_restore_file "/etc/logrotate.d/$app" +ynh_restore_file --origin_path="/etc/logrotate.d/$app" #================================================= # RESTORE THE DATA DIRECTORY #================================================= +ynh_script_progression --message="Restoring data directory..." --weight=2 -datadir="/home/yunohost.app/${app}/data" +datadir="/home/yunohost.app/$app/data" -# The data directory will be restored only if it exists in the backup archive -# So only if it was backup previously. -if [ -d "$YNH_BACKUP_DIR/apps/$app/backup/home/yunohost.app/$app" ] -then - ynh_restore_file "$datadir" -else - # Create app folders - mkdir -p "$datadir" -fi -# Remove the option backup_core_only if it's in the settings.yml file -ynh_app_setting_delete $app backup_core_only +# Use --not_mandatory for the data directory, because if the backup has been made with BACKUP_CORE_ONLY, there's no data into the backup. +ynh_restore_file --origin_path="$datadir" --not_mandatory + +mkdir -p "$datadir" #================================================= # RESTORE USER RIGHTS @@ -123,30 +125,55 @@ ynh_app_setting_delete $app backup_core_only # Fix app ownerships & permissions chown -R $app: "$final_path" "$datadir" -chmod 640 "${final_path}/config/config.php" +chmod 640 "$final_path/config/config.php" chmod 755 /home/yunohost.app # Iterate over users to extend their home folder permissions - for the external # storage plugin usage - and create relevant Nextcloud directories for u in $(ynh_user_list); do - mkdir -p "${datadir}/${u}" - setfacl -m g:$app:rwx "/home/$u" || true + mkdir -p "$datadir/$u" + setfacl --modify g:$app:rwx "/home/$u" || true done #================================================= # YUNOHOST MULTIMEDIA INTEGRATION #================================================= +ynh_script_progression --message="Adding multimedia directories..." --weight=4 # Build YunoHost multimedia directories ynh_multimedia_build_main_dir # Allow nextcloud to write into these directories ynh_multimedia_addaccess $app +#================================================= +# RESTORE THE FAIL2BAN CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the fail2ban configuration..." --weight=7 + +ynh_restore_file --origin_path="/etc/fail2ban/jail.d/$app.conf" +ynh_restore_file --origin_path="/etc/fail2ban/filter.d/$app.conf" + +# Make sure a log file exists (mostly for CI tests) +logfile="/home/yunohost.app/$app/data/nextcloud.log" +if [ ! -f "$logfile" ]; then + touch "$logfile" + chown $app: "$logfile" +fi + +ynh_systemd_action --action=restart --service_name=fail2ban + #================================================= # GENERIC FINALIZATION #================================================= # RELOAD NGINX AND PHP-FPM #================================================= +ynh_script_progression --message="Reloading nginx web server and php-fpm..." + +ynh_systemd_action --service_name=php7.0-fpm --action=reload +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= -systemctl reload php5-fpm -systemctl reload nginx +ynh_script_progression --message="Restoration completed for $app" --last diff --git a/scripts/upgrade b/scripts/upgrade index 774524c..8e75255 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -12,39 +12,50 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= +ynh_script_progression --message="Loading installation settings..." --weight=3 app=$YNH_APP_INSTANCE_NAME -domain=$(ynh_app_setting_get $app domain) -path_url=$(ynh_app_setting_get $app path) -admin=$(ynh_app_setting_get $app admin) -final_path=$(ynh_app_setting_get $app final_path) -db_name=$(ynh_app_setting_get $app db_name) -user_home=$(ynh_app_setting_get $app user_home) +domain=$(ynh_app_setting_get --app=$app --key=domain) +path_url=$(ynh_app_setting_get --app=$app --key=path) +admin=$(ynh_app_setting_get --app=$app --key=admin) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +db_name=$(ynh_app_setting_get --app=$app --key=db_name) +user_home=$(ynh_app_setting_get --app=$app --key=user_home) + +#================================================= +# CHECK VERSION +#================================================= + +upgrade_type=$(ynh_check_app_version_changed) #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= +ynh_script_progression --message="Ensuring downward compatibility..." # If db_name doesn't exist, create it -if [ -z $db_name ]; then - db_name=$(ynh_sanitize_dbid $app) - ynh_app_setting_set $app db_name $db_name +if [ -z "$db_name" ]; then + db_name=$(ynh_sanitize_dbid --db_name=$app) + ynh_app_setting_set --app=$app --key=db_name --value=$db_name fi # If final_path doesn't exist, create it -if [ -z $final_path ]; then +if [ -z "$final_path" ]; then final_path=/var/www/$app - ynh_app_setting_set $app final_path $final_path + ynh_app_setting_set --app=$app --key=final_path --value=$final_path fi +# Remove the option backup_core_only if it's in the settings.yml file +ynh_app_setting_delete --app=$app --key=backup_core_only + #================================================= # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP #================================================= +ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=30 # Made a backup only after the version 11.0.0 # Before, the datas will be always saved. - # Get the current version number of nextcloud/owncloud current_version=$(grep OC_VersionString "$final_path/version.php" | cut -d\' -f2) current_major_version=${current_version%%.*} @@ -52,20 +63,25 @@ current_major_version=${current_version%%.*} if [ $current_major_version -gt 11 ] then # Inform the backup/restore process that it should not save the data directory - ynh_app_setting_set $app backup_core_only 1 + # Use only for the previous backup script that doesn't set 'is_big' + ynh_app_setting_set --app=$app --key=backup_core_only --value=1 # Backup the current version of the app ynh_backup_before_upgrade + + # Remove the option backup_core_only after the backup. + ynh_app_setting_delete $app backup_core_only + ynh_clean_setup () { - # Remove the post migration script before its execution ! - ynh_secure_remove "/tmp/owncloud_post_migration.sh" 2>&1 + # Remove the post migration script before its execution ! + ynh_exec_warn_less ynh_secure_remove --file="/tmp/owncloud_post_migration.sh" - # restore it if the upgrade fails - ynh_restore_upgradebackup + # restore it if the upgrade fails + ynh_restore_upgradebackup } fi -# Exit if an error occurs during the script execution +# Exit if an error occurs during the execution of the script ynh_abort_if_errors #================================================= @@ -75,10 +91,10 @@ ynh_abort_if_errors ynh_handle_app_migration "owncloud" "owncloud_migration" if [ $migration_process -eq 1 ] then - # If a migration has been perform + # If a migration has been performed # Reload some values changed by the migration process - final_path=$(ynh_app_setting_get $app final_path) - db_name=$(ynh_app_setting_get $app db_name) + final_path=$(ynh_app_setting_get --app=$app --key=final_path) + db_name=$(ynh_app_setting_get --app=$app --key=db_name) # Remove the old fake package for owncloud. # Its name is specific, so the migration process can't remove it @@ -98,27 +114,29 @@ fi #================================================= # Normalize the URL path syntax -path_url=$(ynh_normalize_url_path $path_url) +path_url=$(ynh_normalize_url_path --path_url=$path_url) #================================================= # STANDARD UPGRADE STEPS #================================================= # NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Upgrading nginx web server configuration..." --weight=2 + +ynh_backup_if_checksum_is_different --file="/etc/nginx/conf.d/$domain.d/$app.conf" # Delete current nginx configuration to be able to check if .well-known is already served. ynh_remove_nginx_config -ynh_app_setting_delete $app "checksum__etc_nginx_conf.d_$domain.d_$app.conf" || true -# Do not serve .well-known if it's already served on the domain -if is_url_handled "https://${domain}/.well-known/caldav" ; then - sed -ri '/^location = \/\.well\-known\/(caldav|carddav) \{/,/\}/d' \ - "../conf/nginx.conf" -fi +ynh_app_setting_delete --app=$app --key="checksum__etc_nginx_conf.d_$domain.d_$app.conf" + +# Check if .well-known is available for this domain +if is_url_handled --url="https://$domain/.well-known/caldav" || is_url_handled --url="https://$domain/.well-known/carddav" +then + ynh_print_warn --message="Another app already uses the domain $domain to serve a caldav/carddav feature. You may encounter issues when dealing with your calendar or address book." -# Handle root path, avoid double slash. -# Temporary fix, in waiting for an upgrade of the helper. (#361) -path_url_slash_less=${path_url%/} -ynh_replace_string "__PATH__/" "$path_url_slash_less/" "../conf/nginx.conf" + # Remove lines about .well-known/carddav and caldav with sed. + sed --in-place --regexp-extended '/^location = \/\.well\-known\/(caldav|carddav) \{/,/\}/d' "../conf/nginx.conf" +fi # Create a dedicated nginx config ynh_add_nginx_config @@ -126,20 +144,28 @@ ynh_add_nginx_config #================================================= # CREATE DEDICATED USER #================================================= +ynh_script_progression --message="Making sure dedicated system user exists..." -# Create a system user -ynh_system_user_create $app +# Create a dedicated user (if not existing) +ynh_system_user_create --username=$app #================================================= # PHP-FPM CONFIGURATION #================================================= +ynh_script_progression --message="Upgrading php-fpm configuration..." --weight=2 # Create a dedicated php-fpm config ynh_add_fpm_config +# Delete existing ini configuration file (backward compatibility) +if [ -f /etc/php/7.0/fpm/conf.d/20-$app.ini ]; then + ynh_secure_remove --file=/etc/php/7.0/fpm/conf.d/20-$app.ini +fi + #================================================= # UPGRADE DEPENDENCIES #================================================= +ynh_script_progression --message="Upgrading dependencies..." --weight=7 ynh_install_app_dependencies $pkg_dependencies @@ -150,153 +176,185 @@ ynh_install_app_dependencies $pkg_dependencies # VERSION TO THE NEXT ONE #================================================= -# Load the last available version -source upgrade.d/upgrade.last.sh -last_version=$next_version - -# Define app's data directory -datadir="/home/yunohost.app/${app}/data" - -# Set write access for the following commands -chown -R $app: "$final_path" "$datadir" - -# Print the current version number of nextcloud -exec_occ -V - -# While the current version is not the last version, do an upgrade -while [ "$last_version" != "$current_version" ] -do - - # The major version is the first part of the version number - # major_version=${next_version%%.*} - major_version=${last_version%%.*} - current_major_version=${current_version%%.*} - - # If the current version has the same major version than the next one, - # then it's the last upgrade to do - if [ "$major_version" -eq "$current_major_version" ]; then - current_major_version=last - # Execute the commands dedicated to the last upgrade - last_upgrade_operations - fi - - # Load the value for this version - source upgrade.d/upgrade.$current_major_version.sh - - echo -e "\nUpgrade to nextcloud $next_version" >&2 - - # Create an app.src for this version of nextcloud - cp ../conf/app.src.default ../conf/app.src - ynh_replace_string "__VERSION__" "$next_version" "../conf/app.src" - ynh_replace_string "__SHA256_SUM__" "$nextcloud_source_sha256" "../conf/app.src" - - # Create a temporary directory - tmpdir="$(ynh_smart_mktemp 300)" - - # Install the next nextcloud version in $tmpdir - ynh_setup_source "$tmpdir" - - # Enable maintenance mode - exec_occ maintenance:mode --on +if [ "$upgrade_type" == "UPGRADE_APP" ] +then + ynh_script_progression --message="Upgrading nextcloud..." --weight=3 - # Backup the config file in the temp dir - cp -a "$final_path/config/config.php" "$tmpdir/config/config.php" + # Define a function to execute commands with `occ` + exec_occ() { + (cd "$final_path" && exec_as "$app" \ + php occ --no-interaction --no-ansi "$@") + } - # Backup 3rd party applications from the current nextcloud - # But do not overwrite if there is any upgrade - # (apps directory already exists in Nextcloud archive) - ( - cd $final_path/apps - for nc_app_dir in */ - do - if [ ! -d "$tmpdir/apps/$nc_app_dir" ] - then - cp -a "$nc_app_dir" "$tmpdir/apps/$nc_app_dir" - fi - done - ) + # Load the last available version + source upgrade.d/upgrade.last.sh + last_version=$next_version - # Replace the old nextcloud by the new one - ynh_secure_remove "$final_path" - mv "$tmpdir" "$final_path" - ynh_secure_remove "$tmpdir" + # Define app's data directory + datadir="/home/yunohost.app/$app/data" # Set write access for the following commands chown -R $app: "$final_path" "$datadir" - # Upgrade Nextcloud (SUCCESS = 0, UP_TO_DATE = 3) - exec_occ maintenance:mode --off - exec_occ upgrade \ - || ([[ $? -eq 3 ]] || ynh_die "Unable to upgrade Nextcloud") - - # Get the new current version number - current_version=$(grep OC_VersionString "$final_path/version.php" | cut -d\' -f2) - current_major_version=${current_version%%.*} - # Print the current version number of nextcloud exec_occ -V -done - -#================================================= -# CONFIGURE NEXTCLOUD -#================================================= - -# Verify the checksum and backup the file if it's different -ynh_backup_if_checksum_is_different "${final_path}/config/config.php" - -nc_conf="${final_path}/config.json" -cp ../conf/config.json "$nc_conf" -ynh_replace_string "#DOMAIN#" "$domain" "$nc_conf" -ynh_replace_string "#DATADIR#" "$datadir" "$nc_conf" -# Ensure that UpdateNotification app is disabled -exec_occ app:disable updatenotification - -# Enable plugins -exec_occ app:enable user_ldap + # While the current version is not the last version, do an upgrade + while [ "$last_version" != "$current_version" ] + do -# Load the config file in nextcloud -exec_occ config:import "$nc_conf" -# Then remove it -rm -f "$nc_conf" + # The major version is the first part of the version number + # major_version=${next_version%%.*} + major_version=${last_version%%.*} + current_major_version=${current_version%%.*} + + # If the current version has the same major version than the next one, + # then it's the last upgrade to do + if [ "$major_version" -eq "$current_major_version" ]; then + current_major_version=last + # Execute the commands dedicated to the last upgrade + last_upgrade_operations + fi + + # Load the value for this version + source upgrade.d/upgrade.$current_major_version.sh + + ynh_print_info --message="Upgrade to nextcloud $next_version" + + # Create an app.src for this version of nextcloud + cp ../conf/app.src.default ../conf/app.src + ynh_replace_string --match_string="__VERSION__" --replace_string="$next_version" --target_file="../conf/app.src" + ynh_replace_string --match_string="__SHA256_SUM__" --replace_string="$nextcloud_source_sha256" --target_file="../conf/app.src" + + # Create a temporary directory + tmpdir="$(ynh_smart_mktemp min_size=300)" + + # Install the next nextcloud version in $tmpdir + ynh_setup_source --dest_dir="$tmpdir" + + # Enable maintenance mode + exec_occ maintenance:mode --on + + # Backup the config file in the temp dir + cp -a "$final_path/config/config.php" "$tmpdir/config/config.php" + + # Backup 3rd party applications from the current nextcloud + # But do not overwrite if there is any upgrade + # (apps directory already exists in Nextcloud archive) + ( + cd $final_path/apps + for nc_app_dir in */ + do + if [ ! -d "$tmpdir/apps/$nc_app_dir" ] + then + cp -a "$nc_app_dir" "$tmpdir/apps/$nc_app_dir" + fi + done + ) + + # Replace the old nextcloud by the new one + ynh_secure_remove --file="$final_path" + mv "$tmpdir" "$final_path" + ynh_secure_remove --file="$tmpdir" + + # Set write access for the following commands + chown -R $app: "$final_path" "$datadir" + + # Upgrade Nextcloud (SUCCESS = 0, UP_TO_DATE = 3) + exec_occ maintenance:mode --off + exec_occ upgrade \ + || ([ $? -eq 3 ] || ynh_die --message="Unable to upgrade Nextcloud") + + # Get the new current version number + current_version=$(grep OC_VersionString "$final_path/version.php" | cut -d\' -f2) + current_major_version=${current_version%%.*} + + # Print the current version number of nextcloud + exec_occ -V + done -#================================================= -# ALLOW USERS TO DISCONNECT FROM NEXTCLOUD -#================================================= + #================================================= + # CONFIGURE NEXTCLOUD + #================================================= + ynh_script_progression --message="Reconfiguring nextcloud..." --weight=9 + + # Verify the checksum and backup the file if it's different + ynh_backup_if_checksum_is_different --file="$final_path/config/config.php" + + nc_conf="${final_path}/config.json" + cp ../conf/config.json "$nc_conf" + + ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$nc_conf" + ynh_replace_string --match_string="__DATADIR__" --replace_string="$datadir" --target_file="$nc_conf" + + # Ensure that UpdateNotification app is disabled + exec_occ app:disable updatenotification + + # Enable plugins + exec_occ app:enable user_ldap + + # Load the config file in nextcloud + exec_occ config:import "$nc_conf" + + # Then remove the config file + ynh_secure_remove --file="$nc_conf" + + #================================================= + # ALLOW USERS TO DISCONNECT FROM NEXTCLOUD + #================================================= + + # Add dynamic logout URL to the config + exec_occ config:system:get logout_url >/dev/null 2>&1 \ + || echo " + //-YunoHost- + // set logout_url according to main domain + \$main_domain = exec('cat /etc/yunohost/current_host'); + \$CONFIG['logout_url'] = 'https://'.\$main_domain.'/yunohost/sso/?action=logout'; + //-YunoHost- + " >> "$final_path/config/config.php" + + #================================================= + # CHANGE HOSTNAME FOR ACTIVITY NOTIFICATIONS + #================================================= + + ynh_replace_string --match_string="'overwrite.cli.url' => 'http://localhost'," --replace_string="'overwrite.cli.url' => 'https://${domain}'," --target_file="${final_path}/config/config.php" + + #================================================= + # MOUNT HOME FOLDERS AS EXTERNAL STORAGE + #================================================= + + # Define a function to add an external storage + # Create the external storage for the given folders and enable sharing + create_external_storage() { + local datadir="$1" + local mount_name="$2" + local mount_id=`exec_occ files_external:create --output=json \ + "$mount_name" 'local' 'null::null' -c "datadir=$datadir" || true` + ! [[ $mount_id =~ ^[0-9]+$ ]] \ + && ynh_print_warn --message="Unable to create external storage" \ + || exec_occ files_external:option "$mount_id" enable_sharing true + } -# Add dynamic logout URL to the config -exec_occ config:system:get logout_url >/dev/null 2>&1 \ - || echo " -//-YunoHost- -// set logout_url according to main domain -\$main_domain = exec('cat /etc/yunohost/current_host'); -\$CONFIG['logout_url'] = 'https://'.\$main_domain.'/yunohost/sso/?action=logout'; -//-YunoHost- -" >> "${final_path}/config/config.php" + # Enable External Storage and create local mount to home folder as needed + if [ $user_home -eq 1 ]; then + exec_occ app:enable files_external + exec_occ files_external:list --output=json \ + | grep -q '"storage":"\\\\OC\\\\Files\\\\Storage\\\\Local"' \ + || create_external_storage "/home/\$user" "Home" + # Iterate over users to extend their home folder permissions + for u in $(ynh_user_list); do + setfacl --modify g:$app:rwx "/home/$u" || true + done + fi -#================================================= -# MOUNT HOME FOLDERS AS EXTERNAL STORAGE -#================================================= + #================================================= + # STORE THE CHECKSUM OF THE CONFIG FILE + #================================================= -# Enable External Storage and create local mount to home folder as needed -if [ $user_home -eq 1 ]; then - exec_occ app:enable files_external - exec_occ files_external:list --output=json \ - | grep -q '"storage":"\\\\OC\\\\Files\\\\Storage\\\\Local"' \ - || create_external_storage "/home/\$user" "Home" - # Iterate over users to extend their home folder permissions - for u in $(ynh_user_list); do - setfacl -m g:$app:rwx "/home/$u" || true - done + # Calculate and store the config file checksum into the app settings + ynh_store_file_checksum --file="${final_path}/config/config.php" fi -#================================================= -# STORE THE CHECKSUM OF THE CONFIG FILE -#================================================= - -# Calculate and store the config file checksum into the app settings -ynh_store_file_checksum "${final_path}/config/config.php" - #================================================= # UPDATE THE CRON JOB #================================================= @@ -306,8 +364,8 @@ cp -a ../conf/nextcloud.cron "$cron_path" chown root: "$cron_path" chmod 644 "$cron_path" -ynh_replace_string "#USER#" "$app" "$cron_path" -ynh_replace_string "#DESTDIR#" "$final_path" "$cron_path" +ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$cron_path" +ynh_replace_string --match_string="__DESTDIR__" --replace_string="$final_path" --target_file="$cron_path" exec_occ background:cron @@ -316,11 +374,12 @@ exec_occ background:cron #================================================= # Set system group in hooks -ynh_replace_string "#GROUP#" "$app" ../hooks/post_user_create +ynh_replace_string --match_string="__GROUP__" --replace_string="$app" --target_file=../hooks/post_user_create #================================================= # YUNOHOST MULTIMEDIA INTEGRATION #================================================= +ynh_script_progression --message="Updating multimedia directories..." --weight=6 # Build YunoHost multimedia directories ynh_multimedia_build_main_dir @@ -339,43 +398,57 @@ ynh_multimedia_addaccess $app # Fix app ownerships & permissions chown -R $app: "$final_path" "$datadir" -find ${final_path}/ -type f -print0 | xargs -0 chmod 0644 -find ${final_path}/ -type d -print0 | xargs -0 chmod 0755 -find ${datadir}/ -type f -print0 | xargs -0 chmod 0640 -find ${datadir}/ -type d -print0 | xargs -0 chmod 0750 -chmod 640 "${final_path}/config/config.php" +find $final_path/ -type f -print0 | xargs -0 chmod 0644 +find $final_path/ -type d -print0 | xargs -0 chmod 0755 +find $datadir/ -type f -print0 | xargs -0 chmod 0640 +find $datadir/ -type d -print0 | xargs -0 chmod 0750 +chmod 640 "$final_path/config/config.php" chmod 755 /home/yunohost.app #================================================= # WARNING ABOUT THIRD-PARTY APPS #================================================= -# Warn about possible disabled apps -echo "Note that if you've installed some third-parties Nextcloud applications, \ -they are probably disabled and you'll have to manually enable them again." >&2 +if [ "$upgrade_type" == "UPGRADE_APP" ] +then + # Warn about possible disabled apps + ynh_print_warn --message="Note that if you've installed some third-parties Nextcloud applications, \ + they are probably disabled and you'll have to manually enable them again." +fi #================================================= # SETUP LOGROTATE #================================================= +ynh_script_progression --message="Upgrading logrotate configuration..." # Use logrotate to manage app-specific logfile(s) ynh_use_logrotate --non-append +#================================================= +# SETUP FAIL2BAN +#================================================= +ynh_script_progression --message="Reconfiguring fail2ban..." --weight=7 + +# Create a dedicated fail2ban config +ynh_add_fail2ban_config --logpath="/home/yunohost.app/$app/data/nextcloud.log" --failregex="^.*Login failed: '.*' \(Remote IP: ''.*$" --max_retry=5 + #================================================= # GENERIC FINALIZATION #================================================= # SETUP SSOWAT #================================================= +ynh_script_progression --message="Upgrading SSOwat configuration..." --weight=2 -ynh_app_setting_set $app unprotected_uris "/" -ynh_app_setting_set $app skipped_regex \ - "$(sed 's/[\.\-]/\%&/g' <<< $domain)/%.well%-known/.*" +ynh_app_setting_set --app=$app --key=unprotected_uris --value="/" +ynh_app_setting_set --app=$app --key=skipped_regex \ + --value="$(sed 's/[\.\-]/\%&/g' <<< $domain)/%.well%-known/.*" #================================================= # RELOAD NGINX #================================================= +ynh_script_progression --message="Reloading nginx web server..." -systemctl reload nginx +ynh_systemd_action --service_name=nginx --action=reload #================================================= # FINISH MIGRATION PROCESS @@ -383,17 +456,23 @@ systemctl reload nginx if [ $migration_process -eq 1 ] then - echo "ownCloud has been successfully migrated to Nextcloud! \ + ynh_print_info --message="ownCloud has been successfully migrated to Nextcloud! \ A last scheduled operation will run in a couple of minutes to finish the \ migration in YunoHost side. Do not proceed any application operation while \ -you don't see Nextcloud as installed." >&2 +you don't see Nextcloud as installed." # Execute a post migration script after the end of this upgrade. # Mainly for some cleaning script_post_migration=owncloud_post_migration.sh - ynh_replace_string "__OLD_APP__" "$old_app" ../conf/$script_post_migration - ynh_replace_string "__NEW_APP__" "$app" ../conf/$script_post_migration + ynh_replace_string --match_string="__OLD_APP__" --replace_string="$old_app" --target_file=../conf/$script_post_migration + ynh_replace_string --match_string="__NEW_APP__" --replace_string="$app" --target_file=../conf/$script_post_migration cp ../conf/$script_post_migration /tmp chmod +x /tmp/$script_post_migration (cd /tmp; echo "/tmp/$script_post_migration > /tmp/$script_post_migration.log 2>&1" | at now + 2 minutes) fi + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Upgrade of $app completed" --last diff --git a/scripts/upgrade.d/upgrade.last.sh b/scripts/upgrade.d/upgrade.last.sh index 80d65dd..f0da93d 100755 --- a/scripts/upgrade.d/upgrade.last.sh +++ b/scripts/upgrade.d/upgrade.last.sh @@ -1,10 +1,10 @@ #!/bin/bash # Last available nextcloud version -next_version="15.0.4" +next_version="15.0.9" # Nextcloud tarball checksum sha256 -nextcloud_source_sha256="f87db047c174f563e391a22c959d9ace767ca14ef0f97fc394f3061fc63d8f77" +nextcloud_source_sha256="7b33e210f64fb94c9a92aa31f087136db73bdacd1aaa7df2905bc7c0887edd5c" # This function will only be executed upon applying the last upgrade referenced above last_upgrade_operations () { diff --git a/sources/patches_last_version/app-00-add-logout_url-conf.patch b/sources/patches_last_version/app-00-add-logout_url-conf.patch index 2e70ba7..07a9531 100644 --- a/sources/patches_last_version/app-00-add-logout_url-conf.patch +++ b/sources/patches_last_version/app-00-add-logout_url-conf.patch @@ -1,62 +1,16 @@ - core/Controller/LoginController.php | 25 ++++++++++++++----------- - 1 file changed, 14 insertions(+), 11 deletions(-) - diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php -index 182d2bc106..82523e306e 100644 +index f83b03bc90..568e20dcd7 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php -@@ -95,13 +95,13 @@ class LoginController extends Controller { - * @param Throttler $throttler - */ - public function __construct($appName, -- IRequest $request, -- IUserManager $userManager, -- IConfig $config, -- ISession $session, -- IUserSession $userSession, -- IURLGenerator $urlGenerator, -- ILogger $logger, -+ IRequest $request, -+ IUserManager $userManager, -+ IConfig $config, -+ ISession $session, -+ IUserSession $userSession, -+ IURLGenerator $urlGenerator, -+ ILogger $logger, - Manager $twoFactorManager, - Defaults $defaults, - Throttler $throttler) { @@ -130,7 +130,10 @@ class LoginController extends Controller { } $this->userSession->logout(); - + - $response = new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); + $redirectUrl = $this->config->getSystemValue('logout_url', -+ $this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm') -+ ); ++ $this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); ++ + $response = new RedirectResponse($redirectUrl); + $this->session->set('clearingExecutionContexts', '1'); + $this->session->close(); $response->addHeader('Clear-Site-Data', '"cache", "storage", "executionContexts"'); - return $response; - } -@@ -303,10 +306,10 @@ class LoginController extends Controller { - $previousUser = $user; - $user = $users[0]->getUID(); - if($user !== $previousUser) { -- $loginResult = $this->userManager->checkPassword($user, $password); -- } -+ $loginResult = $this->userManager->checkPassword($user, $password); - } - } -+ } - - if ($loginResult === false) { - $this->logger->warning('Login failed: \''. $user . -@@ -314,7 +317,7 @@ class LoginController extends Controller { - ['app' => 'core']); - return $this->createLoginFailedResponse($user, $originalUser, - $redirect_url, self::LOGIN_MSG_INVALIDPASSWORD); -- } -+ } - - // TODO: remove password checks from above and let the user session handle failures - // requires https://github.com/owncloud/core/pull/24616