diff --git a/conf/app.src b/conf/app.src new file mode 100644 index 0000000..452772c --- /dev/null +++ b/conf/app.src @@ -0,0 +1,2 @@ +SOURCE_URL=https://download.prestashop.com/download/releases/prestashop_1.7.0.5.zip +SOURCE_SUM=a48191b3e46965548687535372bcc1df \ No newline at end of file diff --git a/conf/nginx.conf b/conf/nginx.conf index 82606d7..9d9181b 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,21 +1,51 @@ +#--MULTISITE--if (!-e $request_filename) { + #--MULTISITE--rewrite /ecrire$ $scheme://$host$uri/ permanent; + #--MULTISITE--rewrite ^__PATHTOCHANGE__(/[^/]+)?(/.*\.php)$ __PATHTOCHANGE__$2 last; +#--MULTISITE--} -location YNH_WWW_PATH { - alias YNH_WWW_ALIASwww/ ; - if ($scheme = http) { - rewrite ^ https://$server_name$request_uri? permanent; - } - index index.php; - try_files $uri $uri/ index.php; - location ~ [^/]\.php(/|$) { - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - fastcgi_pass unix:/var/run/php5-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; - } +location __PATHTOCHANGE__ { + alias __FINALPATH__/; + index index.php; - # Include SSOWAT user panel. - include conf.d/yunohost_panel.conf.inc; + if (!-e $request_filename) + { + rewrite ^(.+)$ __PATHTOCHANGE__/index.php?q=$1 last; + } + if ($scheme = http) { + rewrite ^ https://$server_name$request_uri? permanent; + } + client_max_body_size 30m; + + # Add headers to serve security related headers + add_header Strict-Transport-Security "max-age=15768000;"; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag none; + add_header X-Download-Options noopen; + add_header X-Permitted-Cross-Domain-Policies none; + + location ~^/(\.ht)/{ + deny all; + } + location ~* \.(jpg|jpeg|gif|css|png|js|ico|swf|mp3|pdf)$ { + # Le contenu statique, est signalé au navigateur comme étant + # à garder en cache une semaine. Si il y a un proxy sur la + # route, celui-ci est autorisé à faire une copie et à la + # cacher. + expires 1w; + add_header Cache-Control public; + } + location ~ [^/]\.php(/|$) { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + fastcgi_pass unix:/var/run/php5-fpm-__NAMETOCHANGE__.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; + } + + #--PRIVATE--# Include SSOWAT user panel. + #--PRIVATE--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..5672f10 --- /dev/null +++ b/conf/php-fpm.conf @@ -0,0 +1,392 @@ +; Start a new pool named 'www'. +; the variable $pool can we 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: +; - '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 = www-data +group = www-data + +; The address on which to accept FastCGI requests. +; Valid syntaxes are: +; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on +; a specific port; +; 'port' - to listen on a TCP socket to all addresses on a +; specific port; +; '/path/to/unix/socket' - to listen on a unix socket. +; Note: This value is mandatory. +listen = /var/run/php5-fpm-__NAMETOCHANGE__.sock + +; Set listen(2) backlog. +; Default Value: 128 (-1 on FreeBSD and OpenBSD) +;listen.backlog = 128 + +; 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 + +; List of ipv4 addresses 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 +; priority = -19 + +; 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 = 10 + +; 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: ${prefix}/share/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: ouput 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) +; %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) +; %u: remote user +; +; Default: "%R - %u %t \"%m %r\" %s" +;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" + +; The log file for slow requests +; Default Value: not set +; Note: slowlog is mandatory if request_slowlog_timeout is set +slowlog = /var/log/nginx/__NAMETOCHANGE__.slow.log + +; The timeout for serving a single request after which a PHP backtrace will be +; dumped to the 'slowlog' file. A value of '0s' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +request_slowlog_timeout = 5s + +; 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 + +; Limits the extensions of the main script FPM will allow to parse. This can +; prevent configuration mistakes on the web server side. You should only limit +; FPM to .php extensions to prevent malicious users to use other extensions to +; exectute php code. +; Note: set an empty value to allow all extensions. +; Default Value: .php +;security.limit_extensions = .php .php3 .php4 .php5 + +; 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 \ No newline at end of file diff --git a/conf/php-fpm.ini b/conf/php-fpm.ini new file mode 100644 index 0000000..55e2ba7 --- /dev/null +++ b/conf/php-fpm.ini @@ -0,0 +1,3 @@ +upload_max_filesize=30M +post_max_size=30M +; max_execution_time=60 \ No newline at end of file diff --git a/manifest.json b/manifest.json index a5fa691..df897c6 100644 --- a/manifest.json +++ b/manifest.json @@ -2,22 +2,25 @@ "name": "Prestashop", "id": "prestashop", "packaging_format": 1, - "requirements": { - "yunohost": ">> 2.3.15" - }, "description": { "en": "Create a E-commerce Website", "fr": "Créer un site ecommerce" }, - "url": "prestashop.com", + "version": "1.1.3", + "url": "https://www.prestashop.com/", + "license": "free", "maintainer": { "name": "frju365", "email": "win10@tutanota.com" }, - "multi_instance": "true", + "requirements": { + "yunohost": ">> 2.4.0" + }, + "multi_instance": true, "services": [ "nginx", - "php5-fpm" + "php5-fpm", + "mysql" ], "arguments": { "install" : [ @@ -25,38 +28,56 @@ "name": "domain", "type": "domain", "ask": { - "en": "Choose a domain for Prestashop", - "fr": "Choisissez un domaine pour Prestashop" + "en": "Choose a domain name for SPIP", + "fr": "Choisissez un nom de domaine pour SPIP" }, - "example": "domain.org" + "example": "example.org" }, { "name": "path", "type": "path", "ask": { - "en": "Choose a path for Prestashop", - "fr": "Choisissez un chemin pour Prestashop" + "en": "Choose a path for SPIP", + "fr": "Choisissez un chemin pour SPIP" }, "example": "/prestashop", "default": "/prestashop" }, + { + "name": "admin", + "type": "user", + "ask": { + "en": "Choose the SPIP administrator (must be an existing YunoHost user)", + "fr": "Administrateur du site (doit être un utilisateur YunoHost existant)" + }, + "example": "johndoe" + }, { "name": "is_public", "ask": { - "en": "Is it a public Prestashop site ?", + "en": "Is it a public SPIP site ?", "fr": "Est-ce un site public ?" }, "choices": ["Yes", "No"], "default": "Yes" }, { - "name": "user", - "type": "user", + "name": "multisite", "ask": { - "en": "Choose the Abantecart administrator (must be an existing YunoHost user)", - "fr": "Choisissez l'administrateur de Abantecart (doit être un utilisateur YunoHost existant)" + "en": "Enable multisite option ?", + "fr": "Activer l'option multisite ?" }, - "example": "homer" + "choices": ["Yes", "No"], + "default": "No" + }, + { + "name": "language", + "ask": { + "en": "Choose the application language", + "fr": "Choisissez la langue de l'application" + }, + "choices": ["en_EN", "fr_FR"], + "default": "fr_FR" }, { "name": "passwd", @@ -77,4 +98,4 @@ } ] } -} +} \ No newline at end of file diff --git a/scripts/.fonctions b/scripts/.fonctions index 59c260b..dde0842 100644 --- a/scripts/.fonctions +++ b/scripts/.fonctions @@ -1,11 +1,50 @@ #!/bin/bash +ynh_version="2.4" + +YNH_VERSION () { # Renvoi le numéro de version de la moulinette Yunohost + ynh_version=$(sudo yunohost -v | grep "moulinette:" | cut -d' ' -f2 | cut -d'.' -f1,2) +} + CHECK_VAR () { # Vérifie que la variable n'est pas vide. # $1 = Variable à vérifier # $2 = Texte à afficher en cas d'erreur test -n "$1" || (echo "$2" >&2 && false) } +EXIT_PROPERLY () { # Provoque l'arrêt du script en cas d'erreur. Et nettoye les résidus. + trap '' ERR + echo -e "\e[91m \e[1m" # Shell in light red bold + echo -e "!!\n $app install's script has encountered an error. Installation was cancelled.\n!!" >&2 + + CLEAN_SETUP # Appel la fonction de nettoyage spécifique du script install. + + # Compense le bug de ssowat qui ne supprime pas l'entrée de l'app en cas d'erreur d'installation. + sudo sed -i "\@\"$domain$path/\":@d" /etc/ssowat/conf.json + + if [ "$ynh_version" = "2.2" ]; then + /bin/bash $script_dir/remove # Appel le script remove. En 2.2, ce comportement n'est pas automatique. + fi + + ynh_die +} + +TRAP_ON () { # Activate signal capture + trap EXIT_PROPERLY ERR # Capturing exit signals on error +} + +TRAP_OFF () { # Ignoring signal capture until TRAP_ON + # Pour une raison que j'ignore, la fonction TRAP_ON fonctionne très bien. + # Mais pas la fonction TRAP_OFF... + # Utiliser directement `trap '' ERR` dans le code pour l'utiliser, à la place de la fonction. + trap '' ERR # Ignoring exit signals +} + +CHECK_USER () { # Vérifie la validité de l'user admin +# $1 = Variable de l'user admin. + ynh_user_exists "$1" || (echo "Wrong admin" >&2 && false) +} + CHECK_PATH () { # Vérifie la présence du / en début de path. Et son absence à la fin. if [ "${path:0:1}" != "/" ]; then # Si le premier caractère n'est pas un / path="/$path" # Ajoute un / en début de path @@ -27,3 +66,183 @@ CHECK_FINALPATH () { # Vérifie que le dossier de destination n'est pas déjà u false fi } + +GENERATE_DB () { # Créer une base de données et un utilisateur dédié au nom de l'app. +# $1 = Nom de la base de donnée + # Génère un mot de passe aléatoire. + db_user=$1 + db_pwd=$(head -n20 /dev/urandom | tr -c -d 'A-Za-z0-9' | head -c20) + CHECK_VAR "$db_pwd" "db_pwd empty" + # Utilise '$app' comme nom d'utilisateur et de base de donnée + # Initialise la base de donnée et stocke le mot de passe mysql. + ynh_mysql_create_db "$db_user" "$db_user" $db_pwd + ynh_app_setting_set $app mysqlpwd $db_pwd +} + +SETUP_SOURCE () { # Télécharge la source, décompresse et copie dans $final_path +# $1 = Nom de l'archive téléchargée. + wget -nv --show-progress -i ../sources/source_url -O $1 + # Vérifie la somme de contrôle de la source téléchargée. + md5sum -c ../sources/source_md5 --status + sudo unzip -q $1 -d $final_path +} + +EXTRACT_SOURCE() { + local DESTDIR=$1 + + # retrieve and extract Prestashop Zip File + rc_tarball="${DESTDIR}/prestashop.zip" + sudo wget -q -O "$rc_tarball" "$PRESTASHOP_SOURCE_URL" \ + || ynh_die "Unable to download source tarball" + sudo unzip "$rc_tarball" "$DESTDIR" \ + || ynh_die "Unable to extract source tarball" + sudo rm "$rc_tarball" +} + +POOL_FPM () { # Créer le fichier de configuration du pool php-fpm et le configure. + sed -i "s@__NAMETOCHANGE__@$app@g" ../conf/php-fpm.conf + sed -i "s@__FINALPATH__@$final_path@g" ../conf/php-fpm.conf + finalphpconf=/etc/php5/fpm/pool.d/$app.conf + sudo cp ../conf/php-fpm.conf $finalphpconf + sudo chown root: $finalphpconf + finalphpini=/etc/php5/fpm/conf.d/20-$app.ini + sudo cp ../conf/php-fpm.ini $finalphpini + sudo chown root: $finalphpini + sudo service php5-fpm reload +} + +STORE_MD5_CONFIG () { # Enregistre la somme de contrôle du fichier de config +# $1 = Nom du fichier de conf pour le stockage dans settings.yml +# $2 = Nom complet et chemin du fichier de conf. + ynh_app_setting_set $app $1_file_md5 $(sudo md5sum "$2" | cut -d' ' -f1) +} + +CHECK_MD5_CONFIG () { # Créé un backup du fichier de config si il a été modifié. +# $1 = Nom du fichier de conf pour le stockage dans settings.yml +# $2 = Nom complet et chemin du fichier de conf. + if [ "$(ynh_app_setting_get $app $1_file_md5)" != $(sudo md5sum "$2" | cut -d' ' -f1) ]; then + sudo cp -a "$2" "$2.backup.$(date '+%d.%m.%y_%Hh%M,%Ss')" # Si le fichier de config a été modifié, créer un backup. + fi +} + +FIND_PORT () { # Cherche un port libre. +# $1 = Numéro de port pour débuter la recherche. + port=$1 + while ! sudo yunohost app checkport $port ; do + port=$((port+1)) + done + CHECK_VAR "$port" "port empty" +} + +# Manage a fail of the script +# +# Print a warning to inform that the script was failed +# Execute the ynh_clean_setup function if used in the app script +# +# usage of ynh_clean_setup function +# This function provide a way to clean some residual of installation that not managed by remove script. +# To use it, simply add in your script: +# ynh_clean_setup () { +# instructions... +# } +# This function is optionnal. +# +# Usage: ynh_exit_properly is used only by the helper ynh_check_error. +# You must not use it directly. +ynh_exit_properly () { + exit_code=$? + if [ "$exit_code" -eq 0 ]; then + exit 0 # Exit without error if the script ended correctly + fi + + trap '' EXIT # Ignore new exit signals + set +eu # Do not exit anymore if a command fail or if a variable is empty + + echo -e "!!\n $app's script has encountered an error. Its execution was cancelled.\n!!" >&2 + + if type -t ynh_clean_setup > /dev/null; then # Check if the function exist in the app script. + ynh_clean_setup # Call the function to do specific cleaning for the app. + fi + + ynh_die # Exit with error status +} + +# Exit if an error occurs during the execution of the script. +# +# Stop immediatly the execution if an error occured or if a empty variable is used. +# The execution of the script is derivate to ynh_exit_properly function before exit. +# +# Usage: ynh_check_error +ynh_check_error () { + set -eu # Exit if a command fail, and if a variable is used unset. + trap ynh_exit_properly EXIT # Capturing exit signals on shell script +} + + +### REMOVE SCRIPT + +REMOVE_NGINX_CONF () { # Suppression de la configuration nginx + if [ -e "/etc/nginx/conf.d/$domain.d/$app.conf" ]; then # Delete nginx config + echo "Delete nginx config" + sudo rm "/etc/nginx/conf.d/$domain.d/$app.conf" + sudo service nginx reload + fi +} + +REMOVE_FPM_CONF () { # Suppression de la configuration du pool php-fpm + if [ -e "/etc/php5/fpm/pool.d/$app.conf" ]; then # Delete fpm config + echo "Delete fpm config" + sudo rm "/etc/php5/fpm/pool.d/$app.conf" + fi + if [ -e "/etc/php5/fpm/conf.d/20-$app.ini" ]; then # Delete php config + echo "Delete php config" + sudo rm "/etc/php5/fpm/conf.d/20-$app.ini" + fi + sudo service php5-fpm reload +} + +REMOVE_LOGROTATE_CONF () { # Suppression de la configuration de logrotate + if [ -e "/etc/logrotate.d/$app" ]; then + echo "Delete logrotate config" + sudo rm "/etc/logrotate.d/$app" + fi +} + +SECURE_REMOVE () { # Suppression de dossier avec vérification des variables + chaine="$1" # L'argument doit être donné entre quotes simple '', pour éviter d'interpréter les variables. + no_var=0 + while (echo "$chaine" | grep -q '\$') # Boucle tant qu'il y a des $ dans la chaine + do + no_var=1 + global_var=$(echo "$chaine" | cut -d '$' -f 2) # Isole la première variable trouvée. + only_var=\$$(expr "$global_var" : '\([A-Za-z0-9_]*\)') # Isole complètement la variable en ajoutant le $ au début et en gardant uniquement le nom de la variable. Se débarrasse surtout du / et d'un éventuel chemin derrière. + real_var=$(eval "echo ${only_var}") # `eval "echo ${var}` permet d'interpréter une variable contenue dans une variable. + if test -z "$real_var" || [ "$real_var" = "/" ]; then + echo "Variable $only_var is empty, suppression of $chaine cancelled." >&2 + return 1 + fi + chaine=$(echo "$chaine" | sed "s@$only_var@$real_var@") # remplace la variable par sa valeur dans la chaine. + done + if [ "$no_var" -eq 1 ] + then + if [ -e "$chaine" ]; then + echo "Delete directory $chaine" + sudo rm -r "$chaine" + fi + return 0 + else + echo "No detected variable." >&2 + return 1 + fi +} + +REMOVE_BDD () { # Suppression de la base de donnée et de l'utilisateur associé. +# $1 = Nom de la base de donnée + # Utilise '$app' comme nom d'utilisateur et de base de donnée + db_user=$1 + if mysqlshow -u root -p$(sudo cat $MYSQL_ROOT_PWD_FILE) | grep -q "^| $db_user"; then + echo "Delete db" + ynh_mysql_drop_db $db_user + ynh_mysql_drop_user $db_user + fi +} \ No newline at end of file diff --git a/scripts/_common b/scripts/_common index 501506e..98f55fd 100644 --- a/scripts/_common +++ b/scripts/_common @@ -1,13 +1 @@ -PRESTASHOP_SOURCE_URL="https://download.prestashop.com/download/releases/prestashop_1.7.0.5.zip" - -extract_source() { - local DESTDIR=$1 - - # retrieve and extract Prestashop Zip File - rc_tarball="${DESTDIR}/prestashop.zip" - sudo wget -q -O "$rc_tarball" "$PRESTASHOP_SOURCE_URL" \ - || ynh_die "Unable to download source tarball" - sudo unzip "$rc_tarball" "$DESTDIR" \ - || ynh_die "Unable to extract source tarball" - sudo rm "$rc_tarball" -} +PRESTASHOP_SOURCE_URL="https://download.prestashop.com/download/releases/prestashop_1.7.0.5.zip" \ No newline at end of file diff --git a/scripts/backup b/scripts/backup new file mode 100644 index 0000000..58a7016 --- /dev/null +++ b/scripts/backup @@ -0,0 +1,32 @@ +#!/bin/bash + +# Exit on command errors and treat unset variables as an error +set -eu + +# The parameter $1 is the backup directory location dedicated to the app +backup_dir=$1 + +# The parameter $2 is theid of the app instance +app=$2 + +# Source app helpers +source /usr/share/yunohost/helpers + +domain=$(ynh_app_setting_get $app domain) +final_path=$(ynh_app_setting_get $app final_path) + +# Copy the app files +sudo mkdir -p ${backup_dir}/var/www +sudo cp -a $final_path "${backup_dir}/var/www/$app" + +# Copy the conf files +sudo mkdir -p "${backup_dir}/conf" +sudo cp -a /etc/nginx/conf.d/$domain.d/$app.conf "${backup_dir}/conf/nginx.conf" + +# Copy dedicated php-fpm process to backup folder +sudo cp -a /etc/php5/fpm/pool.d/$app.conf "${backup_dir}/conf/php-fpm.conf" +sudo cp -a /etc/php5/fpm/conf.d/20-$app.ini "${backup_dir}/conf/php-fpm.ini" + +# Backup db +root_pwd=$(sudo cat /etc/yunohost/mysql) +sudo su -c "mysqldump -u root -p$root_pwd --no-create-db $app > ${backup_dir}/db.sql" diff --git a/scripts/install b/scripts/install index 52991d6..1980797 100644 --- a/scripts/install +++ b/scripts/install @@ -1,125 +1,157 @@ #!/bin/bash -source /usr/share/yunohost/helpers -source ./_common -source .fonctions -set -eu +#================================================= +# GENERIC STARTING +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source .fonctions +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE FAILURE OF THE SCRIPT +#================================================= + +ynh_check_error # Active trap pour arrêter le script si une erreur est détectée. + +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= + +domain=$YNH_APP_ARG_DOMAIN +path=$YNH_APP_ARG_PATH +admin_prestashop=$YNH_APP_ARG_ADMIN +language=$YNH_APP_ARG_LANGUAGE +#multisite=$YNH_APP_ARG_MULTISITE +is_public=$YNH_APP_ARG_IS_PUBLIC +db_pwd=$YNH_APP_ARG_PASSWD +email=$YNH_APP_ARG_EMAIL -# Retrieve app id app=$YNH_APP_INSTANCE_NAME -# Retrieve arguments -domain=$1 -path=$2 -is_public=$3 -user=$4 -passwd=$5 -email=$6 +#================================================= +# CHECK IF THE APP CAN BE INSTALLED WITH THIS ARGS +#================================================= -script_dir=$PWD - -# Vérifie que les variables ne sont pas vides. CHECK_VAR "$app" "app name not set" -CHECK_VAR "$script_dir" "script_dir not set" +CHECK_USER "$admin_prestashop" +CHECK_PATH +CHECK_DOMAINPATH +CHECK_FINALPATH -CHECK_PATH # Vérifie et corrige la syntaxe du path. -CHECK_DOMAINPATH # Vérifie la disponibilité du path et du domaine. +#================================================= +# STORE SETTINGS FROM MANIFEST +#================================================= -CHECK_FINALPATH # Vérifie que le dossier de destination n'est pas déjà utilisé. +ynh_app_setting_set $app domain $domain +ynh_app_setting_set $app path $path +ynh_app_setting_set $app admin $admin_prestashop +ynh_app_setting_set $app is_public $is_public +ynh_app_setting_set $app language $language +ynh_app_setting_set $app db_pwd $db_pwd +ynh_app_setting_set $app email $email +#ynh_app_setting_set $app multisite $multisite -# Install dependency to convert tracks to a readable format for the browser -sudo apt-get update -sudo apt-get -y -qq install php5-mysql +#================================================= +# CREATE A SQL BDD +#================================================= -# Check password strength -[[ ${#passwd} -gt 5 ]] || ynh_die \ -"The password is too weak, it must be longer than 5 characters" +db_name=$app +db_user=$app +db_pwd=$(ynh_string_random) +ynh_mysql_create_db "$db_name" "$db_user" "$db_pwd" +ynh_app_setting_set "$app" db_name "$db_name" +ynh_app_setting_set "$app" db_pwd "$db_pwd" +ynh_app_setting_set "$app" db_user "$db_user" -# Save app settings -user="$app" -ynh_app_setting_set "$app" is_public "$is_public" -ynh_app_setting_set "$app" password "$passwd" -ynh_app_setting_set "$app" user "$user" +#================================================= +# Crée le repertoire de destination et check les permissions +#================================================= +sudo mkdir "$final_path" +sudo chown -R www-data: $final_path -# Initialize database as needed +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= -dbname=$app -dbuser=$app -dbpass=$(ynh_string_random) -ynh_mysql_create_db "$dbname" "$dbuser" "$dbpass" +ynh_app_setting_set $app final_path $final_path +SETUP_SOURCE "prestashop_1.7.0.5.zip" # Télécharge la source, décompresse et copie dans $final_path -# Store the database access -echo -e "# MySQL Database" +#================================================= +# Set /etc/hosts +#================================================= + +echo -e "127.0.0.1 $domain #PRESTASHOP" | sudo tee -a /etc/hosts -# Remove trailing "/" for next commands -if [[ ! "$path" == "/" ]]; then - path=${path%/} -fi +#================================================= +# NGINX CONFIGURATION +#================================================= -# Copy files to the right place -final_path=/var/www/$app -extract_source -SUDO unzip $final_path/prestashop.zip $final_path/prestashop -sudo mv $final_path/prestashop/* $final_path/ -sudo rm -rf $final_path/prestashop +sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf +sudo sed -i "s@__PATHTOCHANGE__@$path@g" /etc/nginx/conf.d/$domain.d/$app.conf +sudo sed -i "s@__FINALPATH__@$final_path@g" /etc/nginx/conf.d/$domain.d/$app.conf +sudo sed -i "s@__NAMETOCHANGE__@$app@g" /etc/nginx/conf.d/$domain.d/$app.conf -pushd $final_path/install/ -sudo php index_cli.php install \ - --db_server=localhost \ - --db_user=$dbuser \ - --db_password=$dbpass \ - --db_name=$dbname \ - --db_driver=amysqli \ - --db_port=3306 \ - --lastname=$user \ - --password=$passwd \ - --email=$email \ - --domain=$domain$path \ - --prefix=_ps_ - -popd - -# file owned by www-data before checking permissions -sudo chown www-data:www-data $final_path -R +#================================================= +# SETUP SSOWAT +#================================================= -# Files owned by root, www-data can just read -sudo chmod 0775 $final_path/config/ -R -sudo chmod 0775 $final_path/cache/ -R -sudo chmod 0775 $final_path/mails/ -R -sudo chmod 0775 $final_path/log/ -R -sudo chmod 0775 $final_path/img/ -R -sudo chmod 0775 $final_path/modules/ -R -sudo chmod 0775 $final_path/override/ -R -sudo chmod 0775 $final_path/themes/default/lang/ -R -sudo chmod 0775 $final_path/themes/default/pdf/lang/ -R -sudo chmod 0775 $final_path/themes/default/cache/ -R -sudo chmod 0775 $final_path/translations/ -R -sudo chmod 0775 $final_path/upload/ -R -sudo chmod 0775 $final_path/download/ -R -sudo chmod 0775 $final_path/extensions/ -R -sudo chmod 0775 $final_path/resources/ -R -sudo chmod 0775 $final_path/sitemap.xml - -# set database configuration -sed -i "s@YNH_WWW_PATH@$path@g" ../conf/nginx.conf - -# Modify Nginx configuration file and copy it to Nginx conf directory -sed -i "s@YNH_WWW_PATH@$path@g" ../conf/nginx.conf -sed -i "s@YNH_WWW_ALIAS@$final_path/@g" ../conf/nginx.conf -nginxconf=/etc/nginx/conf.d/$domain.d/$app.conf -sudo cp ../conf/nginx.conf $nginxconf -sudo chown root: $nginxconf -sudo chmod 600 $nginxconf - -sudo yunohost app setting $app is_public -v "$is_public" if [ "$is_public" = "Yes" ]; then - sudo yunohost app setting $app unprotected_uris -v "/" + sudo sed -i "s@#--PRIVATE--@@g" /etc/nginx/conf.d/$domain.d/$app.conf fi -sudo rm -rf /var/www/$app/install/ +#================================================= +# PHP-FPM CONFIGURATION +#================================================= + +POOL_FPM + +#================================================= +# Option de l'applications +#================================================= + +db_md5=$(echo $db_pwd | md5sum | awk '{print $1}') +db_sha=$(echo $db_pwd | openssl dgst -sha1 -hmac "key" | awk -F'= ' {'print $2'}) +language="$(echo $language | head -c 2)" + +#================================================= +# Changer les informations de la tables +#================================================= + +# Charger la structure des tables dans la base. +# mysql --debug-check -u $db_user -p$db_pwd $db_user < ../conf/sql/prestashop.sql + +#================================================= +# Donne un accès public pour curl +#================================================= + +ynh_app_setting_set $app unprotected_uris "/" + +#================================================= +# Régénère la configuration de SSOwat +#================================================= -sudo service nginx reload sudo yunohost app ssowatconf + +#================================================= +# Reload Nginx and regenerate SSOwat conf +#================================================= +sudo service php5-fpm restart +sudo service nginx reload + +if [ "$is_public" = "No" ]; +then + # Retire l'accès public + ynh_app_setting_delete $app unprotected_uris + sudo yunohost app ssowatconf +fi + +#================================================= +# Nettoyer hosts +#================================================= + +sudo sed -i '/#PRESTASHOP/d' /etc/hosts \ No newline at end of file diff --git a/scripts/remove b/scripts/remove index 206ca5f..51e35a6 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,13 +1,26 @@ #!/bin/bash -app=$YNH_APP_INSTANCE_NAME +# Exit on command errors and treat unset variables as an error set -u + +source .fonctions # Charge les fonctions génériques habituellement utilisées dans le script + # Source app helpers source /usr/share/yunohost/helpers +# Récupère les infos de l'application. +app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get $app domain) -sudo rm -rf /var/www/$app -sudo rm -f /etc/nginx/conf.d/$domain.d/$app.conf +REMOVE_BDD $app # Suppression de la base de donnée et de l'utilisateur associé. -sudo service nginx reload +SECURE_REMOVE '/var/www/$app' # Suppression du dossier de l'application + +REMOVE_NGINX_CONF # Suppression de la configuration nginx + +REMOVE_FPM_CONF # Suppression de la configuration du pool php-fpm + +# Régénère la configuration de SSOwat +sudo yunohost app ssowatconf + +echo -e "\e[0m" # Restore normal color \ No newline at end of file diff --git a/scripts/restore b/scripts/restore new file mode 100644 index 0000000..4d225e0 --- /dev/null +++ b/scripts/restore @@ -0,0 +1,63 @@ +#!/bin/bash +# This restore script is adapted to Yunohost >=2.4 + +# Exit on command errors and treat unset variables as an error +set -eu + +# The parameter $1 is the backup directory location dedicated to the app +backup_dir=$1 + +# The parameter $2 is the id of the app instance ex: ynhexample__2 +app=$2 + +# Source app helpers +source /usr/share/yunohost/helpers + +# Get old parameter of the app +domain=$(ynh_app_setting_get $app domain) +path=$(ynh_app_setting_get $app path) +is_public=$(ynh_app_setting_get $app is_public) +final_path=$(ynh_app_setting_get $app final_path) + +if [ -d $final_path ]; then + ynh_die "There is already a directory: $final_path" +fi + +conf=/etc/nginx/conf.d/$domain.d/$app.conf +if [ -f $conf ]; then + ynh_die "There is already a nginx conf file at this path: $conf" +fi +# Restore conf files +sudo cp -a "${backup_dir}/conf/nginx.conf" $conf + +# Reload Nginx +sudo service nginx reload + +sudo cp -a "${backup_dir}/var/www/$app" $final_path + +db_pwd=$(ynh_app_setting_get $app mysqlpwd) +db_user=$app +ynh_mysql_create_db $db_user $db_user $db_pwd +sudo su -c "mysql -u $db_user -p$db_pwd $app < ${backup_dir}/db.sql" +sudo rm -f "${backup_dir}/db.sql" +sudo sed -i -e "s/'DB_USER', *'[^']*'/'DB_USER', '$app'/g" $final_path/config/connect.php +sudo sed -i -e "s/'DB_NAME', *'[^']*'/'DB_NAME', '$app'/g" $final_path/config/connect.php + +# Set permissions +# Les fichiers appartiennent à www-data, pour permettre les mises à jour. +sudo chown -R www-data: $final_path +# Sauf le fichier de config connect.php qui appartient à root +sudo chown root: $final_path/config/connect.php + +# Copy dedicated php-fpm process from backup folder to the right location +sudo cp -a $backup_dir/conf/php-fpm.conf /etc/php5/fpm/pool.d/$app.conf +sudo cp -a $backup_dir/conf/php-fpm.ini /etc/php5/fpm/conf.d/20-$app.ini +# And restart service +sudo service php5-fpm reload + +# Set ssowat config +if [ "$is_public" = "No" ]; +then + ynh_app_setting_delete $app skipped_uris +fi +sudo yunohost app ssowatconf diff --git a/scripts/upgrade b/scripts/upgrade new file mode 100644 index 0000000..db8f0f7 --- /dev/null +++ b/scripts/upgrade @@ -0,0 +1,58 @@ +#!/bin/bash + +# Exit on command errors and treat unset variables as an error +set -eu + +source .fonctions # Charge les fonctions génériques habituellement utilisées dans le script + +# See comments in install script +app=$YNH_APP_INSTANCE_NAME + +# Source YunoHost helpers +source /usr/share/yunohost/helpers + +# Retrieve app settings +domain=$(ynh_app_setting_get "$app" domain) +path=$(ynh_app_setting_get "$app" path) +admin=$(ynh_app_setting_get "$app" admin) +is_public=$(ynh_app_setting_get "$app" is_public) +language=$(ynh_app_setting_get "$app" language) + +CHECK_PATH # Vérifie et corrige la syntaxe du path. + +# Check if admin is not null +if [[ "$admin" = "" || "$is_public" = "" || "$language" = "" ]]; then + echo "Unable to upgrade, please contact support" + ynh_die +fi + +root_pwd=$(sudo cat /etc/yunohost/mysql) + +final_path=/var/www/$app + +db_name=$app + +CHECK_MD5_CONFIG "connect.php" "$final_path/config/connect.php" # Créé un backup du fichier de config si il a été modifié. + +# Modify Nginx configuration file and copy it to Nginx conf directory +sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf* +sed -i "s@ALIASTOCHANGE@$final_path/@g" ../conf/nginx.conf* + +if [ $is_public = "Yes" ]; +then + sudo cp ../conf/nginx.conf-public /etc/nginx/conf.d/$domain.d/$app.conf +else + sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf +fi + +# If app is public, add url to SSOWat conf as skipped_uris +if [[ $is_public -eq 1 ]]; then + # See install script + ynh_app_setting_set "$app" unprotected_uris "/" + sudo cp ../conf/nginx.conf-public /etc/nginx/conf.d/$domain.d/$app.conf +else + sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf +fi + +# Reload Nginx +sudo service nginx reload diff --git a/sources/source_dir b/sources/source_dir new file mode 100644 index 0000000..4f78cea --- /dev/null +++ b/sources/source_dir @@ -0,0 +1 @@ +prestashop \ No newline at end of file diff --git a/sources/source_md5 b/sources/source_md5 new file mode 100644 index 0000000..8b376cf --- /dev/null +++ b/sources/source_md5 @@ -0,0 +1 @@ +a48191b3e46965548687535372bcc1df prestashop_1.7.0.5.zip \ No newline at end of file diff --git a/sources/source_url b/sources/source_url new file mode 100644 index 0000000..7e46b12 --- /dev/null +++ b/sources/source_url @@ -0,0 +1 @@ +https://download.prestashop.com/download/releases/prestashop_1.7.0.5.zip \ No newline at end of file