From 7bfab53b9bb5153d9a8aa0014e86786b8a8d61f2 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Mon, 7 Mar 2022 09:55:06 +0100 Subject: [PATCH 01/26] Add description --- doc/DESCRIPTION.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/DESCRIPTION.md diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md new file mode 100644 index 0000000..d6dd49b --- /dev/null +++ b/doc/DESCRIPTION.md @@ -0,0 +1,7 @@ +h5ai is a modern file indexer for HTTP web servers with focus on your files. Directories are displayed in a appealing way and browsing them is enhanced by different views, a breadcrumb and a tree overview. + +### Features + +There are lots of optional extensions and configuration options to customize the web appearance of your directory listings. All markup is valid HTML5 spiced up with CSS3 and finest JavaScript to build a fresh but minimal user interface and a user experience that focuses on your files. + +Some of the optional features are: file sorting, different view modes, localization, a breadcrumb, a tree view, custom headers and footers, file filter and search, folder sizes, auto refresh, packaged download, QR codes, thumbnails, file previews \ No newline at end of file From 0e237e12c80784d246afaf6df2122df3c9eeb0ca Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Thu, 31 Mar 2022 17:39:38 +0000 Subject: [PATCH 02/26] Apply example_ynh --- conf/nginx.conf | 40 +-- conf/php-fpm.conf | 430 ++++++++++++++++++++++++++++++ config_panel.toml.example | 295 ++++++++++++++++++++ doc/DESCRIPTION.md | 1 + doc/screenshots/h5ai-1024x540.png | Bin 0 -> 200833 bytes manifest.json | 5 +- scripts/_common.sh | 22 ++ scripts/backup | 12 + scripts/change_url | 23 +- scripts/config | 102 +++++++ scripts/install | 97 +++++-- scripts/remove | 54 +++- scripts/restore | 47 +++- scripts/upgrade | 106 ++++++-- 14 files changed, 1150 insertions(+), 84 deletions(-) create mode 100644 conf/php-fpm.conf create mode 100644 config_panel.toml.example create mode 100644 doc/DESCRIPTION.md create mode 100644 doc/screenshots/h5ai-1024x540.png create mode 100644 scripts/_common.sh create mode 100644 scripts/config diff --git a/conf/nginx.conf b/conf/nginx.conf index 93dc9d7..c169ca5 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,27 +1,31 @@ #sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; location __PATH__/ { - # Path to source - alias __FINALPATH__/; + # Path to source + alias __FINALPATH__/; - index index.php __PATH__/_h5ai/public/index.php; +### Example PHP configuration (remove it if not used) + index index.php __PATH__/_h5ai/public/index.php; - try_files $uri.html $uri $uri/ =404; - - proxy_pass_header Content-Type; + # Common parameter to increase upload size limit in conjunction with dedicated php-fpm file + #client_max_body_size 50M; - client_max_body_size 10G; + try_files $uri.html $uri $uri/ =404; - location ~ [^/]\.php(/|$) { - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - fastcgi_pass unix:/var/run/php/php__PHPVERSION__-fpm.sock; - fastcgi_index index.php; - include fastcgi_params; - fastcgi_param REMOTE_USER $remote_user; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param SCRIPT_FILENAME $request_filename; - } + proxy_pass_header Content-Type; - # Include SSOWAT user panel. - include conf.d/yunohost_panel.conf.inc; + location ~ [^/]\.php(/|$) { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + fastcgi_pass unix:/var/run/php/php__PHPVERSION__-fpm-__NAME__.sock; + + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param REMOTE_USER $remote_user; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param SCRIPT_FILENAME $request_filename; + } +### End of PHP configuration part + + # Include SSOWAT user panel. + include conf.d/yunohost_panel.conf.inc; } diff --git a/conf/php-fpm.conf b/conf/php-fpm.conf new file mode 100644 index 0000000..ab1a471 --- /dev/null +++ b/conf/php-fpm.conf @@ -0,0 +1,430 @@ +; Start a new pool named 'www'. +; 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' +; - 'chdir' +; - 'php_values' +; - 'php_admin_values' +; When not set, the global prefix (or /usr) applies instead. +; Note: This directive can also be relative to the global prefix. +; Default Value: none +;prefix = /path/to/pools/$pool + +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = __USER__ +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 IPv4 address 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/php/php__PHPVERSION__-fpm-__NAMETOCHANGE__.sock + +; 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. +; 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 +; 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 +; accepted from any ip address. +; Default Value: any +;listen.allowed_clients = 127.0.0.1 + +; Specify the nice(2) priority to apply to the pool processes (only if set) +; The value can vary from -19 (highest priority) to 20 (lower priority) +; Note: - It will only work if the FPM master process is launched as root +; - The pool processes will inherit the master process priority +; unless it specified otherwise +; Default Value: no set +; 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: +; static - a fixed number (pm.max_children) of child processes; +; dynamic - the number of child processes are set dynamically based on the +; following directives. With this process management, there will be +; always at least 1 children. +; pm.max_children - the maximum number of children that can +; be alive at the same time. +; pm.start_servers - the number of children created on startup. +; pm.min_spare_servers - the minimum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is less than this +; number then some children will be created. +; pm.max_spare_servers - the maximum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is greater than this +; number then some children will be killed. +; ondemand - no children are created at startup. Children will be forked when +; new requests will connect. The following parameter are used: +; pm.max_children - the maximum number of children that +; can be alive at the same time. +; pm.process_idle_timeout - The number of seconds after which +; an idle process will be killed. +; Note: This value is mandatory. +pm = dynamic + +; The number of child processes to be created when pm is set to 'static' and the +; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. +; This value sets the limit on the number of simultaneous requests that will be +; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. +; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP +; CGI. The below defaults are based on a server without much resources. Don't +; forget to tweak pm.* to fit your needs. +; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' +; Note: This value is mandatory. +pm.max_children = 5 + +; The number of child processes created on startup. +; Note: Used only when pm is set to 'dynamic' +; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 +pm.start_servers = 2 + +; The desired minimum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.min_spare_servers = 1 + +; The desired maximum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.max_spare_servers = 3 + +; The number of seconds after which an idle process will be killed. +; 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 + +; 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: +; pool - the name of the pool; +; process manager - static, dynamic or ondemand; +; start time - the date and time FPM has started; +; start since - number of seconds since FPM has started; +; accepted conn - the number of request accepted by the pool; +; listen queue - the number of request in the queue of pending +; connections (see backlog in listen(2)); +; max listen queue - the maximum number of requests in the queue +; of pending connections since FPM has started; +; listen queue len - the size of the socket queue of pending connections; +; idle processes - the number of idle processes; +; active processes - the number of active processes; +; total processes - the number of idle + active processes; +; max active processes - the maximum number of active processes since FPM +; has started; +; max children reached - number of times, the process limit has been reached, +; when pm tries to start more children (works only for +; pm 'dynamic' and 'ondemand'); +; Value are updated in real time. +; Example output: +; pool: www +; process manager: static +; start time: 01/Jul/2011:17:53:49 +0200 +; start since: 62636 +; accepted conn: 190460 +; listen queue: 0 +; max listen queue: 1 +; listen queue len: 42 +; idle processes: 4 +; active processes: 11 +; total processes: 15 +; max active processes: 12 +; max children reached: 0 +; +; By default the status page output is formatted as text/plain. Passing either +; 'html', 'xml' or 'json' in the query string will return the corresponding +; output syntax. Example: +; http://www.foo.bar/status +; http://www.foo.bar/status?json +; http://www.foo.bar/status?html +; http://www.foo.bar/status?xml +; +; By default the status page only outputs short status. Passing 'full' in the +; query string will also return status for each pool process. +; Example: +; http://www.foo.bar/status?full +; http://www.foo.bar/status?json&full +; http://www.foo.bar/status?html&full +; http://www.foo.bar/status?xml&full +; The Full status returns for each process: +; pid - the PID of the process; +; state - the state of the process (Idle, Running, ...); +; start time - the date and time the process has started; +; start since - the number of seconds since the process has started; +; requests - the number of requests the process has served; +; request duration - the duration in µs of the requests; +; request method - the request method (GET, POST, ...); +; request URI - the request URI with the query string; +; content length - the content length of the request (only with POST); +; user - the user (PHP_AUTH_USER) (or '-' if not set); +; script - the main script called (or '-' if not set); +; last request cpu - the %cpu the last request consumed +; it's always 0 if the process is not in Idle state +; because CPU calculation is done when the request +; processing has terminated; +; last request memory - the max amount of memory the last request consumed +; it's always 0 if the process is not in Idle state +; because memory calculation is done when the request +; processing has terminated; +; If the process is in Idle state, then informations are related to the +; last request the process has served. Otherwise informations are related to +; the current request being served. +; Example output: +; ************************ +; pid: 31330 +; state: Running +; start time: 01/Jul/2011:17:53:49 +0200 +; start since: 63087 +; requests: 12808 +; request duration: 1250261 +; request method: GET +; request URI: /test_mem.php?N=10000 +; content length: 0 +; user: - +; script: /home/fat/web/docs/php/test_mem.php +; last request cpu: 0.00 +; last request memory: 0 +; +; Note: There is a real-time FPM status monitoring sample web page available +; 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 +; may conflict with a real PHP file. +; Default Value: not set +;pm.status_path = /status + +; The ping URI to call the monitoring page of FPM. If this value is not set, no +; URI will be recognized as a ping page. This could be used to test from outside +; that FPM is alive and responding, or to +; - create a graph of FPM availability (rrd or such); +; - remove a server from a group if it is not responding (load balancing); +; - trigger alerts for the operating team (24/7). +; 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 +; may conflict with a real PHP file. +; Default Value: not set +;ping.path = /ping + +; This directive may be used to customize the response of a ping request. The +; response is formatted as text/plain with a 200 response code. +; Default Value: pong +;ping.response = pong + +; The access log file +; Default: not set +;access.log = log/$pool.access.log + +; The access log format. +; The following syntax is allowed +; %%: the '%' character +; %C: %CPU used by the request +; it can accept the following format: +; - %{user}C for user CPU only +; - %{system}C for system CPU only +; - %{total}C for user + system CPU (default) +; %d: time taken to serve the request +; it can accept the following format: +; - %{seconds}d (default) +; - %{miliseconds}d +; - %{mili}d +; - %{microseconds}d +; - %{micro}d +; %e: an environment variable (same as $_ENV or $_SERVER) +; it must be associated with embraces to specify the name of the env +; variable. Some exemples: +; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e +; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e +; %f: script filename +; %l: content-length of the request (for POST request only) +; %m: request method +; %M: peak of memory allocated by PHP +; it can accept the following format: +; - %{bytes}M (default) +; - %{kilobytes}M +; - %{kilo}M +; - %{megabytes}M +; - %{mega}M +; %n: pool name +; %o: output header +; it must be associated with embraces to specify the name of the header: +; - %{Content-Type}o +; - %{X-Powered-By}o +; - %{Transfert-Encoding}o +; - .... +; %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 '?' character if query string exists +; %r: the request URI (without the query string, see %q and %Q) +; %R: remote IP address +; %s: status (response code) +; %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 = 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 = 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 +; possible. However, all PHP paths will be relative to the chroot +; (error_log, sessions.save_path, ...). +; Default Value: not set +;chroot = + +; Chdir to this directory at the start. +; Note: relative path can be used. +; Default Value: current directory or / when chroot +chdir = __FINALPATH__ + +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Note: on highloaded environement, this can cause some delay in the page +; process time (several ms). +; Default Value: no +;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 +; execute php code. +; Note: set an empty value to allow all extensions. +; Default Value: .php +;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 +;env[HOSTNAME] = $HOSTNAME +;env[PATH] = /usr/local/bin:/usr/bin:/bin +;env[TMP] = /tmp +;env[TMPDIR] = /tmp +;env[TEMP] = /tmp + +; 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'. +; 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. + +; Defining 'extension' will load the corresponding shared extension from +; extension_dir. Defining 'disable_functions' or 'disable_classes' will not +; overwrite previously defined php.ini values, but will append the new value +; instead. + +; Note: path INI options can be relative and will be expanded with the prefix +; (pool, global or /usr) + +; Default Value: nothing is defined by default except the values in php.ini and +; specified at startup with the -d argument +;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com +;php_flag[display_errors] = off +;php_admin_value[error_log] = /var/log/fpm-php.www.log +;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 diff --git a/config_panel.toml.example b/config_panel.toml.example new file mode 100644 index 0000000..c6bccd8 --- /dev/null +++ b/config_panel.toml.example @@ -0,0 +1,295 @@ + +## Config panel are available from webadmin > Apps > YOUR_APP > Config Panel Button +## Those panels let user configure some params on their apps using a friendly interface, +## and remove the need to manually edit files from the command line. + +## From a packager perspective, this .toml is coupled to the scripts/config script, +## which may be used to define custom getters/setters. However, most use cases +## should be covered automagically by the core, thus it may not be necessary +## to define a scripts/config at all! + +## ----------------------------------------------------------------------------- +## IMPORTANT: In accordance with YunoHost's spirit, please keep things simple and +## do not overwhelm the admin with tons of misunderstandable or advanced settings. +## ----------------------------------------------------------------------------- + +## The top level describe the entire config panels screen. + +## The version is a required property. +## Here a small reminder to associate config panel version with YunoHost version +## | Config | YNH | Config panel small change log | +## | ------ | --- | ------------------------------------------------------- | +## | 0.1 | 3.x | 0.1 config script not compatible with YNH >= 4.3 | +## | 1.0 | 4.3.x | The new config panel system with 'bind' property | +version = "1.0" + +## (optional) i18n property let you internationalize questions, however this feature +## is only available in core configuration panel (like yunohost domain config). +## So in app config panel this key is ignored for now, but you can internationalize +## by using a lang dictionary (see property name bellow) +# i18n = "prefix_translation_key" + +################################################################################ +#### ABOUT PANELS +################################################################################ + +## The next level describes web admin panels +## You have to choose an ID for each panel, in this example the ID is "main" +## Keep in mind this ID will be used in CLI to refer to your question, so choose +## something short and meaningfull. +## In the webadmin, each panel corresponds to a distinct tab / form +[main] + +## Define the label for your panel +## Internationalization works similarly to the 'description' and 'ask' questions in the manifest +# name.en = "Main configuration" +# name.fr = "Configuration principale" + +## (optional) If you need to trigger a service reload-or-restart after the user +## change a question in this panel, you can add your service in the list. +services = ["__APP__"] +# or services = ["nginx", "__APP__"] to also reload-or-restart nginx + +## (optional) This help properties is a short help displayed on the same line +## than the panel title but not displayed in the tab. +# help = "" + + ############################################################################ + #### ABOUT SECTIONS + ############################################################################ + + ## A panel is composed of one or several sections. + ## + ## Sections are meant to group questions together when they correspond to + ## a same subtopic. This impacts the rendering in terms of CLI prompts + ## and HTML forms + ## + ## You should choose an ID for your section, and prefix it with the panel ID + ## (Be sure to not make a typo in the panel ID, which would implicitly create + ## an other entire panel) + ## + ## We use the context of pepettes_ynh as an example, + ## which is a simple donation form app written in python, + ## and for which the admin will want to edit the configuration + [main.customization] + + ## (optional) Defining a proper title for sections is not mandatory + ## and depends on the exact rendering you're aiming for the CLI / webadmin + name = "" + + ## (optional) This help properties is a short help displayed on the same line + ## than the section title, meant to provide additional details + # help = "" + + ## (optional) As for panel, you can specify to trigger a service + ## reload-or-restart after the user change a question in this section. + ## This property is added to the panel property, it doesn't deactivate it. + ## So no need to replicate, the service list from panel services property. + # services = [] + + ## (optional) By default all questions are optionals, but you can specify a + ## default behaviour for question in the section + optional = false + + ## (optional) It's also possible with the 'visible' property to only + ## display the section depending on the user's answers to previous questions. + ## + ## Be careful that the 'visible' property should only refer to **previous** questions + ## Hence, it should not make sense to have a "visible" property on the very first section. + ## + ## Also, keep in mind that this feature only works in the webadmin and not in CLI + ## (therefore a user could be prompted in CLI for a question that may not be relevant) + # visible = true + + ######################################################################## + #### ABOUT QUESTIONS + ######################################################################## + + ## A section is compound of one or several questions. + + ## --------------------------------------------------------------------- + ## IMPORTANT: as for panel and section you have to choose an ID, but this + ## one should be unique in all this document, even if the question is in + ## an other panel. + ## --------------------------------------------------------------------- + + ## You can use same questions types and properties than in manifest.yml + ## install part. However, in YNH 4.3, a lot of change has been made to + ## extend availables questions types list. + ## See: TODO DOC LINK + + [main.customization.project_name] + + ## (required) The ask property is equivalent to the ask property in + ## the manifest. However, in config panels, questions are displayed on the + ## left side and therefore have less space to be rendered. Therefore, + ## it is better to use a short question, and use the "help" property to + ## provide additional details if necessary. + ask.en = "Name of the project" + + ## (required) The type property indicates how the question should be + ## displayed, validated and managed. Some types have specific properties. + ## + ## Types available: string, boolean, number, range, text, password, path + ## email, url, date, time, color, select, domain, user, tags, file. + ## + ## For a complete list with specific properties, see: TODO DOC LINK + type = "string" + + ######################################################################## + #### ABOUT THE BIND PROPERTY + ######################################################################## + + ## (recommended) 'bind' property is a powerful feature that let you + ## configure how and where the data will be read, validated and written. + + ## By default, 'bind property is in "settings" mode, it means it will + ## **only** read and write the value in application settings file. + ## bind = "settings" + + ## However, settings usually correspond to key/values in actual app configurations + ## Hence, a more useful mode is to have bind = ":FILENAME". In that case, YunoHost + ## will automagically find a line with "KEY=VALUE" in FILENAME + ## (with the adequate separator between KEY and VALUE) + ## + ## YunoHost will then use this value for the read/get operation. + ## During write/set operations, YunoHost will overwrite the value + ## in **both** FILENAME and in the app's settings.yml + + ## Configuration file format supported: yaml, toml, json, ini, env, php, + ## python. The feature probably works with others formats, but should be tested carefully. + + ## Note that this feature only works with relatively simple cases + ## such as `KEY: VALUE`, but won't properly work with + ## complex data structures like multilin array/lists or dictionnaries. + ## It also doesn't work with XML format, custom config function call, php define(), ... + + ## More info on TODO + # bind = ":/var/www/__APP__/settings.py" + + + ## By default, bind = ":FILENAME" will use the question ID as KEY + ## ... but the question ID may sometime not be the exact KEY name in the configuration file. + ## + ## In particular, in pepettes, the python variable is 'name' and not 'project_name' + ## (c.f. https://github.com/YunoHost-Apps/pepettes_ynh/blob/5cc2d3ffd6529cc7356ff93af92dbb6785c3ab9a/conf/settings.py##L11 ) + ## + ## In that case, the key name can be specified before the column ':' + + bind = "name:/var/www/__APP__/settings.py" + + ## --------------------------------------------------------------------- + ## IMPORTANT: other 'bind' mode exists: + ## + ## bind = "FILENAME" (with no column character before FILENAME) + ## may be used to bind to the **entire file content** (instead of a single KEY/VALUE) + ## This could be used to expose an entire configuration file, or binary files such as images + ## For example: + ## bind = "/var/www/__APP__/img/logo.png" + ## + ## bind = "null" can be used to disable reading / writing in settings. + ## This creates sort of a "virtual" or "ephemeral" question which is not related to any actual setting + ## In this mode, you are expected to define custom getter/setters/validators in scripts/config: + ## + ## getter: get__QUESTIONID() + ## setter: set__QUESTIONID() + ## validator: validate__QUESTIONID() + ## + ## You can also specify a common getter / setter / validator, with the + ## function 'bind' mode, for example here it will try to run + ## get__array_settings() first. + # bind = "array_settings()" + ## --------------------------------------------------------------------- + + ## --------------------------------------------------------------------- + ## IMPORTANT: with the exception of bind=null questions, + ## question IDs should almost **always** correspond to an app setting + ## initialized / reused during install/upgrade. + ## Not doing so may result in inconsistencies between the config panel mechanism + ## and the use of ynh_add_config + ## --------------------------------------------------------------------- + + ######################################################################## + #### OTHER GENERIC PROPERTY FOR QUESTIONS + ######################################################################## + + ## (optional) An help text for the question + help = "Fill the name of the project which will received donation" + + ## (optional) An example display as placeholder in web form + # example = "YunoHost" + + ## (optional) set to true in order to redact the value in operation logs + # redact = false + + ## (optional) A validation pattern + ## --------------------------------------------------------------------- + ## IMPORTANT: your pattern should be between simple quote, not double. + ## --------------------------------------------------------------------- + pattern.regexp = '^\w{3,30}$' + pattern.error = "The name should be at least 3 chars and less than 30 chars. Alphanumeric chars are accepted" + + ## Note: visible and optional properties are also available for questions + + + [main.customization.contact_url] + ask = "Contact url" + type = "url" + example = "mailto: contact@example.org" + help = "mailto: accepted" + pattern.regexp = '^mailto:[^@]+@[^@]+|https://$' + pattern.error = "Should be https or mailto:" + bind = ":/var/www/__APP__/settings.py" + + [main.customization.logo] + ask = "Logo" + type = "file" + accept = ".png" + help = "Fill with an already resized logo" + bind = "__FINALPATH__/img/logo.png" + + [main.customization.favicon] + ask = "Favicon" + type = "file" + accept = ".png" + help = "Fill with an already sized favicon" + bind = "__FINALPATH__/img/favicon.png" + + + [main.stripe] + name = "Stripe general info" + optional = false + + # The next alert is overwrited with a getter from the config script + [main.stripe.amount] + ask = "Donation in the month : XX € + type = "alert" + style = "success" + + [main.stripe.publishable_key] + ask = "Publishable key" + type = "string" + redact = true + help = "Indicate here the stripe publishable key" + bind = ":/var/www/__APP__/settings.py" + + [main.stripe.secret_key] + ask = "Secret key" + type = "string" + redact = true + help = "Indicate here the stripe secret key" + bind = ":/var/www/__APP__/settings.py" + + [main.stripe.prices] + ask = "Prices ID" + type = "tags" + help = """\ + Indicates here the prices ID of donation products you created in stripe interfaces. \ + Go on [Stripe products](https://dashboard.stripe.com/products) to create those donation products. \ + Fill it tag with 'FREQUENCY/CURRENCY/PRICE_ID' \ + FREQUENCY: 'one_time' or 'recuring' \ + CURRENCY: 'EUR' or 'USD' \ + PRICE_ID: ID from stripe interfaces starting with 'price_' \ + """ + pattern.regexp = '^(one_time|recuring)/(EUR|USD)/price_.*$' + pattern.error = "Please respect the format describe in help text for each price ID" diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md new file mode 100644 index 0000000..8febe3c --- /dev/null +++ b/doc/DESCRIPTION.md @@ -0,0 +1 @@ +h5ai is a modern file indexer for HTTP web servers with focus on your files. Directories are displayed in a appealing way and browsing them is enhanced by different views, a breadcrumb and a tree overview. Initially h5ai was an acronym for HTML5 Apache Index but now it supports other web servers too. diff --git a/doc/screenshots/h5ai-1024x540.png b/doc/screenshots/h5ai-1024x540.png new file mode 100644 index 0000000000000000000000000000000000000000..6c0cfba8f877f3cbcf4c6fe39014aee1229abb5a GIT binary patch literal 200833 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�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

  • v<$_wsBw?%+CA?(EQz8HV)$ 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 4.3.0" }, - "multi_instance": false, + "multi_instance": true, "services": [ "nginx", "php7.3-fpm" diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..dc0d03b --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +#================================================= +# COMMON VARIABLES +#================================================= + +# dependencies used by the app +#pkg_dependencies="deb1 deb2 php$YNH_DEFAULT_PHP_VERSION-deb1 php$YNH_DEFAULT_PHP_VERSION-deb2" + +phpversion="7.3" + +#================================================= +# PERSONAL HELPERS +#================================================= + +#================================================= +# EXPERIMENTAL HELPERS +#================================================= + +#================================================= +# FUTURE OFFICIAL HELPERS +#================================================= diff --git a/scripts/backup b/scripts/backup index c45c6e1..8a882cb 100644 --- a/scripts/backup +++ b/scripts/backup @@ -6,12 +6,18 @@ # IMPORT GENERIC HELPERS #================================================= +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers #================================================= # MANAGE SCRIPT FAILURE #================================================= +ynh_clean_setup () { + ### Remove this function if there's nothing to clean before calling the remove script. + true +} # Exit if an error occurs during the execution of the script ynh_abort_if_errors @@ -42,6 +48,12 @@ ynh_backup --src_path="$final_path" --is_big ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" +#================================================= +# BACKUP THE PHP-FPM CONFIGURATION +#================================================= + +ynh_backup --src_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" + #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/change_url b/scripts/change_url index 92e6311..22ff689 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -6,6 +6,7 @@ # IMPORT GENERIC HELPERS #================================================= +source _common.sh source /usr/share/yunohost/helpers #================================================= @@ -23,15 +24,15 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading installation settings..." --time --weight=1 # Needed for helper "ynh_add_nginx_config" final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +# BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP #================================================= -ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --weight=1 +ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --time --weight=1 # Backup the current version of the app ynh_backup_before_upgrade @@ -64,7 +65,7 @@ fi #================================================= # MODIFY URL IN NGINX CONF #================================================= -ynh_script_progression --message="Updating NGINX web server configuration..." --weight=3 +ynh_script_progression --message="Updating NGINX web server configuration..." --time --weight=1 nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf @@ -90,12 +91,22 @@ then ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" fi +#================================================= +# SPECIFIC MODIFICATIONS +#================================================= +# ... +#================================================= + #================================================= # GENERIC FINALISATION +#================================================= +# ... +#================================================= + #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 +ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 ynh_systemd_action --service_name=nginx --action=reload @@ -103,4 +114,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Change of URL completed for $app" --last +ynh_script_progression --message="Change of URL completed for $app" --time --last diff --git a/scripts/config b/scripts/config new file mode 100644 index 0000000..b9e79f8 --- /dev/null +++ b/scripts/config @@ -0,0 +1,102 @@ +#!/bin/bash +# In simple cases, you don't need a config script. + +# With a simple config_panel.toml, you can write in the app settings, in the +# upstream config file or replace complete files (logo ...) and restart services. + +# The config scripts allows you to go further, to handle specific cases +# (validation of several interdependent fields, specific getter/setter for a value, +# display dynamic informations or choices, pre-loading of config type .cube... ). + +#================================================= +# GENERIC STARTING +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source /usr/share/yunohost/helpers + +ynh_abort_if_errors + +#================================================= +# RETRIEVE ARGUMENTS +#================================================= + +final_path=$(ynh_app_setting_get $app final_path) + +#================================================= +# SPECIFIC GETTERS FOR TOML SHORT KEY +#================================================= + +get__amount() { + # Here we can imagine to have an API call to stripe to know the amount of donation during a month + local amount = 200 + + # It's possible to change some properties of the question by overriding it: + if [ $amount -gt 100 ] + then + cat << EOF +style: success +value: $amount +ask: + en: A lot of donation this month: **$amount €** +EOF + else + cat << EOF +style: danger +value: $amount +ask: + en: Not so much donation this month: $amount € +EOF + fi +} + +get__prices() { + local prices = "$(grep "DONATION\['" "$final_path/settings.py" | sed -r "s@^DONATION\['([^']*)'\]\['([^']*)'\] = '([^']*)'@\1/\2/\3@g" | sed -z 's/\n/,/g;s/,$/\n/')" + if [ "$prices" == "," ]; + then + # Return YNH_NULL if you prefer to not return a value at all. + echo YNH_NULL + else + echo $prices + fi +} + + +#================================================= +# SPECIFIC VALIDATORS FOR TOML SHORT KEYS +#================================================= +validate__publishable_key() { + + # We can imagine here we test if the key is really a publisheable key + (is_secret_key $publishable_key) && + echo 'This key seems to be a secret key' +} + +#================================================= +# SPECIFIC SETTERS FOR TOML SHORT KEYS +#================================================= +set__prices() { + + #--------------------------------------------- + # IMPORTANT: setter are trigger only if a change is detected + #--------------------------------------------- + for price in $(echo $prices | sed "s/,/ /"); do + frequency=$(echo $price | cut -d/ -f1) + currency=$(echo $price | cut -d/ -f2) + price_id=$(echo $price | cut -d/ -f3) + sed "d/DONATION\['$frequency'\]\['$currency'\]" "$final_path/settings.py" + + echo "DONATION['$frequency']['$currency'] = '$price_id'" >> "$final_path/settings.py" + done + + #--------------------------------------------- + # IMPORTANT: to be able to upgrade properly, you have to saved the value in settings too + #--------------------------------------------- + ynh_app_setting_set $app prices $prices +} + +#================================================= +# GENERIC FINALIZATION +#================================================= +ynh_app_config_run $1 diff --git a/scripts/install b/scripts/install index 6c7ce89..86e4f68 100644 --- a/scripts/install +++ b/scripts/install @@ -6,12 +6,17 @@ # IMPORT GENERIC HELPERS #================================================= +source _common.sh source /usr/share/yunohost/helpers #================================================= # MANAGE SCRIPT FAILURE #================================================= +ynh_clean_setup () { + ### Remove this function if there's nothing to clean before calling the remove script. + true +} # Exit if an error occurs during the execution of the script ynh_abort_if_errors @@ -28,26 +33,47 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= -ynh_script_progression --message="Validating installation parameters..." --weight=1 +ynh_script_progression --message="Validating installation parameters..." --time --weight=1 -if [[ "$path_url" != "/" ]] -then - # We use the path url name (e.g. /documents) instead of h5ai for convenience... - final_path=/var/www$path_url -else - final_path=/var/www/$app -fi +final_path=/var/www/$app +test ! -e "$final_path" || ynh_die --message="This path already contains a folder" # Register (book) web path ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url -# Check final_path availability -test ! -e "$final_path" || ynh_die "This path already contains a folder" +#================================================= +# STORE SETTINGS FROM MANIFEST +#================================================= +ynh_script_progression --message="Storing installation settings..." --time --weight=1 + +ynh_app_setting_set --app=$app --key=domain --value=$domain +ynh_app_setting_set --app=$app --key=path --value=$path_url + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# ... +#================================================= + +#================================================= +# INSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Installing dependencies..." --time --weight=1 + +### `ynh_install_app_dependencies` allows you to add any "apt" dependencies to the package. +### Those deb packages will be installed as dependencies of this package. +### If you're not using this helper: +### - Remove the section "REMOVE DEPENDENCIES" in the remove script +### - Remove the variable "pkg_dependencies" in _common.sh +### - As well as the section "REINSTALL DEPENDENCIES" in the restore script +### - And the section "UPGRADE DEPENDENCIES" in the upgrade script + +ynh_install_app_dependencies $pkg_dependencies #================================================= # CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Configuring system user..." --weight=1 +ynh_script_progression --message="Configuring system user..." --time --weight=1 # Create a system user ynh_system_user_create --username=$app --home_dir="$final_path" @@ -55,13 +81,12 @@ ynh_system_user_create --username=$app --home_dir="$final_path" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= -ynh_script_progression --message="Setting up source files..." --weight=4 +ynh_script_progression --message="Setting up source files..." --time --weight=1 ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Download, check integrity, uncompress and patch the source from app.src -ynh_setup_source "$final_path" +ynh_setup_source --dest_dir="$final_path" -# Restore permissions on app files chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" @@ -69,26 +94,58 @@ chown -R $app:www-data "$final_path" #================================================= # NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Configuring NGINX web server..." --weight=1 +ynh_script_progression --message="Configuring NGINX web server..." --time --weight=1 -# Create a dedicated nginx config +# Create a dedicated NGINX config ynh_add_nginx_config +#================================================= +# PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Configuring PHP-FPM..." --time --weight=1 + +# Create a dedicated PHP-FPM config +ynh_add_fpm_config + +#================================================= +# SPECIFIC SETUP +#================================================= +# ... +#================================================= + +#================================================= +# ADD A CONFIGURATION +#================================================= +ynh_script_progression --message="Adding a configuration file..." --time --weight=1 + +ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" + +chmod 400 "$final_path/some_config_file" +chown $app:$app "$final_path/some_config_file" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# ... +#================================================= + #================================================= # SETUP SSOWAT #================================================= -ynh_script_progression --message="Configuring permissions..." --weight=1 +ynh_script_progression --message="Configuring permissions..." --time --weight=1 -# Make app public if necessary or protect it +# Make app public if necessary if [ $is_public -eq 1 ] then + # Everyone can access the app. + # The "main" permission is automatically created before the install script. ynh_permission_update --permission="main" --add="visitors" fi #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 +ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 ynh_systemd_action --service_name=nginx --action=reload @@ -96,4 +153,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Installation of $app completed" --last +ynh_script_progression --message="Installation of $app completed" --time --last diff --git a/scripts/remove b/scripts/remove index 734f57e..1ef375f 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,17 +1,18 @@ #!/bin/bash #================================================= -# GENERIC STARTING +# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= +source _common.sh source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading installation settings..." --time --weight=1 app=$YNH_APP_INSTANCE_NAME @@ -19,24 +20,59 @@ domain=$(ynh_app_setting_get --app=$app --key=domain) final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= -# REMOVE THE MAIN DIR OF THE APP +# STANDARD REMOVE +#================================================= +# ... #================================================= -ynh_script_progression --message="Removing $app main directory..." --weight=3 -# Remove sources +#================================================= +# REMOVE APP MAIN DIR +#================================================= +ynh_script_progression --message="Removing app main directory..." --time --weight=1 + +# Remove the app directory securely ynh_secure_remove --file="$final_path" #================================================= -# REMOVE THE NGINX CONFIGURATION +# REMOVE NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Removing NGINX web server configuration..." --weight=1 +ynh_script_progression --message="Removing NGINX web server configuration..." --time --weight=1 +# Remove the dedicated NGINX config ynh_remove_nginx_config +#================================================= +# REMOVE PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Removing PHP-FPM configuration..." --time --weight=1 + +# Remove the dedicated PHP-FPM config +ynh_remove_fpm_config + +#================================================= +# REMOVE DEPENDENCIES +#================================================= +ynh_script_progression --message="Removing dependencies..." --time --weight=1 + +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + +#================================================= +# SPECIFIC REMOVE +#================================================= +# REMOVE VARIOUS FILES +#================================================= +ynh_script_progression --message="Removing various files..." --time --weight=1 + +# Remove a directory securely +ynh_secure_remove --file="/etc/$app" + +#================================================= +# GENERIC FINALIZATION #================================================= # REMOVE DEDICATED USER #================================================= -ynh_script_progression --message="Removing the dedicated system user..." --weight=1 +ynh_script_progression --message="Removing the dedicated system user..." --time --weight=1 # Delete a system user ynh_system_user_delete --username=$app @@ -45,4 +81,4 @@ ynh_system_user_delete --username=$app # END OF SCRIPT #================================================= -ynh_script_progression --message="Removal of $app completed" --last +ynh_script_progression --message="Removal of $app completed" --time --last diff --git a/scripts/restore b/scripts/restore index aa8b395..70ad96d 100644 --- a/scripts/restore +++ b/scripts/restore @@ -6,19 +6,25 @@ # IMPORT GENERIC HELPERS #================================================= +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers #================================================= # MANAGE SCRIPT FAILURE #================================================= +ynh_clean_setup () { + #### Remove this function if there's nothing to clean before calling the remove script. + true +} # Exit if an error occurs during the execution of the script ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading installation settings..." --time --weight=1 app=$YNH_APP_INSTANCE_NAME @@ -29,7 +35,7 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # CHECK IF THE APP CAN BE RESTORED #================================================= -ynh_script_progression --message="Validating restoration parameters..." --weight=1 +ynh_script_progression --message="Validating restoration parameters..." --time --weight=1 test ! -d $final_path \ || ynh_die --message="There is already a directory: $final_path " @@ -39,13 +45,14 @@ test ! -d $final_path \ #================================================= # RESTORE THE NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Restoring the NGINX web server configuration..." --time --weight=1 ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= # RECREATE THE DEDICATED USER #================================================= -ynh_script_progression --message="Recreating the dedicated system user..." --weight=1 +ynh_script_progression --message="Recreating the dedicated system user..." --time --weight=1 # Create the dedicated user (if not existing) ynh_system_user_create --username=$app --home_dir="$final_path" @@ -53,26 +60,50 @@ ynh_system_user_create --username=$app --home_dir="$final_path" #================================================= # RESTORE THE APP MAIN DIR #================================================= -ynh_script_progression --message="Restoring the app main directory..." --weight=4 +ynh_script_progression --message="Restoring the app main directory..." --time --weight=1 ynh_restore_file --origin_path="$final_path" -# Restore permissions on app files chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" +#================================================= +# RESTORE THE PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the PHP-FPM configuration..." --time --weight=1 + +ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" + +#================================================= +# SPECIFIC RESTORATION +#================================================= +# REINSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Reinstalling dependencies..." --time --weight=1 + +# Define and install dependencies +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# RESTORE VARIOUS FILES +#================================================= +ynh_script_progression --message="Restoring various files..." --time --weight=1 + +ynh_restore_file --origin_path="/etc/$app/" + #================================================= # GENERIC FINALIZATION #================================================= -# RELOAD NGINX +# RELOAD NGINX AND PHP-FPM #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 +ynh_script_progression --message="Reloading NGINX web server and PHP-FPM..." --time --weight=1 +ynh_systemd_action --service_name=php$phpversion-fpm --action=reload ynh_systemd_action --service_name=nginx --action=reload #================================================= # END OF SCRIPT #================================================= -ynh_script_progression --message="Restoration completed for $app" --last +ynh_script_progression --message="Restoration completed for $app" --time --last diff --git a/scripts/upgrade b/scripts/upgrade index 8bd5203..63ddbeb 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -6,12 +6,13 @@ # IMPORT GENERIC HELPERS #================================================= +source _common.sh source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading installation settings..." --time --weight=1 app=$YNH_APP_INSTANCE_NAME if [[ "$path_url" != "/" ]] @@ -22,9 +23,9 @@ else final_path=/var/www/$app fi +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) -domain=$(ynh_app_setting_get --app=$app --key=domain) #================================================= # CHECK VERSION @@ -35,38 +36,50 @@ upgrade_type=$(ynh_check_app_version_changed) #================================================= # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP #================================================= -ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=1 +ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --time --weight=1 # Backup the current version of the app ynh_backup_before_upgrade ynh_clean_setup () { - # restore it if the upgrade fails + # Restore it if the upgrade fails ynh_restore_upgradebackup } # Exit if an error occurs during the execution of the script ynh_abort_if_errors +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# ... +#================================================= + #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= -ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 +ynh_script_progression --message="Ensuring downward compatibility..." --time --weight=1 + +# +# N.B. : the followings setting migrations snippets are provided as *EXAMPLES* +# of what you may want to do in some cases (e.g. a setting was not defined on +# some legacy installs and you therefore want to initiaze stuff during upgrade) +# + +# If db_name doesn't exist, create it +#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 - final_path=/var/www/$app - ynh_app_setting_set --app=$app --key=final_path --value=$final_path -fi +#if [ -z "$final_path" ]; then +# final_path=/var/www/$app +# ynh_app_setting_set --app=$app --key=final_path --value=$final_path +#fi -# Cleaning legacy permissions -if ynh_legacy_permissions_exists; then - ynh_legacy_permissions_delete_all - - ynh_app_setting_delete --app=$app --key=is_public -fi #================================================= # CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1 +ynh_script_progression --message="Making sure dedicated system user exists..." --time --weight=1 # Create a dedicated user (if not existing) ynh_system_user_create --username=$app --home_dir="$final_path" @@ -77,13 +90,12 @@ ynh_system_user_create --username=$app --home_dir="$final_path" if [ "$upgrade_type" == "UPGRADE_APP" ] then - ynh_script_progression --message="Upgrading source files..." --weight=4 + ynh_script_progression --message="Upgrading source files..." --time --weight=1 # Download, check integrity, uncompress and patch the source from app.src ynh_setup_source --dest_dir="$final_path" fi -# Set permissions on app files chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" @@ -91,15 +103,67 @@ chown -R $app:www-data "$final_path" #================================================= # NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 +ynh_script_progression --message="Upgrading NGINX web server configuration..." --time --weight=1 # Create a dedicated NGINX config ynh_add_nginx_config +#================================================= +# UPGRADE DEPENDENCIES +#================================================= +ynh_script_progression --message="Upgrading dependencies..." --time --weight=1 + +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Upgrading PHP-FPM configuration..." --time --weight=1 + +# Create a dedicated PHP-FPM config +ynh_add_fpm_config + +#================================================= +# SPECIFIC UPGRADE +#================================================= +# ... +#================================================= + +#================================================= +# UPDATE A CONFIG FILE +#================================================= +ynh_script_progression --message="Updating a configuration file..." --time --weight=1 + +### Same as during install +### +### The file will automatically be backed-up if it's found to be manually modified (because +### ynh_add_config keeps track of the file's checksum) + +ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" + +# FIXME: this should be handled by the core in the future +# You may need to use chmod 600 instead of 400, +# for example if the app is expected to be able to modify its own config +chmod 400 "$final_path/some_config_file" +chown $app:$app "$final_path/some_config_file" + +### For more complex cases where you want to replace stuff using regexes, +### you shoud rely on ynh_replace_string (which is basically a wrapper for sed) +### When doing so, you also need to manually call ynh_store_file_checksum +### +### ynh_replace_string --match_string="match_string" --replace_string="replace_string" --target_file="$final_path/some_config_file" +### ynh_store_file_checksum --file="$final_path/some_config_file" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# ... +#================================================= + #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 +ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 ynh_systemd_action --service_name=nginx --action=reload @@ -107,4 +171,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Upgrade of $app completed" --last +ynh_script_progression --message="Upgrade of $app completed" --time --last From 77b10a542d338e1e1d8c52175b54e44c85e66297 Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Thu, 31 Mar 2022 17:52:17 +0000 Subject: [PATCH 03/26] Fix dependencies --- scripts/_common.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/_common.sh b/scripts/_common.sh index dc0d03b..0177438 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,11 +4,11 @@ # COMMON VARIABLES #================================================= -# dependencies used by the app -#pkg_dependencies="deb1 deb2 php$YNH_DEFAULT_PHP_VERSION-deb1 php$YNH_DEFAULT_PHP_VERSION-deb2" - phpversion="7.3" +# dependencies used by the app +pkg_dependencies="php$phpversion-fpm ffmpeg imagemagick" + #================================================= # PERSONAL HELPERS #================================================= From af27d37d30adabfbd656c322ae8e7eb1b072b371 Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Fri, 1 Apr 2022 12:18:59 +0000 Subject: [PATCH 04/26] Remove config file for now --- scripts/install | 8 ++++---- scripts/upgrade | 23 ++++------------------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/scripts/install b/scripts/install index 86e4f68..dfcd627 100644 --- a/scripts/install +++ b/scripts/install @@ -116,12 +116,12 @@ ynh_add_fpm_config #================================================= # ADD A CONFIGURATION #================================================= -ynh_script_progression --message="Adding a configuration file..." --time --weight=1 +#ynh_script_progression --message="Adding a configuration file..." --time --weight=1 -ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" +#ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" -chmod 400 "$final_path/some_config_file" -chown $app:$app "$final_path/some_config_file" +#chmod 400 "$final_path/some_config_file" +#chown $app:$app "$final_path/some_config_file" #================================================= # GENERIC FINALIZATION diff --git a/scripts/upgrade b/scripts/upgrade index 63ddbeb..77dc801 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -132,27 +132,12 @@ ynh_add_fpm_config #================================================= # UPDATE A CONFIG FILE #================================================= -ynh_script_progression --message="Updating a configuration file..." --time --weight=1 +#ynh_script_progression --message="Updating a configuration file..." --time --weight=1 -### Same as during install -### -### The file will automatically be backed-up if it's found to be manually modified (because -### ynh_add_config keeps track of the file's checksum) +#ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" -ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" - -# FIXME: this should be handled by the core in the future -# You may need to use chmod 600 instead of 400, -# for example if the app is expected to be able to modify its own config -chmod 400 "$final_path/some_config_file" -chown $app:$app "$final_path/some_config_file" - -### For more complex cases where you want to replace stuff using regexes, -### you shoud rely on ynh_replace_string (which is basically a wrapper for sed) -### When doing so, you also need to manually call ynh_store_file_checksum -### -### ynh_replace_string --match_string="match_string" --replace_string="replace_string" --target_file="$final_path/some_config_file" -### ynh_store_file_checksum --file="$final_path/some_config_file" +#chmod 400 "$final_path/some_config_file" +#chown $app:$app "$final_path/some_config_file" #================================================= # GENERIC FINALIZATION From bce144322e43f4c1b6e75d2e978735a589de69ee Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Sat, 2 Apr 2022 01:47:22 +0000 Subject: [PATCH 05/26] fix restore script --- scripts/restore | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/restore b/scripts/restore index 70ad96d..add9f04 100644 --- a/scripts/restore +++ b/scripts/restore @@ -88,9 +88,7 @@ ynh_install_app_dependencies $pkg_dependencies #================================================= # RESTORE VARIOUS FILES #================================================= -ynh_script_progression --message="Restoring various files..." --time --weight=1 - -ynh_restore_file --origin_path="/etc/$app/" +#ynh_script_progression --message="Restoring various files..." --time --weight=1 #================================================= # GENERIC FINALIZATION From e93e5e6f0e80a75799dabcb3bebce090341d5184 Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Mon, 4 Apr 2022 18:12:41 +0000 Subject: [PATCH 06/26] remove --time --- scripts/change_url | 10 +++++----- scripts/install | 22 +++++++++++----------- scripts/remove | 16 ++++++++-------- scripts/restore | 20 ++++++++++---------- scripts/upgrade | 22 +++++++++++----------- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/scripts/change_url b/scripts/change_url index 22ff689..720ae93 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -24,7 +24,7 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --time --weight=1 +ynh_script_progression --message="Loading installation settings..." --weight=1 # Needed for helper "ynh_add_nginx_config" final_path=$(ynh_app_setting_get --app=$app --key=final_path) @@ -32,7 +32,7 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP #================================================= -ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --time --weight=1 +ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --weight=1 # Backup the current version of the app ynh_backup_before_upgrade @@ -65,7 +65,7 @@ fi #================================================= # MODIFY URL IN NGINX CONF #================================================= -ynh_script_progression --message="Updating NGINX web server configuration..." --time --weight=1 +ynh_script_progression --message="Updating NGINX web server configuration..." --weight=1 nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf @@ -106,7 +106,7 @@ fi #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 +ynh_script_progression --message="Reloading NGINX web server..." --weight=1 ynh_systemd_action --service_name=nginx --action=reload @@ -114,4 +114,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Change of URL completed for $app" --time --last +ynh_script_progression --message="Change of URL completed for $app" --last diff --git a/scripts/install b/scripts/install index dfcd627..3132f9f 100644 --- a/scripts/install +++ b/scripts/install @@ -33,7 +33,7 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= -ynh_script_progression --message="Validating installation parameters..." --time --weight=1 +ynh_script_progression --message="Validating installation parameters..." --weight=1 final_path=/var/www/$app test ! -e "$final_path" || ynh_die --message="This path already contains a folder" @@ -44,7 +44,7 @@ ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url #================================================= # STORE SETTINGS FROM MANIFEST #================================================= -ynh_script_progression --message="Storing installation settings..." --time --weight=1 +ynh_script_progression --message="Storing installation settings..." --weight=1 ynh_app_setting_set --app=$app --key=domain --value=$domain ynh_app_setting_set --app=$app --key=path --value=$path_url @@ -58,7 +58,7 @@ ynh_app_setting_set --app=$app --key=path --value=$path_url #================================================= # INSTALL DEPENDENCIES #================================================= -ynh_script_progression --message="Installing dependencies..." --time --weight=1 +ynh_script_progression --message="Installing dependencies..." --weight=1 ### `ynh_install_app_dependencies` allows you to add any "apt" dependencies to the package. ### Those deb packages will be installed as dependencies of this package. @@ -73,7 +73,7 @@ ynh_install_app_dependencies $pkg_dependencies #================================================= # CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Configuring system user..." --time --weight=1 +ynh_script_progression --message="Configuring system user..." --weight=1 # Create a system user ynh_system_user_create --username=$app --home_dir="$final_path" @@ -81,7 +81,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= -ynh_script_progression --message="Setting up source files..." --time --weight=1 +ynh_script_progression --message="Setting up source files..." --weight=1 ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Download, check integrity, uncompress and patch the source from app.src @@ -94,7 +94,7 @@ chown -R $app:www-data "$final_path" #================================================= # NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Configuring NGINX web server..." --time --weight=1 +ynh_script_progression --message="Configuring NGINX web server..." --weight=1 # Create a dedicated NGINX config ynh_add_nginx_config @@ -102,7 +102,7 @@ ynh_add_nginx_config #================================================= # PHP-FPM CONFIGURATION #================================================= -ynh_script_progression --message="Configuring PHP-FPM..." --time --weight=1 +ynh_script_progression --message="Configuring PHP-FPM..." --weight=1 # Create a dedicated PHP-FPM config ynh_add_fpm_config @@ -116,7 +116,7 @@ ynh_add_fpm_config #================================================= # ADD A CONFIGURATION #================================================= -#ynh_script_progression --message="Adding a configuration file..." --time --weight=1 +#ynh_script_progression --message="Adding a configuration file..." --weight=1 #ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" @@ -132,7 +132,7 @@ ynh_add_fpm_config #================================================= # SETUP SSOWAT #================================================= -ynh_script_progression --message="Configuring permissions..." --time --weight=1 +ynh_script_progression --message="Configuring permissions..." --weight=1 # Make app public if necessary if [ $is_public -eq 1 ] @@ -145,7 +145,7 @@ fi #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 +ynh_script_progression --message="Reloading NGINX web server..." --weight=1 ynh_systemd_action --service_name=nginx --action=reload @@ -153,4 +153,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Installation of $app completed" --time --last +ynh_script_progression --message="Installation of $app completed" --last diff --git a/scripts/remove b/scripts/remove index 1ef375f..7c6361b 100644 --- a/scripts/remove +++ b/scripts/remove @@ -12,7 +12,7 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --time --weight=1 +ynh_script_progression --message="Loading installation settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME @@ -28,7 +28,7 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # REMOVE APP MAIN DIR #================================================= -ynh_script_progression --message="Removing app main directory..." --time --weight=1 +ynh_script_progression --message="Removing app main directory..." --weight=1 # Remove the app directory securely ynh_secure_remove --file="$final_path" @@ -36,7 +36,7 @@ ynh_secure_remove --file="$final_path" #================================================= # REMOVE NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Removing NGINX web server configuration..." --time --weight=1 +ynh_script_progression --message="Removing NGINX web server configuration..." --weight=1 # Remove the dedicated NGINX config ynh_remove_nginx_config @@ -44,7 +44,7 @@ ynh_remove_nginx_config #================================================= # REMOVE PHP-FPM CONFIGURATION #================================================= -ynh_script_progression --message="Removing PHP-FPM configuration..." --time --weight=1 +ynh_script_progression --message="Removing PHP-FPM configuration..." --weight=1 # Remove the dedicated PHP-FPM config ynh_remove_fpm_config @@ -52,7 +52,7 @@ ynh_remove_fpm_config #================================================= # REMOVE DEPENDENCIES #================================================= -ynh_script_progression --message="Removing dependencies..." --time --weight=1 +ynh_script_progression --message="Removing dependencies..." --weight=1 # Remove metapackage and its dependencies ynh_remove_app_dependencies @@ -62,7 +62,7 @@ ynh_remove_app_dependencies #================================================= # REMOVE VARIOUS FILES #================================================= -ynh_script_progression --message="Removing various files..." --time --weight=1 +ynh_script_progression --message="Removing various files..." --weight=1 # Remove a directory securely ynh_secure_remove --file="/etc/$app" @@ -72,7 +72,7 @@ ynh_secure_remove --file="/etc/$app" #================================================= # REMOVE DEDICATED USER #================================================= -ynh_script_progression --message="Removing the dedicated system user..." --time --weight=1 +ynh_script_progression --message="Removing the dedicated system user..." --weight=1 # Delete a system user ynh_system_user_delete --username=$app @@ -81,4 +81,4 @@ ynh_system_user_delete --username=$app # END OF SCRIPT #================================================= -ynh_script_progression --message="Removal of $app completed" --time --last +ynh_script_progression --message="Removal of $app completed" --last diff --git a/scripts/restore b/scripts/restore index add9f04..5f158ff 100644 --- a/scripts/restore +++ b/scripts/restore @@ -24,7 +24,7 @@ ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --time --weight=1 +ynh_script_progression --message="Loading installation settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME @@ -35,7 +35,7 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # CHECK IF THE APP CAN BE RESTORED #================================================= -ynh_script_progression --message="Validating restoration parameters..." --time --weight=1 +ynh_script_progression --message="Validating restoration parameters..." --weight=1 test ! -d $final_path \ || ynh_die --message="There is already a directory: $final_path " @@ -45,14 +45,14 @@ test ! -d $final_path \ #================================================= # RESTORE THE NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Restoring the NGINX web server configuration..." --time --weight=1 +ynh_script_progression --message="Restoring the NGINX web server configuration..." --weight=1 ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= # RECREATE THE DEDICATED USER #================================================= -ynh_script_progression --message="Recreating the dedicated system user..." --time --weight=1 +ynh_script_progression --message="Recreating the dedicated system user..." --weight=1 # Create the dedicated user (if not existing) ynh_system_user_create --username=$app --home_dir="$final_path" @@ -60,7 +60,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" #================================================= # RESTORE THE APP MAIN DIR #================================================= -ynh_script_progression --message="Restoring the app main directory..." --time --weight=1 +ynh_script_progression --message="Restoring the app main directory..." --weight=1 ynh_restore_file --origin_path="$final_path" @@ -71,7 +71,7 @@ chown -R $app:www-data "$final_path" #================================================= # RESTORE THE PHP-FPM CONFIGURATION #================================================= -ynh_script_progression --message="Restoring the PHP-FPM configuration..." --time --weight=1 +ynh_script_progression --message="Restoring the PHP-FPM configuration..." --weight=1 ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" @@ -80,7 +80,7 @@ ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" #================================================= # REINSTALL DEPENDENCIES #================================================= -ynh_script_progression --message="Reinstalling dependencies..." --time --weight=1 +ynh_script_progression --message="Reinstalling dependencies..." --weight=1 # Define and install dependencies ynh_install_app_dependencies $pkg_dependencies @@ -88,14 +88,14 @@ ynh_install_app_dependencies $pkg_dependencies #================================================= # RESTORE VARIOUS FILES #================================================= -#ynh_script_progression --message="Restoring various files..." --time --weight=1 +#ynh_script_progression --message="Restoring various files..." --weight=1 #================================================= # GENERIC FINALIZATION #================================================= # RELOAD NGINX AND PHP-FPM #================================================= -ynh_script_progression --message="Reloading NGINX web server and PHP-FPM..." --time --weight=1 +ynh_script_progression --message="Reloading NGINX web server and PHP-FPM..." --weight=1 ynh_systemd_action --service_name=php$phpversion-fpm --action=reload ynh_systemd_action --service_name=nginx --action=reload @@ -104,4 +104,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Restoration completed for $app" --time --last +ynh_script_progression --message="Restoration completed for $app" --last diff --git a/scripts/upgrade b/scripts/upgrade index 77dc801..93e5891 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -12,7 +12,7 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --time --weight=1 +ynh_script_progression --message="Loading installation settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME if [[ "$path_url" != "/" ]] @@ -36,7 +36,7 @@ upgrade_type=$(ynh_check_app_version_changed) #================================================= # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP #================================================= -ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --time --weight=1 +ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=1 # Backup the current version of the app ynh_backup_before_upgrade @@ -56,7 +56,7 @@ ynh_abort_if_errors #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= -ynh_script_progression --message="Ensuring downward compatibility..." --time --weight=1 +ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 # # N.B. : the followings setting migrations snippets are provided as *EXAMPLES* @@ -79,7 +79,7 @@ ynh_script_progression --message="Ensuring downward compatibility..." --time --w #================================================= # CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." --time --weight=1 +ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1 # Create a dedicated user (if not existing) ynh_system_user_create --username=$app --home_dir="$final_path" @@ -90,7 +90,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" if [ "$upgrade_type" == "UPGRADE_APP" ] then - ynh_script_progression --message="Upgrading source files..." --time --weight=1 + ynh_script_progression --message="Upgrading source files..." --weight=1 # Download, check integrity, uncompress and patch the source from app.src ynh_setup_source --dest_dir="$final_path" @@ -103,7 +103,7 @@ chown -R $app:www-data "$final_path" #================================================= # NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Upgrading NGINX web server configuration..." --time --weight=1 +ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 # Create a dedicated NGINX config ynh_add_nginx_config @@ -111,14 +111,14 @@ ynh_add_nginx_config #================================================= # UPGRADE DEPENDENCIES #================================================= -ynh_script_progression --message="Upgrading dependencies..." --time --weight=1 +ynh_script_progression --message="Upgrading dependencies..." --weight=1 ynh_install_app_dependencies $pkg_dependencies #================================================= # PHP-FPM CONFIGURATION #================================================= -ynh_script_progression --message="Upgrading PHP-FPM configuration..." --time --weight=1 +ynh_script_progression --message="Upgrading PHP-FPM configuration..." --weight=1 # Create a dedicated PHP-FPM config ynh_add_fpm_config @@ -132,7 +132,7 @@ ynh_add_fpm_config #================================================= # UPDATE A CONFIG FILE #================================================= -#ynh_script_progression --message="Updating a configuration file..." --time --weight=1 +#ynh_script_progression --message="Updating a configuration file..." --weight=1 #ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" @@ -148,7 +148,7 @@ ynh_add_fpm_config #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 +ynh_script_progression --message="Reloading NGINX web server..." --weight=1 ynh_systemd_action --service_name=nginx --action=reload @@ -156,4 +156,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Upgrade of $app completed" --time --last +ynh_script_progression --message="Upgrade of $app completed" --last From 3014fc5f964f81f45d40bf3f429ebcb1f7020915 Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Mon, 4 Apr 2022 18:14:17 +0000 Subject: [PATCH 07/26] fix --- scripts/install | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/install b/scripts/install index 3132f9f..048ea77 100644 --- a/scripts/install +++ b/scripts/install @@ -35,7 +35,13 @@ app=$YNH_APP_INSTANCE_NAME #================================================= ynh_script_progression --message="Validating installation parameters..." --weight=1 -final_path=/var/www/$app +if [[ "$path_url" != "/" ]] +then + # We use the path url name (e.g. /documents) instead of h5ai for convenience... + final_path=/var/www$path_url +else + final_path=/var/www/$app +fi test ! -e "$final_path" || ynh_die --message="This path already contains a folder" # Register (book) web path From a4faf5c6f034051b3d3d19e1be4a6c73925dbedb Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Mon, 4 Apr 2022 20:21:11 +0200 Subject: [PATCH 08/26] Apply suggestions from code review --- scripts/change_url | 2 +- scripts/install | 2 +- scripts/remove | 2 +- scripts/restore | 2 +- scripts/upgrade | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/change_url b/scripts/change_url index 720ae93..7eba06d 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -65,7 +65,7 @@ fi #================================================= # MODIFY URL IN NGINX CONF #================================================= -ynh_script_progression --message="Updating NGINX web server configuration..." --weight=1 +ynh_script_progression --message="Updating NGINX web server configuration..." --weight=3 nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf diff --git a/scripts/install b/scripts/install index 048ea77..e18c3ef 100644 --- a/scripts/install +++ b/scripts/install @@ -87,7 +87,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= -ynh_script_progression --message="Setting up source files..." --weight=1 +ynh_script_progression --message="Setting up source files..." --weight=4 ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Download, check integrity, uncompress and patch the source from app.src diff --git a/scripts/remove b/scripts/remove index 7c6361b..93d6724 100644 --- a/scripts/remove +++ b/scripts/remove @@ -28,7 +28,7 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # REMOVE APP MAIN DIR #================================================= -ynh_script_progression --message="Removing app main directory..." --weight=1 +ynh_script_progression --message="Removing app main directory..." --weight=3 # Remove the app directory securely ynh_secure_remove --file="$final_path" diff --git a/scripts/restore b/scripts/restore index 5f158ff..27f9724 100644 --- a/scripts/restore +++ b/scripts/restore @@ -60,7 +60,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" #================================================= # RESTORE THE APP MAIN DIR #================================================= -ynh_script_progression --message="Restoring the app main directory..." --weight=1 +ynh_script_progression --message="Restoring the app main directory..." --weight=4 ynh_restore_file --origin_path="$final_path" diff --git a/scripts/upgrade b/scripts/upgrade index 93e5891..e21ca0f 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -90,7 +90,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" if [ "$upgrade_type" == "UPGRADE_APP" ] then - ynh_script_progression --message="Upgrading source files..." --weight=1 + ynh_script_progression --message="Upgrading source files..." --weight=4 # Download, check integrity, uncompress and patch the source from app.src ynh_setup_source --dest_dir="$final_path" From ed091b498073b547cb939d4424c3c9d7dcbbd143 Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Mon, 4 Apr 2022 20:22:57 +0200 Subject: [PATCH 09/26] Update scripts/remove --- scripts/remove | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/remove b/scripts/remove index 93d6724..bcbd72a 100644 --- a/scripts/remove +++ b/scripts/remove @@ -60,12 +60,9 @@ ynh_remove_app_dependencies #================================================= # SPECIFIC REMOVE #================================================= -# REMOVE VARIOUS FILES +# ... #================================================= -ynh_script_progression --message="Removing various files..." --weight=1 -# Remove a directory securely -ynh_secure_remove --file="/etc/$app" #================================================= # GENERIC FINALIZATION From 378990cb6dfd87958cba7d30dfb6e9647ad1785d Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Wed, 4 May 2022 01:21:56 +0200 Subject: [PATCH 10/26] Update scripts/remove --- scripts/remove | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/remove b/scripts/remove index bcbd72a..92c3940 100644 --- a/scripts/remove +++ b/scripts/remove @@ -31,7 +31,7 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) ynh_script_progression --message="Removing app main directory..." --weight=3 # Remove the app directory securely -ynh_secure_remove --file="$final_path" +ynh_secure_remove --file="$final_path/_h5ai" #================================================= # REMOVE NGINX CONFIGURATION From 9f162a606bbf38289a08673f5adfd2e4ea0ab410 Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Sat, 20 Aug 2022 20:27:00 +0000 Subject: [PATCH 11/26] Allow install in existing folder --- scripts/install | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/install b/scripts/install index 048ea77..bf46782 100644 --- a/scripts/install +++ b/scripts/install @@ -42,7 +42,6 @@ then else final_path=/var/www/$app fi -test ! -e "$final_path" || ynh_die --message="This path already contains a folder" # Register (book) web path ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url From cc770f3feecceb0e640616c86b99ea81e7f97819 Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Sat, 20 Aug 2022 22:28:35 +0200 Subject: [PATCH 12/26] Remove unecessary comment --- scripts/install | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/install b/scripts/install index a80cb55..43f5491 100644 --- a/scripts/install +++ b/scripts/install @@ -65,7 +65,6 @@ ynh_app_setting_set --app=$app --key=path --value=$path_url #================================================= ynh_script_progression --message="Installing dependencies..." --weight=1 -### `ynh_install_app_dependencies` allows you to add any "apt" dependencies to the package. ### Those deb packages will be installed as dependencies of this package. ### If you're not using this helper: ### - Remove the section "REMOVE DEPENDENCIES" in the remove script From 568764bdaf1c55ebb64c551d1e074c4ac9d6a776 Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Sat, 20 Aug 2022 20:31:09 +0000 Subject: [PATCH 13/26] Implement --purge in the remove script --- scripts/remove | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/remove b/scripts/remove index 92c3940..abc28db 100644 --- a/scripts/remove +++ b/scripts/remove @@ -33,6 +33,12 @@ ynh_script_progression --message="Removing app main directory..." --weight=3 # Remove the app directory securely ynh_secure_remove --file="$final_path/_h5ai" +# Remove the data directory if --purge option is used +if [ "${YNH_APP_PURGE:-0}" -eq 1 ] +then + ynh_secure_remove --file="$final_path" +fi + #================================================= # REMOVE NGINX CONFIGURATION #================================================= From 5543e41f30affc8694c834f21558b09210569d02 Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Sat, 20 Aug 2022 22:53:10 +0200 Subject: [PATCH 14/26] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Éric Gaspar <46165813+ericgaspar@users.noreply.github.com> --- manifest.json | 2 +- scripts/_common.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manifest.json b/manifest.json index 9a1b3cd..61f1449 100644 --- a/manifest.json +++ b/manifest.json @@ -26,7 +26,7 @@ "multi_instance": true, "services": [ "nginx", - "php7.3-fpm" + "php7.4-fpm" ], "arguments": { "install" : [ diff --git a/scripts/_common.sh b/scripts/_common.sh index 0177438..6fb7135 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,10 +4,10 @@ # COMMON VARIABLES #================================================= -phpversion="7.3" +YNH_PHP_VERSION=7.4 # dependencies used by the app -pkg_dependencies="php$phpversion-fpm ffmpeg imagemagick" +pkg_dependencies="php$YNH_PHP_VERSION-fpm ffmpeg imagemagick" #================================================= # PERSONAL HELPERS From 8b2957e2c7a695045ade18fc6530ac2b11e8e076 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Fri, 26 Aug 2022 08:15:48 +0200 Subject: [PATCH 15/26] Cleaning up --- scripts/change_url | 12 ----------- scripts/install | 35 ------------------------------- scripts/remove | 13 ------------ scripts/restore | 5 ----- scripts/upgrade | 51 ---------------------------------------------- 5 files changed, 116 deletions(-) diff --git a/scripts/change_url b/scripts/change_url index 7eba06d..7d347e3 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -91,18 +91,6 @@ then ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" fi -#================================================= -# SPECIFIC MODIFICATIONS -#================================================= -# ... -#================================================= - -#================================================= -# GENERIC FINALISATION -#================================================= -# ... -#================================================= - #================================================= # RELOAD NGINX #================================================= diff --git a/scripts/install b/scripts/install index 43f5491..5c2c8b7 100644 --- a/scripts/install +++ b/scripts/install @@ -54,24 +54,11 @@ ynh_script_progression --message="Storing installation settings..." --weight=1 ynh_app_setting_set --app=$app --key=domain --value=$domain ynh_app_setting_set --app=$app --key=path --value=$path_url -#================================================= -# STANDARD MODIFICATIONS -#================================================= -# ... -#================================================= - #================================================= # INSTALL DEPENDENCIES #================================================= ynh_script_progression --message="Installing dependencies..." --weight=1 -### Those deb packages will be installed as dependencies of this package. -### If you're not using this helper: -### - Remove the section "REMOVE DEPENDENCIES" in the remove script -### - Remove the variable "pkg_dependencies" in _common.sh -### - As well as the section "REINSTALL DEPENDENCIES" in the restore script -### - And the section "UPGRADE DEPENDENCIES" in the upgrade script - ynh_install_app_dependencies $pkg_dependencies #================================================= @@ -111,28 +98,6 @@ ynh_script_progression --message="Configuring PHP-FPM..." --weight=1 # Create a dedicated PHP-FPM config ynh_add_fpm_config -#================================================= -# SPECIFIC SETUP -#================================================= -# ... -#================================================= - -#================================================= -# ADD A CONFIGURATION -#================================================= -#ynh_script_progression --message="Adding a configuration file..." --weight=1 - -#ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" - -#chmod 400 "$final_path/some_config_file" -#chown $app:$app "$final_path/some_config_file" - -#================================================= -# GENERIC FINALIZATION -#================================================= -# ... -#================================================= - #================================================= # SETUP SSOWAT #================================================= diff --git a/scripts/remove b/scripts/remove index abc28db..3dedba8 100644 --- a/scripts/remove +++ b/scripts/remove @@ -19,12 +19,6 @@ app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get --app=$app --key=domain) final_path=$(ynh_app_setting_get --app=$app --key=final_path) -#================================================= -# STANDARD REMOVE -#================================================= -# ... -#================================================= - #================================================= # REMOVE APP MAIN DIR #================================================= @@ -63,13 +57,6 @@ ynh_script_progression --message="Removing dependencies..." --weight=1 # Remove metapackage and its dependencies ynh_remove_app_dependencies -#================================================= -# SPECIFIC REMOVE -#================================================= -# ... -#================================================= - - #================================================= # GENERIC FINALIZATION #================================================= diff --git a/scripts/restore b/scripts/restore index 27f9724..813cb0f 100644 --- a/scripts/restore +++ b/scripts/restore @@ -85,11 +85,6 @@ ynh_script_progression --message="Reinstalling dependencies..." --weight=1 # Define and install dependencies ynh_install_app_dependencies $pkg_dependencies -#================================================= -# RESTORE VARIOUS FILES -#================================================= -#ynh_script_progression --message="Restoring various files..." --weight=1 - #================================================= # GENERIC FINALIZATION #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index e21ca0f..af7a987 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -47,35 +47,6 @@ ynh_clean_setup () { # Exit if an error occurs during the execution of the script ynh_abort_if_errors -#================================================= -# STANDARD UPGRADE STEPS -#================================================= -# ... -#================================================= - -#================================================= -# ENSURE DOWNWARD COMPATIBILITY -#================================================= -ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 - -# -# N.B. : the followings setting migrations snippets are provided as *EXAMPLES* -# of what you may want to do in some cases (e.g. a setting was not defined on -# some legacy installs and you therefore want to initiaze stuff during upgrade) -# - -# If db_name doesn't exist, create it -#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 -# final_path=/var/www/$app -# ynh_app_setting_set --app=$app --key=final_path --value=$final_path -#fi - #================================================= # CREATE DEDICATED USER #================================================= @@ -123,28 +94,6 @@ ynh_script_progression --message="Upgrading PHP-FPM configuration..." --weight=1 # Create a dedicated PHP-FPM config ynh_add_fpm_config -#================================================= -# SPECIFIC UPGRADE -#================================================= -# ... -#================================================= - -#================================================= -# UPDATE A CONFIG FILE -#================================================= -#ynh_script_progression --message="Updating a configuration file..." --weight=1 - -#ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" - -#chmod 400 "$final_path/some_config_file" -#chown $app:$app "$final_path/some_config_file" - -#================================================= -# GENERIC FINALIZATION -#================================================= -# ... -#================================================= - #================================================= # RELOAD NGINX #================================================= From e9bb0aa28d9bc149508f5a0ee15aea92fe520646 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Sun, 16 Oct 2022 20:26:47 +0200 Subject: [PATCH 16/26] Apply last example_ynh --- .gitattributes | 17 ---------------- .gitignore | 47 ------------------------------------------- check_process | 2 ++ conf/app.src | 1 + conf/nginx.conf | 2 -- doc/DESCRIPTION_fr.md | 7 +++++++ manifest.json | 4 ++-- scripts/_common.sh | 8 ++++++-- scripts/backup | 3 +-- scripts/change_url | 4 +++- scripts/install | 17 ++++++++-------- scripts/remove | 6 ++++-- scripts/restore | 31 ++++++++++++++-------------- scripts/upgrade | 28 +++++++++++++++++--------- 14 files changed, 69 insertions(+), 108 deletions(-) delete mode 100644 .gitattributes delete mode 100644 .gitignore create mode 100644 doc/DESCRIPTION_fr.md diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index bdb0cab..0000000 --- a/.gitattributes +++ /dev/null @@ -1,17 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto - -# Custom for Visual Studio -*.cs diff=csharp - -# Standard to msysgit -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore deleted file mode 100644 index cd2946a..0000000 --- a/.gitignore +++ /dev/null @@ -1,47 +0,0 @@ -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# ========================= -# Operating System Files -# ========================= - -# OSX -# ========================= - -.DS_Store -.AppleDouble -.LSOverride - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk diff --git a/check_process b/check_process index c587673..38c40ba 100644 --- a/check_process +++ b/check_process @@ -12,6 +12,8 @@ setup_public=1 upgrade=1 upgrade=1 from_commit=73f74039fb63adc555222d73ded6b43a64d41456 + # 0.30.0~ynh3 + upgrade=1 from_commit=af190a49ec43b470a38b21d81887a1b457b333fa backup_restore=1 multi_instance=0 change_url=1 diff --git a/conf/app.src b/conf/app.src index 2c6471e..46c7310 100644 --- a/conf/app.src +++ b/conf/app.src @@ -4,3 +4,4 @@ SOURCE_SUM_PRG=sha256sum SOURCE_FORMAT=zip SOURCE_IN_SUBDIR=false SOURCE_FILENAME=h5ai.zip +SOURCE_EXTRACT=true diff --git a/conf/nginx.conf b/conf/nginx.conf index c169ca5..ce361ca 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -4,7 +4,6 @@ location __PATH__/ { # Path to source alias __FINALPATH__/; -### Example PHP configuration (remove it if not used) index index.php __PATH__/_h5ai/public/index.php; # Common parameter to increase upload size limit in conjunction with dedicated php-fpm file @@ -24,7 +23,6 @@ location __PATH__/ { fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_FILENAME $request_filename; } -### End of PHP configuration part # Include SSOWAT user panel. include conf.d/yunohost_panel.conf.inc; diff --git a/doc/DESCRIPTION_fr.md b/doc/DESCRIPTION_fr.md new file mode 100644 index 0000000..2b7a432 --- /dev/null +++ b/doc/DESCRIPTION_fr.md @@ -0,0 +1,7 @@ +h5ai est un indexeur de fichiers moderne pour les serveurs web HTTP avec un focus sur vos fichiers. Les répertoires sont affichés de manière attrayante et leur navigation est améliorée par différentes vues, un fil d'Ariane et une arborescence. + +### Caractéristiques + +Il y a beaucoup d'extensions optionnelles et d'options de configuration pour personnaliser l'apparence web de vos listes de répertoire. Tout le balisage est du HTML5 valide, agrémenté de CSS3 et du JavaScript le plus fin pour construire + +Parmi les fonctionnalités optionnelles, citons : le tri des fichiers, différents modes d'affichage, la localisation, le fil d'Ariane, l'arborescence, les en-têtes et pieds de page personnalisés, le filtrage et la recherche de fichiers, la taille des dossiers, le rafraîchissement automatique, l'emballage... diff --git a/manifest.json b/manifest.json index 61f1449..9639936 100644 --- a/manifest.json +++ b/manifest.json @@ -11,9 +11,9 @@ "upstream": { "license": "MIT", "website": "https://larsjung.de/h5ai/", + "demo": "https://larsjung.de/h5ai/demo/", "admindoc": "https://larsjung.de/h5ai/", - "code": "https://github.com/lrsjng/h5ai", - "demo": "https://larsjung.de/h5ai/demo/" + "code": "https://github.com/lrsjng/h5ai" }, "license": "MIT", "maintainer": { diff --git a/scripts/_common.sh b/scripts/_common.sh index 6fb7135..d311fd0 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -3,11 +3,15 @@ #================================================= # COMMON VARIABLES #================================================= +# PHP APP SPECIFIC +#================================================= YNH_PHP_VERSION=7.4 -# dependencies used by the app -pkg_dependencies="php$YNH_PHP_VERSION-fpm ffmpeg imagemagick" +php_dependencies="php$YNH_PHP_VERSION-fpm" + +# dependencies used by the app (must be on a single line) +pkg_dependencies="ffmpeg imagemagick $php_dependencies" #================================================= # PERSONAL HELPERS diff --git a/scripts/backup b/scripts/backup index 8a882cb..e0a77d8 100644 --- a/scripts/backup +++ b/scripts/backup @@ -15,7 +15,6 @@ source /usr/share/yunohost/helpers #================================================= ynh_clean_setup () { - ### Remove this function if there's nothing to clean before calling the remove script. true } # Exit if an error occurs during the execution of the script @@ -24,7 +23,7 @@ ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_print_info --message="Loading installation settings..." +ynh_print_info --message="Loading settings..." app=$YNH_APP_INSTANCE_NAME diff --git a/scripts/change_url b/scripts/change_url index 7d347e3..fa8736a 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -24,7 +24,7 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading settings..." --weight=1 # Needed for helper "ynh_add_nginx_config" final_path=$(ynh_app_setting_get --app=$app --key=final_path) @@ -91,6 +91,8 @@ then ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" fi +#================================================= +# GENERIC FINALISATION #================================================= # RELOAD NGINX #================================================= diff --git a/scripts/install b/scripts/install index 5c2c8b7..83d2112 100644 --- a/scripts/install +++ b/scripts/install @@ -14,7 +14,6 @@ source /usr/share/yunohost/helpers #================================================= ynh_clean_setup () { - ### Remove this function if there's nothing to clean before calling the remove script. true } # Exit if an error occurs during the execution of the script @@ -82,6 +81,14 @@ chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" +#================================================= +# PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Configuring PHP-FPM..." --weight=1 + +# Create a dedicated PHP-FPM config +ynh_add_fpm_config + #================================================= # NGINX CONFIGURATION #================================================= @@ -91,13 +98,7 @@ ynh_script_progression --message="Configuring NGINX web server..." --weight=1 ynh_add_nginx_config #================================================= -# PHP-FPM CONFIGURATION -#================================================= -ynh_script_progression --message="Configuring PHP-FPM..." --weight=1 - -# Create a dedicated PHP-FPM config -ynh_add_fpm_config - +# GENERIC FINALIZATION #================================================= # SETUP SSOWAT #================================================= diff --git a/scripts/remove b/scripts/remove index 3dedba8..b192533 100644 --- a/scripts/remove +++ b/scripts/remove @@ -12,13 +12,15 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get --app=$app --key=domain) final_path=$(ynh_app_setting_get --app=$app --key=final_path) +#================================================= +# STANDARD REMOVE #================================================= # REMOVE APP MAIN DIR #================================================= @@ -30,7 +32,7 @@ ynh_secure_remove --file="$final_path/_h5ai" # Remove the data directory if --purge option is used if [ "${YNH_APP_PURGE:-0}" -eq 1 ] then - ynh_secure_remove --file="$final_path" + ynh_secure_remove --file="$final_path" fi #================================================= diff --git a/scripts/restore b/scripts/restore index 813cb0f..d6afdf1 100644 --- a/scripts/restore +++ b/scripts/restore @@ -15,7 +15,6 @@ source /usr/share/yunohost/helpers #================================================= ynh_clean_setup () { - #### Remove this function if there's nothing to clean before calling the remove script. true } # Exit if an error occurs during the execution of the script @@ -24,7 +23,7 @@ ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME @@ -42,13 +41,6 @@ test ! -d $final_path \ #================================================= # STANDARD RESTORATION STEPS -#================================================= -# RESTORE THE NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Restoring the NGINX web server configuration..." --weight=1 - -ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" - #================================================= # RECREATE THE DEDICATED USER #================================================= @@ -68,13 +60,6 @@ chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" -#================================================= -# RESTORE THE PHP-FPM CONFIGURATION -#================================================= -ynh_script_progression --message="Restoring the PHP-FPM configuration..." --weight=1 - -ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" - #================================================= # SPECIFIC RESTORATION #================================================= @@ -85,6 +70,20 @@ ynh_script_progression --message="Reinstalling dependencies..." --weight=1 # Define and install dependencies ynh_install_app_dependencies $pkg_dependencies +#================================================= +# RESTORE THE PHP-FPM CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the PHP-FPM configuration..." --weight=1 + +ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" + +#================================================= +# RESTORE THE NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the NGINX web server configuration..." --weight=1 + +ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" + #================================================= # GENERIC FINALIZATION #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index af7a987..1f834e7 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -12,7 +12,7 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Loading settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME if [[ "$path_url" != "/" ]] @@ -30,6 +30,7 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # CHECK VERSION #================================================= +ynh_script_progression --message="Checking version..." --weight=1 upgrade_type=$(ynh_check_app_version_changed) @@ -47,6 +48,13 @@ ynh_clean_setup () { # Exit if an error occurs during the execution of the script ynh_abort_if_errors +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= +ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 + #================================================= # CREATE DEDICATED USER #================================================= @@ -71,14 +79,6 @@ chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 - -# Create a dedicated NGINX config -ynh_add_nginx_config - #================================================= # UPGRADE DEPENDENCIES #================================================= @@ -94,6 +94,16 @@ ynh_script_progression --message="Upgrading PHP-FPM configuration..." --weight=1 # Create a dedicated PHP-FPM config ynh_add_fpm_config +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 + +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# GENERIC FINALIZATION #================================================= # RELOAD NGINX #================================================= From a2956d8587680f6d7e30c27c9740e9f0d253edd5 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Sun, 16 Oct 2022 18:26:54 +0000 Subject: [PATCH 17/26] Auto-update README --- README.md | 31 ++++++++++++++++++++----------- README_fr.md | 37 +++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 0d41372..7cd4f9b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ It shall NOT be edited by hand. # h5ai for YunoHost -[![Integration level](https://dash.yunohost.org/integration/h5ai.svg)](https://dash.yunohost.org/appci/app/h5ai) ![](https://ci-apps.yunohost.org/ci/badges/h5ai.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/h5ai.maintain.svg) +[![Integration level](https://dash.yunohost.org/integration/h5ai.svg)](https://dash.yunohost.org/appci/app/h5ai) ![Working status](https://ci-apps.yunohost.org/ci/badges/h5ai.status.svg) ![Maintenance status](https://ci-apps.yunohost.org/ci/badges/h5ai.maintain.svg) [![Install h5ai with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=h5ai) *[Lire ce readme en français.](./README_fr.md)* @@ -15,15 +15,23 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in ## Overview -Modern HTTP web server index for NGINX +h5ai is a modern file indexer for HTTP web servers with focus on your files. Directories are displayed in a appealing way and browsing them is enhanced by different views, a breadcrumb and a tree overview. + +### Features + +There are lots of optional extensions and configuration options to customize the web appearance of your directory listings. All markup is valid HTML5 spiced up with CSS3 and finest JavaScript to build a fresh but minimal user interface and a user experience that focuses on your files. + +Some of the optional features are: file sorting, different view modes, localization, a breadcrumb, a tree view, custom headers and footers, file filter and search, folder sizes, auto refresh, packaged download, QR codes, thumbnails, file previews + **Shipped version:** 0.30.0~ynh3 - +**Demo:** https://larsjung.de/h5ai/demo/ ## Screenshots -![](./doc/screenshots/screenshot.jpg) +![Screenshot of h5ai](./doc/screenshots/screenshot.jpg) +![Screenshot of h5ai](./doc/screenshots/h5ai-1024x540.png) ## Disclaimers / important information @@ -35,21 +43,22 @@ The main configuration file is `_h5ai/private/conf/options.json`. You might want ## Documentation and resources -* Official app website: https://larsjung.de/h5ai/ -* Official admin documentation: https://larsjung.de/h5ai/ -* Upstream app code repository: https://github.com/lrsjng/h5ai -* YunoHost documentation for this app: https://yunohost.org/app_h5ai -* Report a bug: https://github.com/YunoHost-Apps/h5ai_ynh/issues +* Official app website: +* Official admin documentation: +* Upstream app code repository: +* YunoHost documentation for this app: +* Report a bug: ## Developer info Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing). To try the testing branch, please proceed like that. -``` + +``` bash sudo yunohost app install https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing --debug or sudo yunohost app upgrade h5ai -u https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing --debug ``` -**More info regarding app packaging:** https://yunohost.org/packaging_apps \ No newline at end of file +**More info regarding app packaging:** diff --git a/README_fr.md b/README_fr.md index 0eea75c..8ccd7f7 100644 --- a/README_fr.md +++ b/README_fr.md @@ -1,25 +1,37 @@ + + # h5ai pour YunoHost -[![Niveau d'intégration](https://dash.yunohost.org/integration/h5ai.svg)](https://dash.yunohost.org/appci/app/h5ai) ![](https://ci-apps.yunohost.org/ci/badges/h5ai.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/h5ai.maintain.svg) +[![Niveau d'intégration](https://dash.yunohost.org/integration/h5ai.svg)](https://dash.yunohost.org/appci/app/h5ai) ![Statut du fonctionnement](https://ci-apps.yunohost.org/ci/badges/h5ai.status.svg) ![Statut de maintenance](https://ci-apps.yunohost.org/ci/badges/h5ai.maintain.svg) [![Installer h5ai avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=h5ai) *[Read this readme in english.](./README.md)* -*[Lire ce readme en français.](./README_fr.md)* > *Ce package vous permet d'installer h5ai rapidement et simplement sur un serveur YunoHost. Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* ## Vue d'ensemble -Serveur moderne d'index pour NGINX +h5ai est un indexeur de fichiers moderne pour les serveurs web HTTP avec un focus sur vos fichiers. Les répertoires sont affichés de manière attrayante et leur navigation est améliorée par différentes vues, un fil d'Ariane et une arborescence. + +### Caractéristiques + +Il y a beaucoup d'extensions optionnelles et d'options de configuration pour personnaliser l'apparence web de vos listes de répertoire. Tout le balisage est du HTML5 valide, agrémenté de CSS3 et du JavaScript le plus fin pour construire + +Parmi les fonctionnalités optionnelles, citons : le tri des fichiers, différents modes d'affichage, la localisation, le fil d'Ariane, l'arborescence, les en-têtes et pieds de page personnalisés, le filtrage et la recherche de fichiers, la taille des dossiers, le rafraîchissement automatique, l'emballage... + **Version incluse :** 0.30.0~ynh3 - +**Démo :** https://larsjung.de/h5ai/demo/ ## Captures d'écran -![](./doc/screenshots/screenshot.jpg) +![Capture d'écran de h5ai](./doc/screenshots/screenshot.jpg) +![Capture d'écran de h5ai](./doc/screenshots/h5ai-1024x540.png) ## Avertissements / informations importantes @@ -31,21 +43,22 @@ Le fichier de configuration principal est `_h5ai / private / conf / options.json ## Documentations et ressources -* Site officiel de l'app : https://larsjung.de/h5ai/ -* Documentation officielle de l'admin : https://larsjung.de/h5ai/ -* Dépôt de code officiel de l'app : https://github.com/lrsjng/h5ai -* Documentation YunoHost pour cette app : https://yunohost.org/app_h5ai -* Signaler un bug : https://github.com/YunoHost-Apps/h5ai_ynh/issues +* Site officiel de l'app : +* Documentation officielle de l'admin : +* Dépôt de code officiel de l'app : +* Documentation YunoHost pour cette app : +* Signaler un bug : ## Informations pour les développeurs Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing). Pour essayer la branche testing, procédez comme suit. -``` + +``` bash sudo yunohost app install https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing --debug ou sudo yunohost app upgrade h5ai -u https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing --debug ``` -**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps \ No newline at end of file +**Plus d'infos sur le packaging d'applications :** From 87b736d8e114c53edc5041dc1a4ee490e5ffc24a Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Sun, 16 Oct 2022 18:28:19 +0000 Subject: [PATCH 18/26] Auto-update README --- README.md | 31 ++++++++++++++++++++----------- README_fr.md | 37 +++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 0d41372..7cd4f9b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ It shall NOT be edited by hand. # h5ai for YunoHost -[![Integration level](https://dash.yunohost.org/integration/h5ai.svg)](https://dash.yunohost.org/appci/app/h5ai) ![](https://ci-apps.yunohost.org/ci/badges/h5ai.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/h5ai.maintain.svg) +[![Integration level](https://dash.yunohost.org/integration/h5ai.svg)](https://dash.yunohost.org/appci/app/h5ai) ![Working status](https://ci-apps.yunohost.org/ci/badges/h5ai.status.svg) ![Maintenance status](https://ci-apps.yunohost.org/ci/badges/h5ai.maintain.svg) [![Install h5ai with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=h5ai) *[Lire ce readme en français.](./README_fr.md)* @@ -15,15 +15,23 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in ## Overview -Modern HTTP web server index for NGINX +h5ai is a modern file indexer for HTTP web servers with focus on your files. Directories are displayed in a appealing way and browsing them is enhanced by different views, a breadcrumb and a tree overview. + +### Features + +There are lots of optional extensions and configuration options to customize the web appearance of your directory listings. All markup is valid HTML5 spiced up with CSS3 and finest JavaScript to build a fresh but minimal user interface and a user experience that focuses on your files. + +Some of the optional features are: file sorting, different view modes, localization, a breadcrumb, a tree view, custom headers and footers, file filter and search, folder sizes, auto refresh, packaged download, QR codes, thumbnails, file previews + **Shipped version:** 0.30.0~ynh3 - +**Demo:** https://larsjung.de/h5ai/demo/ ## Screenshots -![](./doc/screenshots/screenshot.jpg) +![Screenshot of h5ai](./doc/screenshots/screenshot.jpg) +![Screenshot of h5ai](./doc/screenshots/h5ai-1024x540.png) ## Disclaimers / important information @@ -35,21 +43,22 @@ The main configuration file is `_h5ai/private/conf/options.json`. You might want ## Documentation and resources -* Official app website: https://larsjung.de/h5ai/ -* Official admin documentation: https://larsjung.de/h5ai/ -* Upstream app code repository: https://github.com/lrsjng/h5ai -* YunoHost documentation for this app: https://yunohost.org/app_h5ai -* Report a bug: https://github.com/YunoHost-Apps/h5ai_ynh/issues +* Official app website: +* Official admin documentation: +* Upstream app code repository: +* YunoHost documentation for this app: +* Report a bug: ## Developer info Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing). To try the testing branch, please proceed like that. -``` + +``` bash sudo yunohost app install https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing --debug or sudo yunohost app upgrade h5ai -u https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing --debug ``` -**More info regarding app packaging:** https://yunohost.org/packaging_apps \ No newline at end of file +**More info regarding app packaging:** diff --git a/README_fr.md b/README_fr.md index 0eea75c..e03e6ab 100644 --- a/README_fr.md +++ b/README_fr.md @@ -1,25 +1,37 @@ + + # h5ai pour YunoHost -[![Niveau d'intégration](https://dash.yunohost.org/integration/h5ai.svg)](https://dash.yunohost.org/appci/app/h5ai) ![](https://ci-apps.yunohost.org/ci/badges/h5ai.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/h5ai.maintain.svg) +[![Niveau d'intégration](https://dash.yunohost.org/integration/h5ai.svg)](https://dash.yunohost.org/appci/app/h5ai) ![Statut du fonctionnement](https://ci-apps.yunohost.org/ci/badges/h5ai.status.svg) ![Statut de maintenance](https://ci-apps.yunohost.org/ci/badges/h5ai.maintain.svg) [![Installer h5ai avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=h5ai) *[Read this readme in english.](./README.md)* -*[Lire ce readme en français.](./README_fr.md)* > *Ce package vous permet d'installer h5ai rapidement et simplement sur un serveur YunoHost. Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* ## Vue d'ensemble -Serveur moderne d'index pour NGINX +h5ai is a modern file indexer for HTTP web servers with focus on your files. Directories are displayed in a appealing way and browsing them is enhanced by different views, a breadcrumb and a tree overview. + +### Features + +There are lots of optional extensions and configuration options to customize the web appearance of your directory listings. All markup is valid HTML5 spiced up with CSS3 and finest JavaScript to build a fresh but minimal user interface and a user experience that focuses on your files. + +Some of the optional features are: file sorting, different view modes, localization, a breadcrumb, a tree view, custom headers and footers, file filter and search, folder sizes, auto refresh, packaged download, QR codes, thumbnails, file previews + **Version incluse :** 0.30.0~ynh3 - +**Démo :** https://larsjung.de/h5ai/demo/ ## Captures d'écran -![](./doc/screenshots/screenshot.jpg) +![Capture d'écran de h5ai](./doc/screenshots/screenshot.jpg) +![Capture d'écran de h5ai](./doc/screenshots/h5ai-1024x540.png) ## Avertissements / informations importantes @@ -31,21 +43,22 @@ Le fichier de configuration principal est `_h5ai / private / conf / options.json ## Documentations et ressources -* Site officiel de l'app : https://larsjung.de/h5ai/ -* Documentation officielle de l'admin : https://larsjung.de/h5ai/ -* Dépôt de code officiel de l'app : https://github.com/lrsjng/h5ai -* Documentation YunoHost pour cette app : https://yunohost.org/app_h5ai -* Signaler un bug : https://github.com/YunoHost-Apps/h5ai_ynh/issues +* Site officiel de l'app : +* Documentation officielle de l'admin : +* Dépôt de code officiel de l'app : +* Documentation YunoHost pour cette app : +* Signaler un bug : ## Informations pour les développeurs Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing). Pour essayer la branche testing, procédez comme suit. -``` + +``` bash sudo yunohost app install https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing --debug ou sudo yunohost app upgrade h5ai -u https://github.com/YunoHost-Apps/h5ai_ynh/tree/testing --debug ``` -**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps \ No newline at end of file +**Plus d'infos sur le packaging d'applications :** From d47757837d4358be5917230e908c34b020497ff2 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Sun, 16 Oct 2022 18:30:09 +0000 Subject: [PATCH 19/26] Auto-update README --- README_fr.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README_fr.md b/README_fr.md index a8aed7d..8ccd7f7 100644 --- a/README_fr.md +++ b/README_fr.md @@ -23,6 +23,7 @@ Il y a beaucoup d'extensions optionnelles et d'options de configuration pour per Parmi les fonctionnalités optionnelles, citons : le tri des fichiers, différents modes d'affichage, la localisation, le fil d'Ariane, l'arborescence, les en-têtes et pieds de page personnalisés, le filtrage et la recherche de fichiers, la taille des dossiers, le rafraîchissement automatique, l'emballage... + **Version incluse :** 0.30.0~ynh3 **Démo :** https://larsjung.de/h5ai/demo/ From d69266d57431a77622cfc3e7ce23907c34dd67c4 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Sun, 16 Oct 2022 20:38:07 +0200 Subject: [PATCH 20/26] Fix script order --- conf/nginx.conf | 4 +--- conf/php-fpm.conf | 4 ++-- manifest.json | 2 +- scripts/_common.sh | 4 +++- scripts/install | 17 +++++++++-------- scripts/restore | 24 +++++++++++------------- scripts/upgrade | 16 ++++++++-------- 7 files changed, 35 insertions(+), 36 deletions(-) diff --git a/conf/nginx.conf b/conf/nginx.conf index c169ca5..c9fb7eb 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -4,11 +4,10 @@ location __PATH__/ { # Path to source alias __FINALPATH__/; -### Example PHP configuration (remove it if not used) index index.php __PATH__/_h5ai/public/index.php; # Common parameter to increase upload size limit in conjunction with dedicated php-fpm file - #client_max_body_size 50M; + client_max_body_size 500M; try_files $uri.html $uri $uri/ =404; @@ -24,7 +23,6 @@ location __PATH__/ { fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_FILENAME $request_filename; } -### End of PHP configuration part # Include SSOWAT user panel. include conf.d/yunohost_panel.conf.inc; diff --git a/conf/php-fpm.conf b/conf/php-fpm.conf index ab1a471..573704e 100644 --- a/conf/php-fpm.conf +++ b/conf/php-fpm.conf @@ -419,8 +419,8 @@ chdir = __FINALPATH__ ;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_value[upload_max_filesize] = 500M +php_admin_value[post_max_size] = 500M ; php_admin_flag[mail.add_x_header] = Off ; Other common parameters diff --git a/manifest.json b/manifest.json index 61f1449..fbe90f7 100644 --- a/manifest.json +++ b/manifest.json @@ -21,7 +21,7 @@ "email": "alex.aubin@mailoo.org" }, "requirements": { - "yunohost": ">= 4.3.0" + "yunohost": ">= 11.0.9" }, "multi_instance": true, "services": [ diff --git a/scripts/_common.sh b/scripts/_common.sh index 6fb7135..caa3c0c 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -7,7 +7,9 @@ YNH_PHP_VERSION=7.4 # dependencies used by the app -pkg_dependencies="php$YNH_PHP_VERSION-fpm ffmpeg imagemagick" +php_dependencies="php$YNH_PHP_VERSION-fpm" + +pkg_dependencies="ffmpeg imagemagick $php_dependencies" #================================================= # PERSONAL HELPERS diff --git a/scripts/install b/scripts/install index 5c2c8b7..fd9d729 100644 --- a/scripts/install +++ b/scripts/install @@ -82,14 +82,6 @@ chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Configuring NGINX web server..." --weight=1 - -# Create a dedicated NGINX config -ynh_add_nginx_config - #================================================= # PHP-FPM CONFIGURATION #================================================= @@ -97,6 +89,15 @@ ynh_script_progression --message="Configuring PHP-FPM..." --weight=1 # Create a dedicated PHP-FPM config ynh_add_fpm_config +phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) + +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Configuring NGINX web server..." --weight=1 + +# Create a dedicated NGINX config +ynh_add_nginx_config #================================================= # SETUP SSOWAT diff --git a/scripts/restore b/scripts/restore index 813cb0f..cfb077f 100644 --- a/scripts/restore +++ b/scripts/restore @@ -42,13 +42,6 @@ test ! -d $final_path \ #================================================= # STANDARD RESTORATION STEPS -#================================================= -# RESTORE THE NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Restoring the NGINX web server configuration..." --weight=1 - -ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" - #================================================= # RECREATE THE DEDICATED USER #================================================= @@ -68,6 +61,14 @@ chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" +#================================================= +# REINSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Reinstalling dependencies..." --weight=1 + +# Define and install dependencies +ynh_install_app_dependencies $pkg_dependencies + #================================================= # RESTORE THE PHP-FPM CONFIGURATION #================================================= @@ -76,14 +77,11 @@ ynh_script_progression --message="Restoring the PHP-FPM configuration..." --weig ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf" #================================================= -# SPECIFIC RESTORATION +# RESTORE THE NGINX CONFIGURATION #================================================= -# REINSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Reinstalling dependencies..." --weight=1 +ynh_script_progression --message="Restoring the NGINX web server configuration..." --weight=1 -# Define and install dependencies -ynh_install_app_dependencies $pkg_dependencies +ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= # GENERIC FINALIZATION diff --git a/scripts/upgrade b/scripts/upgrade index af7a987..b05af36 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -71,14 +71,6 @@ chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 - -# Create a dedicated NGINX config -ynh_add_nginx_config - #================================================= # UPGRADE DEPENDENCIES #================================================= @@ -94,6 +86,14 @@ ynh_script_progression --message="Upgrading PHP-FPM configuration..." --weight=1 # Create a dedicated PHP-FPM config ynh_add_fpm_config +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 + +# Create a dedicated NGINX config +ynh_add_nginx_config + #================================================= # RELOAD NGINX #================================================= From 798ca62f9dac1da026872d4fe639451fb3888492 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Sun, 16 Oct 2022 22:55:29 +0200 Subject: [PATCH 21/26] Fix --- scripts/backup | 1 + scripts/restore | 1 + 2 files changed, 2 insertions(+) diff --git a/scripts/backup b/scripts/backup index 8a882cb..aa7c492 100644 --- a/scripts/backup +++ b/scripts/backup @@ -30,6 +30,7 @@ app=$YNH_APP_INSTANCE_NAME final_path=$(ynh_app_setting_get --app=$app --key=final_path) domain=$(ynh_app_setting_get --app=$app --key=domain) +phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) #================================================= # DECLARE DATA AND CONF FILES TO BACKUP diff --git a/scripts/restore b/scripts/restore index cfb077f..24e81b0 100644 --- a/scripts/restore +++ b/scripts/restore @@ -31,6 +31,7 @@ app=$YNH_APP_INSTANCE_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) +phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) #================================================= # CHECK IF THE APP CAN BE RESTORED From 4f1cffb2339e4f5fcd1a450b7fa487c3c20e53b9 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Sun, 16 Oct 2022 22:56:37 +0200 Subject: [PATCH 22/26] Update check_process --- check_process | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check_process b/check_process index c587673..bdd94ae 100644 --- a/check_process +++ b/check_process @@ -13,7 +13,7 @@ upgrade=1 upgrade=1 from_commit=73f74039fb63adc555222d73ded6b43a64d41456 backup_restore=1 - multi_instance=0 + multi_instance=1 change_url=1 ;;; Upgrade options ; commit=73f74039fb63adc555222d73ded6b43a64d41456 From bb1cbb75eb29ea6865494fedf5a7450e4a45a93e Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Sun, 16 Oct 2022 22:58:05 +0200 Subject: [PATCH 23/26] Update check_process --- check_process | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/check_process b/check_process index bdd94ae..55648a7 100644 --- a/check_process +++ b/check_process @@ -11,11 +11,11 @@ setup_private=1 setup_public=1 upgrade=1 - upgrade=1 from_commit=73f74039fb63adc555222d73ded6b43a64d41456 + upgrade=1 from_commit=af190a49ec43b470a38b21d81887a1b457b333fa backup_restore=1 multi_instance=1 change_url=1 ;;; Upgrade options - ; commit=73f74039fb63adc555222d73ded6b43a64d41456 - name=Update check_process, 24 Jun 2019 + ; commit=af190a49ec43b470a38b21d81887a1b457b333fa + name=Merge pull request #11 manifest_arg=domain=DOMAIN&path=PATH&admin=USER&language=fr&is_public=1&password=pass&port=666& From af46cf6019f38b279cd83e2e2eab71fefa330c39 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Mon, 17 Oct 2022 01:52:08 +0200 Subject: [PATCH 24/26] Update restore --- scripts/restore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/restore b/scripts/restore index 15ce2cf..4a79d7e 100644 --- a/scripts/restore +++ b/scripts/restore @@ -55,7 +55,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" #================================================= ynh_script_progression --message="Restoring the app main directory..." --weight=4 -ynh_restore_file --origin_path="$final_path" +ynh_restore_file --origin_path="$final_path" --not_mandatory chmod 750 "$final_path" chmod -R o-rwx "$final_path" From d0817776f02e92086c816fd2421b97f349f619de Mon Sep 17 00:00:00 2001 From: yalh76 Date: Tue, 18 Oct 2022 01:30:43 +0200 Subject: [PATCH 25/26] Fix restore --- scripts/restore | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/restore b/scripts/restore index 4a79d7e..12f37be 100644 --- a/scripts/restore +++ b/scripts/restore @@ -37,9 +37,6 @@ phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) #================================================= ynh_script_progression --message="Validating restoration parameters..." --weight=1 -test ! -d $final_path \ - || ynh_die --message="There is already a directory: $final_path " - #================================================= # STANDARD RESTORATION STEPS #================================================= From c54c8f27d773241b3cfe1d79f3edd47792080479 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Tue, 18 Oct 2022 01:41:49 +0200 Subject: [PATCH 26/26] Implement auto-updater --- .github/workflows/updater.sh | 108 ++++++++++++++++++++++++++++++++++ .github/workflows/updater.yml | 49 +++++++++++++++ conf/app.src | 2 +- manifest.json | 2 +- 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/updater.sh create mode 100644 .github/workflows/updater.yml diff --git a/.github/workflows/updater.sh b/.github/workflows/updater.sh new file mode 100644 index 0000000..751c7f0 --- /dev/null +++ b/.github/workflows/updater.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +#================================================= +# PACKAGE UPDATING HELPER +#================================================= + +# This script is meant to be run by GitHub Actions +# The YunoHost-Apps organisation offers a template Action to run this script periodically +# Since each app is different, maintainers can adapt its contents so as to perform +# automatic actions when a new upstream release is detected. + +#================================================= +# FETCHING LATEST RELEASE AND ITS ASSETS +#================================================= + +# Fetching information +current_version=$(cat manifest.json | jq -j '.version|split("~")[0]') +repo=$(cat manifest.json | jq -j '.upstream.code|split("https://github.com/")[1]') +# Some jq magic is needed, because the latest upstream release is not always the latest version (e.g. security patches for older versions) +version=$(curl --silent "https://api.github.com/repos/$repo/tags" | jq -r '.[] | select( .prerelease != true ) | .name' | sort -V | tail -1) + +# Later down the script, we assume the version has only digits and dots +# Sometimes the release name starts with a "v", so let's filter it out. +# You may need more tweaks here if the upstream repository has different naming conventions. +if [[ ${version:0:1} == "v" || ${version:0:1} == "V" ]]; then + version=${version:1} +fi + +assets="https://release.larsjung.de/h5ai/h5ai-$version.zip" + +# Setting up the environment variables +echo "Current version: $current_version" +echo "Latest release from upstream: $version" +echo "VERSION=$version" >> $GITHUB_ENV +echo "REPO=$repo" >> $GITHUB_ENV +# For the time being, let's assume the script will fail +echo "PROCEED=false" >> $GITHUB_ENV + +# Proceed only if the retrieved version is greater than the current one +if ! dpkg --compare-versions "$current_version" "lt" "$version" ; then + echo "::warning ::No new version available" + exit 0 +# Proceed only if a PR for this new version does not already exist +elif git ls-remote -q --exit-code --heads https://github.com/$GITHUB_REPOSITORY.git ci-auto-update-v$version ; then + echo "::warning ::A branch already exists for this update" + exit 0 +fi + +#================================================= +# UPDATE SOURCE FILES +#================================================= + +# Let's download source tarball +asset_url=$assets + +echo "Handling asset at $asset_url" + +src="app" + +# Create the temporary directory +tempdir="$(mktemp -d)" + +# Download sources and calculate checksum +filename=${asset_url##*/} +curl --silent -4 -L $asset_url -o "$tempdir/$filename" +checksum=$(sha256sum "$tempdir/$filename" | head -c 64) + +# Delete temporary directory +rm -rf $tempdir + +# Get extension +if [[ $filename == *.tar.gz ]]; then + extension=tar.gz +else + extension=${filename##*.} +fi + +# Rewrite source file +cat < conf/$src.src +SOURCE_URL=$asset_url +SOURCE_SUM=$checksum +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=$extension +SOURCE_IN_SUBDIR=false +SOURCE_FILENAME= +SOURCE_EXTRACT=true +EOT +echo "... conf/$src.src updated" + +#================================================= +# SPECIFIC UPDATE STEPS +#================================================= + +# Any action on the app's source code can be done. +# The GitHub Action workflow takes care of committing all changes after this script ends. + +#================================================= +# GENERIC FINALIZATION +#================================================= + +# Replace new version in manifest +echo "$(jq -s --indent 4 ".[] | .version = \"$version~ynh1\"" manifest.json)" > manifest.json + +# No need to update the README, yunohost-bot takes care of it + +# The Action will proceed only if the PROCEED environment variable is set to true +echo "PROCEED=true" >> $GITHUB_ENV +exit 0 diff --git a/.github/workflows/updater.yml b/.github/workflows/updater.yml new file mode 100644 index 0000000..fb72ba0 --- /dev/null +++ b/.github/workflows/updater.yml @@ -0,0 +1,49 @@ +# This workflow allows GitHub Actions to automagically update your app whenever a new upstream release is detected. +# You need to enable Actions in your repository settings, and fetch this Action from the YunoHost-Apps organization. +# This file should be enough by itself, but feel free to tune it to your needs. +# It calls updater.sh, which is where you should put the app-specific update steps. +name: Check for new upstream releases +on: + # Allow to manually trigger the workflow + workflow_dispatch: + # Run it every day at 6:00 UTC + schedule: + - cron: '0 6 * * *' +jobs: + updater: + runs-on: ubuntu-latest + steps: + - name: Fetch the source code + uses: actions/checkout@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: Run the updater script + id: run_updater + run: | + # Setting up Git user + git config --global user.name 'yunohost-bot' + git config --global user.email 'yunohost-bot@users.noreply.github.com' + # Run the updater script + /bin/bash .github/workflows/updater.sh + - name: Commit changes + id: commit + if: ${{ env.PROCEED == 'true' }} + run: | + git commit -am "Upgrade to v$VERSION" + - name: Create Pull Request + id: cpr + if: ${{ env.PROCEED == 'true' }} + uses: peter-evans/create-pull-request@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: Update to version ${{ env.VERSION }} + committer: 'yunohost-bot ' + author: 'yunohost-bot ' + signoff: false + base: testing + branch: ci-auto-update-v${{ env.VERSION }} + delete-branch: true + title: 'Upgrade to version ${{ env.VERSION }}' + body: | + Upgrade to v${{ env.VERSION }} + draft: false diff --git a/conf/app.src b/conf/app.src index 46c7310..d99b84c 100644 --- a/conf/app.src +++ b/conf/app.src @@ -3,5 +3,5 @@ SOURCE_SUM=fe138305a61d72094beb8c507dab728020158e4b00dae695a60b9803babb3e30 SOURCE_SUM_PRG=sha256sum SOURCE_FORMAT=zip SOURCE_IN_SUBDIR=false -SOURCE_FILENAME=h5ai.zip +SOURCE_FILENAME= SOURCE_EXTRACT=true diff --git a/manifest.json b/manifest.json index a0881a4..1bce46f 100644 --- a/manifest.json +++ b/manifest.json @@ -29,7 +29,7 @@ "php7.4-fpm" ], "arguments": { - "install" : [ + "install": [ { "name": "domain", "type": "domain"