diff --git a/tools/app_generator/app_generator.py b/tools/app_generator/app_generator.py
index ccfbf151..810d79a0 100644
--- a/tools/app_generator/app_generator.py
+++ b/tools/app_generator/app_generator.py
@@ -1,4 +1,7 @@
#### Imports
+from io import BytesIO
+import re
+import os
import jinja2 as j2
from flask import (
Flask,
@@ -301,16 +304,6 @@ class Resources(FlaskForm):
default=False,
)
- ## TODO
- # These infos are used by https://github.com/YunoHost/apps/blob/master/tools/autoupdate_app_sources/autoupdate_app_sources.py
- # to auto-update the previous asset urls and sha256sum + manifest version
- # assuming the upstream's code repo is on github and relies on tags or releases
- # See the 'sources' resource documentation for more details
-
- # autoupdate.strategy = "latest_github_tag"
-
-
-
apt_dependencies = StringField(
"Dépendances à installer via apt (séparées par des virgules et/ou espaces)",
render_kw={
@@ -375,11 +368,6 @@ class SpecificTechnology(FlaskForm):
# PHP
#
- # TODO : add a tip about adding the PHP dependencies in the APT deps earlier
-
- # TODO : add a tip about the auto-prepared nginx config that will include the fastcgi snippet
-
-
use_composer = BooleanField(
"Utiliser composer",
description="Composer est un gestionnaire de dépendance PHP utilisé par certaines apps",
@@ -405,8 +393,6 @@ class SpecificTechnology(FlaskForm):
# NodeJS / Python / Ruby / ...
- # TODO : add a tip about the auto-prepared nginx config that will include a proxy_pass / reverse proxy to an auto-prepared systemd service
-
systemd_execstart = StringField(
"Commande pour lancer le daemon de l'app (depuis le service systemd)",
description="Corresponds to 'ExecStart' statement in systemd. You can use '__INSTALL_DIR__' to refer to the install directory, or '__APP__' to refer to the app id",
@@ -443,7 +429,7 @@ class AppConfig(FlaskForm):
class MoreAdvanced(FlaskForm):
- supports_change_url = BooleanField(
+ enable_change_url = BooleanField(
"Gérer le changement d'URL d'installation (script change_url)",
default=True,
render_kw={
@@ -462,7 +448,7 @@ class MoreAdvanced(FlaskForm):
# custom_log_file = "/var/log/$app/$app.log" "/var/log/nginx/${domain}-error.log"
use_fail2ban = BooleanField(
"Protéger l'application des attaques par force brute (via fail2ban)",
- default=True,
+ default=False,
render_kw={
"title": "Si l'application genère des journaux (log) d'erreurs de connexion, cette option permet de bannir automatiquement les IP au bout d'un certain nombre d'essais de mot de passe. Recommandé."
},
@@ -497,249 +483,97 @@ class MoreAdvanced(FlaskForm):
class GeneratorForm(
GeneralInfos, IntegrationInfos, UpstreamInfos, InstallQuestions, Resources, SpecificTechnology, AppConfig, MoreAdvanced
):
+
+ class Meta:
+ csrf = False
+
generator_mode = SelectField(
"Mode du générateur",
description="En mode tutoriel, l'application générée contiendra des commentaires additionnels pour faciliter la compréhension. En version épurée, l'application générée ne contiendra que le minimum nécessaire.",
- choices=[("false", "Version épurée"), ("true", "Version tutoriel")],
+ choices=[("simple", "Version épurée"), ("tutorial", "Version tutoriel")],
default="true",
validators=[DataRequired()],
)
- submit = SubmitField("Soumettre")
+ submit_preview = SubmitField("Prévisualiser")
+ submit_download = SubmitField("Télécharger le .zip")
#### Web pages
@app.route("/", methods=["GET", "POST"])
def main_form_route():
- parameters = {}
main_form = GeneratorForm()
+ app_files = []
if request.method == "POST":
- result = request.form
- results = dict(result)
- # print("[DEBUG] This is a POST request")
- # print(results)
- for key, value in results.items():
- parameters[key] = value
- parameters["preview"] = True
- if main_form.validate_on_submit():
- parameters["invalid_form"] = False
- print()
- print("formulaire valide")
- # print(main_form.data.items())
- for key, value in main_form.data.items():
- parameters[key] = value # TODO change the name
+ if not main_form.validate_on_submit():
+ print("not validated?")
+ print(main_form.errors)
- templates = (
- "templates/manifest.j2",
- "templates/install.j2",
- "templates/remove.j2",
- "templates/backup.j2",
- "templates/restore.j2",
- "templates/upgrade.j2",
- "templates/config.j2",
- "templates/change_url.j2",
- "templates/_common.sh.j2",
- )
- markdown_to_html = dict()
- for template in templates:
- markdown_content, html_content = markdown_file_to_html_string(template)
- template_key = template.split("templates/")[1].split(".j2")[
- 0
- ] # Let's retrieve what's the exact template used
- markdown_to_html[template_key] = {
- "markdown_content": markdown_content,
- "html_content": html_content,
- }
- # print(markdown_to_html["markdown_content"])
- # print(markdown_to_html["html_content"])
-
- ## Prepare the file contents for the download button
- # print(markdown_to_html['manifest']['markdown_content'])
-
- # Workaround so /download_zip can access the content - FIXME ?
- global template_manifest_content
- global template_install_content
- global template_remove_content
- global template_backup_content
- global template_restore_content
- global template_upgrade_content
- global template_config_content
- global template_change_url_content
- global template_common_sh_content
- global custom_config_file
- global nginx_config_file
- global systemd_config_file
- global cron_config_file
-
- template_manifest_content = render_template_string(
- markdown_to_html["manifest"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- )
-
- template_install_content = render_template_string(
- markdown_to_html["install"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html["install"],
- )
-
- template_remove_content = render_template_string(
- markdown_to_html["remove"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html["remove"],
- )
-
- template_backup_content = render_template_string(
- markdown_to_html["backup"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html["backup"],
- )
-
- template_restore_content = render_template_string(
- markdown_to_html["restore"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html["restore"],
- )
-
- template_upgrade_content = render_template_string(
- markdown_to_html["upgrade"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html["upgrade"],
- )
-
- template_config_content = render_template_string(
- markdown_to_html["config"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html["config"],
- )
-
- template_common_sh_content = render_template_string(
- markdown_to_html["_common.sh"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html["_common.sh"],
- )
-
- if parameters["supports_change_url"]:
- template_change_url_content = render_template_string(
- markdown_to_html["change_url"]["markdown_content"],
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html["change_url"],
- )
- else:
- template_change_url_content = False
-
- print(parameters["custom_config_file"])
- print(parameters["use_custom_config_file"])
return render_template(
- "index.html",
- parameters=parameters,
- main_form=main_form,
- markdown_to_html=markdown_to_html,
- template_manifest_content=template_manifest_content,
- template_install_content=template_install_content,
- template_remove_content=template_remove_content,
- template_backup_content=template_backup_content,
- template_restore_content=template_restore_content,
- template_upgrade_content=template_upgrade_content,
- template_config_content=template_config_content,
- template_change_url_content=template_change_url_content,
- template_common_sh_content=template_common_sh_content,
- nginx_config_file=parameters["nginx_config_file"],
- systemd_config_file=parameters["systemd_config_file"],
- custom_config_file=parameters["custom_config_file"],
- cron_config_file=parameters["cron_config_file"],
+ "index.html", main_form=main_form, generated_files={}
)
- else:
- print("[DEBUG] Formulaire invalide: ", main_form.errors)
- parameters["preview"] = False
- parameters["invalid_form"] = True
- elif request.method == "GET":
- parameters["preview"] = False
+ submit_mode = "preview" if main_form.submit_preview.data else "download"
+
+ class AppFile:
+ def __init__(self, id_, destination_path=None):
+ self.id = id_
+ self.destination_path = destination_path
+ self.content = None
+
+ app_files = [
+ AppFile("manifest", "manifest.toml"),
+ AppFile("_common.sh", "scripts/_common.sh"),
+ AppFile("install", "scripts/install"),
+ AppFile("remove", "scripts/remove"),
+ AppFile("backup", "scripts/backup"),
+ AppFile("restore", "scripts/restore"),
+ AppFile("upgrade", "scripts/upgrade"),
+ AppFile("nginx", "conf/nginx.conf"),
+ ]
+
+ if main_form.enable_change_url:
+ app_files.append(AppFile("change_url", "scripts/change_url"))
+
+ if main_form.main_technology not in ["none", "php"]:
+ app_files.append(AppFile("systemd", "conf/systemd.service"))
+
+ if main_form.main_technology == "php":
+ app_files.append(AppFile("php", "conf/extra_php-fpm.conf"))
+
+ template_dir = os.path.dirname(__file__) + "/templates/"
+ for app_file in app_files:
+ template = open(template_dir + app_file.id + ".j2").read()
+ app_file.content = render_template_string(template, data=dict(request.form))
+ app_file.content = re.sub(r'\n\s+$', '\n', app_file.content, flags=re.M)
+ app_file.content = re.sub(r'\n{3,}', '\n\n', app_file.content, flags=re.M)
+
+ # TODO
+ #if main_form.use_custom_config_file:
+ # app_files.append(AppFile("appconf", "conf/" + main_form.custom_config_file))
+ # app_files[-1].content = main_form.custom_config_file_content
+
+ # TODO : same for cron job
+
+ if submit_mode == "download":
+ # Generate the zip file
+ f = BytesIO()
+ with zipfile.ZipFile(f, "w") as zf:
+ for app_file in app_files:
+ print(app_file.id)
+ zf.writestr(app_file.destination_path, app_file.content)
+ f.seek(0)
+ # Send the zip file to the user
+ return send_file(f, as_attachment=True, download_name=request.form["app_id"] + ".zip")
return render_template(
- "index.html", parameters=parameters, main_form=main_form
+ "index.html", main_form=main_form, generated_files=app_files
)
-@app.route("/download_zip", methods=("GET", "POST"))
-def telecharger_zip():
- # Retrieve arguments
- print("Génération du .zip")
- app_id = request.args.get("app_id")
- print("Génération du .zip pour " + app_id)
-
- custom_config_file = parse.unquote(request.args.get("custom_config_file"))
- custom_config_file_content = parse.unquote(
- request.args.get("custom_config_file_content")
- )
- systemd_config_file = parse.unquote(request.args.get("systemd_config_file"))
- nginx_config_file = parse.unquote(request.args.get("nginx_config_file"))
- cron_config_file = parse.unquote(request.args.get("cron_config_file"))
-
- global template_manifest_content
- global template_install_content
- global template_remove_content
- global template_backup_content
- global template_restore_content
- global template_upgrade_content
- global template_config_content
- global template_change_url_content
- global template_common_sh_content
-
- # global custom_config_file
-
- use_php = request.args.get("use_php")
- print("PHP")
- print(use_php)
- php_config_file = parse.unquote(request.args.get("php_config_file"))
- php_config_file_content = parse.unquote(request.args.get("php_config_file_content"))
-
- archive_name = (
- app_id + ".zip"
- ) # Actually it's the javascript that decide of the filename… this is only an internal name
-
- # Generate the zip file (will be stored in the working directory)
- with zipfile.ZipFile(archive_name, "w") as zf:
- # Add text in directly in the ZIP, as a file
- zf.writestr("manifest.toml", template_manifest_content)
- zf.writestr("scripts/install", template_install_content)
- zf.writestr("scripts/remove", template_remove_content)
- zf.writestr("scripts/backup", template_backup_content)
- zf.writestr("scripts/restore", template_restore_content)
- zf.writestr("scripts/upgrade", template_upgrade_content)
- zf.writestr("scripts/_common_sh", template_common_sh_content)
-
- if template_config_content:
- zf.writestr("scripts/config", template_config_content)
- if template_change_url_content:
- zf.writestr("scripts/change_url", template_change_url_content)
- if custom_config_file:
- zf.writestr("conf/" + custom_config_file, custom_config_file_content)
- if systemd_config_file:
- zf.writestr("conf/systemd.service", systemd_config_file)
- if nginx_config_file:
- zf.writestr("conf/nginx.conf", nginx_config_file)
- if cron_config_file:
- zf.writestr("conf/task.conf", cron_config_file)
- if use_php == "True":
- zf.writestr("conf/" + php_config_file, php_config_file_content)
-
- # Send the zip file to the user
- return send_file(archive_name, as_attachment=True)
-
-
#### Running the web server
if __name__ == "__main__":
app.run(debug=True)
diff --git a/tools/app_generator/templates/_common.sh.j2 b/tools/app_generator/templates/_common.sh.j2
index ea830fd7..eb200e90 100644
--- a/tools/app_generator/templates/_common.sh.j2
+++ b/tools/app_generator/templates/_common.sh.j2
@@ -4,17 +4,11 @@
# COMMON VARIABLES
#=================================================
-{% if parameters["use_nodejs"] -%}
-nodejs_version={{ parameters["use_nodejs_version"]}}
+{% if data.use_nodejs -%}
+nodejs_version={{ data.nodejs_version }}
{% endif -%}
+
#=================================================
# PERSONAL HELPERS
#=================================================
-#=================================================
-# EXPERIMENTAL HELPERS
-#=================================================
-
-#=================================================
-# FUTURE OFFICIAL HELPERS
-#=================================================
diff --git a/tools/app_generator/templates/backup.j2 b/tools/app_generator/templates/backup.j2
index 495cce94..db3c8be8 100644
--- a/tools/app_generator/templates/backup.j2
+++ b/tools/app_generator/templates/backup.j2
@@ -1,9 +1,9 @@
#!/bin/bash
-#### App file generated with YoloGen, the YunoHost app generator, version {{ parameters['GENERATOR_VERSION'] }}.
-{% if parameters["tutorial"] -%} # This is the tutorial version of the app.
+#### App file generated with YoloGen, the YunoHost app generator, version {{ data.GENERATOR_VERSION }}.
+{% if data.generator_mode == 'tutorial' -%} # This is the tutorial version of the app.
# It contains extra commands to explain what should be done in case you want to adjust some part of the script.
# Once you are done, you may remove them.
-{% endif -%}
+{% endif %}
#=================================================
# GENERIC START
#=================================================
@@ -19,91 +19,63 @@ source /usr/share/yunohost/helpers
#=================================================
ynh_print_info --message="Declaring files to be backed up..."
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
### N.B. : the following 'ynh_backup' calls are only a *declaration* of what needs
### to be backuped and not an actual copy of any file. The actual backup that
### creates and fill the archive with the files happens in the core after this
### script is called. Hence ynh_backups calls takes basically 0 seconds to run.
-{% endif -%}
-
-#=================================================
-# BACKUP THE APP MAIN DIR
-#=================================================
+{% endif %}
+{% if data.data_dir -%}
ynh_backup --src_path="$install_dir"
+{% endif %}
-{% if parameters["data_dir"] -%}
-#=================================================
-# BACKUP THE DATA DIR
-#=================================================
-
- {% if parameters["tutorial"] -%}
+{% if data.data_dir -%}
+{% if data.generator_mode == 'tutorial' -%}
# The --is_big parameters ensure this folder is not included in the backup by default (taking less space), except if BACKUP_CORE_ONLY=0 is passed before the backup command. You might want to document that for your users.
- {% endif -%}
-# Only relevant if there is a "data_dir" resource for this app
+{% endif %}
ynh_backup --src_path="$data_dir" --is_big
-{% endif -%}
-#=================================================
-# BACKUP THE NGINX CONFIGURATION
-#=================================================
+{% endif %}
ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf"
-{% if parameters["use_php"] -%}
-#=================================================
-# BACKUP THE PHP-FPM CONFIGURATION
-#=================================================
-
+{% if data.main_technology == "php" -%}
ynh_backup --src_path="/etc/php/$phpversion/fpm/pool.d/$app.conf"
-{% endif -%}
-{% if parameters["use_fail2ban"] -%}
-#=================================================
-# BACKUP FAIL2BAN CONFIGURATION
-#=================================================
+{% endif %}
+{% if data.use_fail2ban -%}
ynh_backup --src_path="/etc/fail2ban/jail.d/$app.conf"
ynh_backup --src_path="/etc/fail2ban/filter.d/$app.conf"
-{% endif -%}
-{% if parameters["use_logrotate"] -%}
-#=================================================
-# SPECIFIC BACKUP
-#=================================================
-# BACKUP LOGROTATE
-#=================================================
+{% endif %}
+{% if data.use_logrotate -%}
ynh_backup --src_path="/etc/logrotate.d/$app"
-{% endif -%}
-{% if parameters["use_systemd_service"] -%}
-#=================================================
-# BACKUP SYSTEMD
-#=================================================
+{% endif %}
+{% if data.main_technology not in ["php", "none"] -%}
ynh_backup --src_path="/etc/systemd/system/$app.service"
-{% endif -%}
-#=================================================
-# BACKUP VARIOUS FILES
-#=================================================
-{% if parameters["use_cron"] -%}
+{% endif %}
+
+{% if data.use_cron -%}
ynh_backup --src_path="/etc/cron.d/$app"
-{% endif -%}
-ynh_backup --src_path="/etc/$app/"
+{% endif %}
-
-{% if parameters["use_db"] -%}
+{% if data.database != 'false' -%}
#=================================================
# BACKUP THE DATABASE
#=================================================
-ynh_print_info --message="Backing up the {{ parameters['use_db'] }} database..."
+ynh_print_info --message="Backing up the {{ data.database }} database..."
### (However, things like MySQL dumps *do* take some time to run, though the
### copy of the generated dump to the archive still happens later)
-{% if parameters["use_db"] == 'mysql' -%}
+{% if data.use_db == 'mysql' -%}
ynh_mysql_dump_db --database="$db_name" > db.sql
-{% elif parameters["use_db"] == 'postgresql' -%}
+{% elif data.use_db == 'postgresql' -%}
ynh_psql_dump_db --database="$db_name" > db.sql
-{% endif -%}
-{% endif -%}
+{% endif %}
+{% endif %}
+
#=================================================
# END OF SCRIPT
#=================================================
diff --git a/tools/app_generator/templates/change_url.j2 b/tools/app_generator/templates/change_url.j2
index 92a1d85e..bfd0a14c 100644
--- a/tools/app_generator/templates/change_url.j2
+++ b/tools/app_generator/templates/change_url.j2
@@ -1,9 +1,11 @@
#!/bin/bash
-#### App file generated with YoloGen, the YunoHost app generator, version {{ parameters['GENERATOR_VERSION'] }}.
-{% if parameters["tutorial"] -%} # This is the tutorial version of the app.
+
+{% if data.generator_mode == 'tutorial' -%}
+# This is the tutorial version of the app.
# It contains extra commands to explain what should be done in case you want to adjust some part of the script.
# Once you are done, you may remove them.
-{% endif -%}
+{% endif %}
+
#=================================================
# GENERIC STARTING
#=================================================
@@ -13,20 +15,19 @@
source _common.sh
source /usr/share/yunohost/helpers
+{% if data.main_technology not in ["php", "none"] -%}
#=================================================
-# STANDARD MODIFICATIONS
-#=================================================
-{% if parameters["use_systemd_service"] -%}
# STOP SYSTEMD SERVICE
#=================================================
-ynh_script_progression --message="Stopping a systemd service..." --weight=1
+ynh_script_progression --message="Stopping a systemd service..."
ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app/$app.log"
-{% endif -%}
+{% endif %}
+
#=================================================
# 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..."
ynh_change_url_nginx_config
@@ -36,16 +37,15 @@ ynh_change_url_nginx_config
# ...
#=================================================
+{% if data.main_technology not in ["php", "none"] -%}
#=================================================
-# GENERIC FINALISATION
-#=================================================
-{% if parameters["use_systemd_service"] -%}
# START SYSTEMD SERVICE
#=================================================
-ynh_script_progression --message="Starting a systemd service..." --weight=1
+ynh_script_progression --message="Starting a systemd service..."
ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log"
-{% endif -%}
+{% endif %}
+
#=================================================
# END OF SCRIPT
#=================================================
diff --git a/tools/app_generator/templates/config.j2 b/tools/app_generator/templates/config.j2
deleted file mode 100644
index acc66a01..00000000
--- a/tools/app_generator/templates/config.j2
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/bin/bash
-#### App file generated with YoloGen, the YunoHost app generator, version {{ parameters['GENERATOR_VERSION'] }}.
-{% if parameters["tutorial"] -%} # This is the tutorial version of the app.
-# It contains extra commands to explain what should be done in case you want to adjust some part of the script.
-# Once you are done, you may remove them.
-{% endif -%}
-
-{% if parameters["tutorial"] -%}
-# 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... ).
-{% endif -%}
-#=================================================
-# GENERIC STARTING
-#=================================================
-# IMPORT GENERIC HELPERS
-#=================================================
-
-source /usr/share/yunohost/helpers
-
-ynh_abort_if_errors
-
-#=================================================
-# RETRIEVE ARGUMENTS
-#=================================================
-
-install_dir=$(ynh_app_setting_get --app=$app --key=install_dir)
-
-#=================================================
-# 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\['" "$install_dir/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'\]" "$install_dir/settings.py"
-
- echo "DONATION['$frequency']['$currency'] = '$price_id'" >> "$install_dir/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/tools/app_generator/templates/index.html b/tools/app_generator/templates/index.html
index ba22c9f1..10a14486 100644
--- a/tools/app_generator/templates/index.html
+++ b/tools/app_generator/templates/index.html
@@ -31,189 +31,14 @@ YunoHost app generator
{% endblock %}
{% block content %}
-
-
-
-
Formulaire de génération d'une application Yunohost
diff --git a/tools/app_generator/templates/install.j2 b/tools/app_generator/templates/install.j2
index f6e07073..cef50dbd 100644
--- a/tools/app_generator/templates/install.j2
+++ b/tools/app_generator/templates/install.j2
@@ -1,9 +1,11 @@
#!/bin/bash
-#### App file generated with YoloGen, the YunoHost app generator, version {{ parameters['GENERATOR_VERSION'] }}.
-{% if parameters["tutorial"] -%} # This is the tutorial version of the app.
+
+{% if data.generator_mode == 'tutorial' -%}
+# This is the tutorial version of the app.
# It contains extra commands to explain what should be done in case you want to adjust some part of the script.
# Once you are done, you may remove them.
-{% endif -%}
+{% endif %}
+
#=================================================
# GENERIC START
#=================================================
@@ -12,7 +14,7 @@
source _common.sh
source /usr/share/yunohost/helpers
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# Install parameters are automatically saved as settings
#
# Settings are automatically loaded as bash variables
@@ -33,121 +35,70 @@ source /usr/share/yunohost/helpers
# $app is the app id (i.e. 'example' for first install,
# or 'example__2', '__3', ... for multi-instance installs)
#
-{% endif -%}
+{% endif %}
#=================================================
# INSTALL DEPENDENCIES
#=================================================
-ynh_script_progression --message="Installing dependencies..." --weight=10
-{% if parameters["use_nodejs_needs_yarn"] -%}
+{% if data.main_technology == "nodejs" -%}
+ynh_script_progression --message="Installing NodeJS..." --weight=10
+
# Install Nodejs
ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$nodejs_version
-{% endif -%}
+ynh_use_nodejs
+{% endif %}
#=================================================
# APP "BUILD" (DEPLOYING SOURCES, VENV, COMPILING ETC)
#=================================================
# DOWNLOAD, CHECK AND UNPACK SOURCE
#=================================================
-ynh_script_progression --message="Setting up source files..." --weight=1
+ynh_script_progression --message="Setting up source files..."
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
### `ynh_setup_source` is used to install an app from a zip or tar.gz file,
-### downloaded from an upstream source, like a git repository.
-### `ynh_setup_source` use the file conf/app.src
-{% endif -%}
+### downloaded from an upstream source, as defined in the manifest.toml
+{% endif %}
-# Download, check integrity, uncompress and patch the source from app.src
ynh_setup_source --dest_dir="$install_dir"
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# $install_dir will automatically be initialized with some decent
# permission by default ... however, you may need to recursively reapply
# ownership to all files such as after the ynh_setup_source step
-{% endif -%}
-chown -R $app:www-data "$install_dir" {# TODO : we may need to allow people to configure this #}
+{% endif %}
+chown -R $app:www-data "$install_dir"
#=================================================
# SYSTEM CONFIGURATION
#=================================================
-ynh_script_progression --message="Adding system configurations related to $app..." --weight=1
-{% if use_php -%}
+ynh_script_progression --message="Adding system configurations related to $app..."
-{% if version == "tutorial" -%}
-### `ynh_add_fpm_config` is used to set up a PHP config.
-### You can remove it if your app doesn't use PHP.
-### `ynh_add_fpm_config` will use the files conf/php-fpm.conf
-### If you're not using these lines:
-### - You can remove these files in conf/.
-### - Remove the section "BACKUP THE PHP-FPM CONFIGURATION" in the backup script
-### - Remove also the section "REMOVE PHP-FPM CONFIGURATION" in the remove script
-### - As well as the section "RESTORE THE PHP-FPM CONFIGURATION" in the restore script
-### with the reload at the end of the script.
-### - And the section "PHP-FPM CONFIGURATION" in the upgrade script
-### But wait : This should have been handled by our app generator ;)
-{% endif -%}
-
-ynh_script_progression --message="Adding {{php_version}} configurations related to $app..." --weight=1
-# Create a dedicated PHP-FPM config using the conf/php-fpm.conf or conf/extra_php-fpm.conf
+{% if data.main_technology == "php" -%}
+# Create a dedicated PHP-FPM config
+# conf/extra_php-fpm.conf will be appended to the auto-generated config, which will go in /etc/php/X.Y/fpm/pool.d/
ynh_add_fpm_config
-{% endif -%}
-
-
-{% if use_php -%}
-
- {% if version == "tutorial" -%}
-### `ynh_add_fpm_config` is used to set up a PHP config.
-### You can remove it if your app doesn't use PHP.
-### `ynh_add_fpm_config` will use the files conf/php-fpm.conf
-### If you're not using these lines:
-### - You can remove these files in conf/.
-### - Remove the section "BACKUP THE PHP-FPM CONFIGURATION" in the backup script
-### - Remove also the section "REMOVE PHP-FPM CONFIGURATION" in the remove script
-### - As well as the section "RESTORE THE PHP-FPM CONFIGURATION" in the restore script
-### with the reload at the end of the script.
-### - And the section "PHP-FPM CONFIGURATION" in the upgrade script
- {% endif -%}
-
-ynh_script_progression --message="Adding {{php_version}} configurations related to $app..." --weight=1
-# Create a dedicated PHP-FPM config using the conf/php-fpm.conf or conf/extra_php-fpm.conf
-ynh_add_fpm_config
-{% endif -%}
+{% endif %}
# Create a dedicated NGINX config using the conf/nginx.conf template
ynh_add_nginx_config
-{% if parameters["use_systemd_service"] -%}
- {% if version == "tutorial" -%}
-### `ynh_systemd_config` is used to configure a systemd script for an app.
-### It can be used for apps that use sysvinit (with adaptation) or systemd.
-### Have a look at the app to be sure this app needs a systemd script.
-### `ynh_systemd_config` will use the file conf/systemd.service
-### If you're not using these lines:
-### - You can remove those files in conf/.
-### - Remove the section "BACKUP SYSTEMD" in the backup script
-### - Remove also the section "STOP AND REMOVE SERVICE" in the remove script
-### - As well as the section "RESTORE SYSTEMD" in the restore script
-### - And the section "SETUP SYSTEMD" in the upgrade script
- {% endif -%}
-
+{% if data.main_technology not in ["php", "none"] -%}
+{% if data.generator_mode == 'tutorial' -%}
+### `ynh_systemd_config` is used to configure a systemd script for an app, using the conf/systemd.service template
+{% endif %}
# Create a dedicated systemd config
ynh_add_systemd_config
- {% if version == "tutorial" -%}
+{% if data.generator_mode == 'tutorial' -%}
### `yunohost service add` integrates a service in YunoHost. It then gets
### displayed in the admin interface and through the others `yunohost service` commands.
-### (N.B.: this line only makes sense if the app adds a service to the system!)
-### If you're not using these lines:
-### - You can remove these files in conf/.
-### - Remove the section "REMOVE SERVICE INTEGRATION IN YUNOHOST" in the remove script
-### - As well as the section "INTEGRATE SERVICE IN YUNOHOST" in the restore script
-### - And the section "INTEGRATE SERVICE IN YUNOHOST" in the upgrade script
- {% endif -%}
+{% endif %}
-yunohost service add $app --description="{{ parameters['systemd_service_description'] }}" --log="/var/log/$app/$app.log"
+yunohost service add $app --log="/var/log/$app/$app.log"
- {% if version == "tutorial" -%}
+{% if data.generator_mode == 'tutorial' -%}
### Additional options starting with 3.8:
###
### --needs_exposed_ports "$port" a list of ports that needs to be publicly exposed
@@ -163,43 +114,35 @@ yunohost service add $app --description="{{ parameters['systemd_service_descript
### to proceed if you later realize that you need to enable some flags that
### weren't enabled on old installs (be careful it'll override the existing
### service though so you should re-provide all relevant flags when doing so)
-
-### `ynh_use_logrotate` is used to configure a logrotate configuration for the logs of this app.
-### Use this helper only if there is effectively a log file for this app.
-### If you're not using this helper:
-### - Remove the section "BACKUP LOGROTATE" in the backup script
-### - Remove also the section "REMOVE LOGROTATE CONFIGURATION" in the remove script
-### - As well as the section "RESTORE THE LOGROTATE CONFIGURATION" in the restore script
-### - And the section "SETUP LOGROTATE" in the upgrade script
- {% endif -%}
{% endif -%}
+{% endif %}
+{% if data.use_logrotate %}
# Use logrotate to manage application logfile(s)
ynh_use_logrotate
+{% endif %}
-{% if parameters["use_fail2ban"] -%}
+{% if data.use_fail2ban -%}
# Create a dedicated Fail2Ban config
-ynh_add_fail2ban_config --logpath="/var/log/nginx/${domain}-error.log" --failregex="{{ parameters['fail2ban_regex'] }}"
-{% endif -%}
+ynh_add_fail2ban_config --logpath="/var/log/nginx/${domain}-error.log" --failregex="{{ data.fail2ban_regex }}"
+{% endif %}
-{% if parameters["use_cron"] -%}
-#=================================================
-# ADD A CRON JOB
-#=================================================
+{% if data.use_cron -%}
+# Add cron job
cron_path="/etc/cron.d/$app"
ynh_add_config --template="../conf/task.cron" --destination="$cron_path"
chown root: "$cron_path"
chmod 644 "$cron_path"
-{% endif -%}
+{% endif %}
#=================================================
# APP INITIAL CONFIGURATION
#=================================================
# ADD A CONFIGURATION
#=================================================
-ynh_script_progression --message="Adding a configuration file..." --weight=1
+ynh_script_progression --message="Adding app's configuration file..."
-{% if version == "tutorial" -%}
+{% if data.generator_mode == 'tutorial' -%}
### You can add specific configuration files.
###
### Typically, put your template conf file in ../conf/your_config_file
@@ -211,73 +154,60 @@ ynh_script_progression --message="Adding a configuration file..." --weight=1
### if it's found that the file was manually modified
###
### Check the documentation of `ynh_add_config` for more info.
-{% endif -%}
+{% endif %}
-ynh_add_config --template="{{ parameters['custom_config_file'] }}" --destination="$install_dir/{{ parameters['custom_config_file'] }}"
+ynh_add_config --template="{{ data.custom_config_file }}" --destination="$install_dir/{{ data.custom_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 "$install_dir/{{ parameters['custom_config_file'] }}"
-chown $app:$app "$install_dir/{{ parameters['custom_config_file'] }}"
+chmod 400 "$install_dir/{{ data.custom_config_file }}"
+chown $app:$app "$install_dir/{{ data.custom_config_file }}"
+{% if data.generator_mode == 'tutorial' -%}
### 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="$install_dir/some_config_file"
### ynh_store_file_checksum --file="$install_dir/some_config_file"
+{% endif %}
-{% if parameters["use_nodejs_needs_yarn"] -%}
+{% if data.install_snippet -%}
#=================================================
-# INSTALL YARN
+# INSTALL APP
#=================================================
-ynh_script_progression --message="Installing yarn dependency..." --weight=15
+ynh_script_progression --message="Installing app..." --weight=5
pushd $install_dir
- ynh_use_nodejs
- ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH yarn install
+{{ data.install_snippet }}
popd
-{% endif -%}
+{% endif %}
#=================================================
-# SETUP APPLICATION WITH CURL
+# FINALIZE APP INSTALL WITH CURL
#=================================================
-{% if version == "tutorial" -%}
+{% if data.generator_mode == 'tutorial' -%}
### Use these lines only if the app installation needs to be finalized through
### web forms. We generally don't want to ask the final user,
### so we're going to use curl to automatically fill the fields and submit the
### forms.
-{% endif -%}
+{% endif %}
-#### TODO in Yunohost App Generator
-# Installation with curl
-ynh_script_progression --message="Finalizing installation..." --weight=1
-ynh_local_curl "/INSTALL_PATH" "key1=value1" "key2=value2" "key3=value3"
+# REMOVEME? ynh_script_progression --message="Finalizing installation..."
+# REMOVEME? ynh_local_curl "/INSTALL_PATH" "key1=value1" "key2=value2" "key3=value3"
+{% if data.main_technology not in ["php", "none"] -%}
#=================================================
-# GENERIC FINALIZATION
-#=================================================
-{% if parameters["use_systemd_service"] -%}
# START SYSTEMD SERVICE
#=================================================
-ynh_script_progression --message="Starting a systemd service..." --weight=1
-
-
-{% if version == "tutorial" -%}
-### `ynh_systemd_action` is used to start a systemd service for an app.
-### Only needed if you have configure a systemd service
-### If you're not using these lines:
-### - Remove the section "STOP SYSTEMD SERVICE" and "START SYSTEMD SERVICE" in the backup script
-### - As well as the section "START SYSTEMD SERVICE" in the restore script
-### - As well as the section"STOP SYSTEMD SERVICE" and "START SYSTEMD SERVICE" in the upgrade script
-### - And the section "STOP SYSTEMD SERVICE" and "START SYSTEMD SERVICE" in the change_url script
-{% endif -%}
+ynh_script_progression --message="Starting app's systemd service..."
# Start a systemd service
ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log"
-{% endif -%}
+{% endif %}
+
#=================================================
# END OF SCRIPT
#=================================================
diff --git a/tools/app_generator/templates/manifest.j2 b/tools/app_generator/templates/manifest.j2
index 54b7bf44..244c035e 100644
--- a/tools/app_generator/templates/manifest.j2
+++ b/tools/app_generator/templates/manifest.j2
@@ -1,101 +1,93 @@
packaging_format = 2
-id = "{{ parameters['app_id'] }}"
-name = "{{ parameters['app_name'] }}"
+id = "{{ data.app_id }}"
+name = "{{ data.app_name }}"
-{% if parameters['tutorial'] -%}
-{% endif -%}
+description.en = "{{ data.description_en }}"
+description.fr = "{{ data.description_fr }}"
+version = "{{ data.version }}"
-description.en = "{{ parameters['description_en'] }}"
-description.fr = "{{ parameters['description_fr'] }}"
-
-version = "{{ parameters['version'] }}"
-
-maintainers = ["{{ parameters['maintainers'] }}"]
+{% if data.maintainers -%}
+maintainers = ["{{ data.maintainers }}"]
+{%- endif %}
[upstream]
-# NB: Only the "license" key is mandatory. Remove entries for which there's no relevant data
-license = "{{ parameters['license'] }}"
-website = "{{ parameters['website'] }}"
-demo = "{{ parameters['demo'] }}"
-admindoc = "{{ parameters['admindoc'] }}"
-userdoc = "{{ parameters['userdoc'] }}"
-code = "{{ parameters['code'] }}"
-# FIXME: optional but recommended if relevant, this is meant to contain the Common Platform Enumeration, which is sort of a standard id for applications defined by the NIST. In particular, YunoHost may use this is in the future to easily track CVE (=security reports) related to apps. The CPE may be obtained by searching here: https://nvd.nist.gov/products/cpe/search. For example, for Nextcloud, the CPE is 'cpe:2.3:a:nextcloud:nextcloud' (no need to include the version number)
-cpe = "???"
-# FIXME: optional but recommended (or remove if irrelevant / not applicable). This is meant to be an URL where people can financially support this app, especially when its development is based on volunteers and/or financed by its community. YunoHost may later advertise it in the webadmin.
-fund = "???"
-
+license = "{{ data.license }}"
+{% if data.website -%}website = "{{ data.website }}"{%- endif %}
+{% if data.demo -%}demo = "{{ data.demo }}"{%- endif %}
+{% if data.admindoc -%}admindoc = "{{ data.admindoc }}"{%- endif %}
+{% if data.userdoc -%}userdoc = "{{ data.userdoc }}"{%- endif %}
+{% if data.code -%}code = "{{ data.code }}"{%- endif %}
[integration]
-{% if parameters['yunohost_required_version'] -%}
-yunohost = '>= {{ parameters['yunohost_required_version'] }}'
-{% else -%}
-yunohost = ">= 11.1.21"
-{% endif -%}
-
-{% if parameters['tutorial'] -%}
+yunohost = '>= {{ data.yunohost_required_version or '11.2'}}'
+{% if data.generator_mode == "tutorial" -%}
# List of supported archs using the dpkg --print-architecture nomenclature (amd64/i386/armhf/arm64), for example: ["amd64", "i386']
{% endif -%}
-architectures = "{{ parameters['architectures'] }}" # TODO : handle the "all" option (no ["all"])
-multi_instance = {{% if parameters['multi_instance'] -%} true {% else -%} false {% endif -%}
-ldap = "{{ parameters['ldap'] }}"
-sso = "{{ parameters['sso'] }}"
+architectures = "{{ data.architectures }}" # TODO : handle the "all" option (no ["all"])
+multi_instance = {% if data.multi_instance -%} true {% else -%} false {% endif -%}
+ldap = "{{ data.ldap }}" # TODO : fixme, use actual booleans + handle the "not_relevant" value
+sso = "{{ data.sso }}"
# FIXME: replace with an **estimate** minimum disk and RAM requirements. e.g. 20M, 400M, 1G... You may have have a look at CI results
disk = "50M"
ram.build = "50M"
ram.runtime = "50M"
[install]
+
+ {% if data.domain_and_path != "false" -%}
[install.domain]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# this is a generic question - ask strings are automatically handled by YunoHost's core
{% endif -%}
type = "domain"
- {% if not parameters['use_whole_domain'] -%}
+ {% if data.domain_and_path != "full_domain" -%}
[install.path]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# this is a generic question - ask strings are automatically handled by YunoHost's core
{% endif -%}
type = "path"
default = "/example"
{% endif -%}
+ {% endif %}
+ {% if data.init_main_permission -%}
[install.init_main_permission]
+ {% if data.generator_mode == "tutorial" -%}
# this is a generic question - ask strings are automatically handled by YunoHost's core
# This won't be saved as setting and will instead be used to initialize the SSOwat permission
+ {% endif -%}
type = "group"
- default = "{{ parameters['visibility'] }}"
+ default = "visitors"
+ {% endif %}
+ {% if data.language != "_" -%}
[install.language]
ask.en = "Choose the application language"
ask.fr = "Choisissez la langue de l'application"
type = "select"
- choices = {{ parameters['language'] |safe }}
- default = "{{ parameters['default_language'] }}"
+ choices = {{ data.language |safe }}
+ {% endif %}
- [install.admin]
- {% if parameters['tutorial'] -%}
+ {% if data.init_admin_permission -%}
+ [install.init_admin_permission]
+ {% if data.generator_mode == "tutorial" -%}
# this is a generic question - ask strings are automatically handled by YunoHost's core
- type = "user"
+ # This won't be saved as setting and will instead be used to initialize the SSOwat permission
{% endif -%}
+ type = "group"
+ default = "admins"
+ {% endif %}
- [install.password]
- {% if parameters['tutorial'] -%}
- # this is a generic question - ask strings are automatically handled by YunoHost's core
- # Note that user-provided passwords questions are not automatically saved as setting
- {% endif -%}
- help.en = "Use the help field to add an information for the admin about this question."
- help.fr = "Utilisez le champ aide pour ajouter une information à l'intention de l'administrateur à propos de cette question."
- type = "password"
[resources]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# See the packaging documentation for the full set
# of explanation regarding the behavior and properties for each of those
- {% endif -%}
+ # https://yunohost.org/packaging_apps_resources
+ {% endif %}
[resources.sources]
@@ -103,77 +95,79 @@ ram.runtime = "50M"
# This will pre-fetch the asset which can then be deployed during the install/upgrade scripts with :
# ynh_setup_source --dest_dir="$install_dir"
# You can also define other assets than "main" and add --source_id="foobar" in the previous command
- url = "{{parameters['source_url']}}"
- sha256 = "{{parameters['sha256sum']}}"
+ url = "{{data.source_url}}"
+ sha256 = "{{data.sha256sum}}"
# These infos are used by https://github.com/YunoHost/apps/blob/master/tools/autoupdate_app_sources/autoupdate_app_sources.py
# to auto-update the previous asset urls and sha256sum + manifest version
# assuming the upstream's code repo is on github and relies on tags or releases
# See the 'sources' resource documentation for more details
- {% if parameters['auto_update'] -%}
+ {% if data.auto_update -%}
autoupdate.strategy = "latest_github_tag"
{% else -%}
# autoupdate.strategy = "latest_github_tag"
- {% endif -%}
+ {% endif %}
+ {% if data.system_user -%}
[resources.system_user]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# This will provision/deprovision a unix system user
- {% endif -%}
+ {%- endif -%}
+ {%- endif %}
+ {% if data.install_dir -%}
[resources.install_dir]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# This will create/remove the install dir as /var/www/$app
# and store the corresponding setting $install_dir
- {% endif -%}
+ {%- endif -%}
+ {%- endif %}
- {% if parameters['data_dir'] %}
+ {% if data.data_dir -%}
[resources.data_dir]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# This will create/remove the data dir as /home/yunohost.app/$app
# and store the corresponding setting $data_dir
- {% endif -%}
- {% if parameters['data_subdirs'] -%}
- subdirs = {{ parameters['data_subdirs'].split(",") |safe}}
- {% endif -%}
- {% endif -%}
+ {%- endif -%}
+ {%- endif %}
[resources.permissions]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# This will configure SSOwat permission for $domain/$path/
# The initial allowed group of user is configured via the init_main_permission question (public=visitors, private=all_users)
{% endif -%}
main.url = "/"
+ {% if data.main_technology not in ['none', 'php'] -%}
[resources.ports]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# This will pick a random port for reverse-proxying and store it as the $port setting
{% endif -%}
+ {%- endif %}
- {% if parameters['dependencies'] or parameters['use_nodejs_needs_yarn'] -%}
+ {%- if data.apt_dependencies or data.use_yarn -%}
[resources.apt]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# This will automatically install/uninstall the following apt packages
# and implicitly define the $phpversion setting as 8.0 (if phpX.Y-foobar dependencies are listed)
{% endif -%}
- packages = "{{ parameters['dependencies'] }} {% if parameters['use_db'] != 'false' -%} {{ parameters['use_db'] }} {% endif -%} {% if parameters['use_python'] -%} python3-venv {% endif -%}"
- {% endif -%}
+ packages = "{{ data.apt_dependencies }} {% if data.database == 'mysql' -%} mariadb-server {% elif data.database == 'postgresql' %} postgresql {% endif -%} {% if data.main_technology == 'python' -%} python3 python3-venv {% endif -%}"
+ {%- endif %}
- {% if parameters['tutorial'] -%}
- {% if parameters['use_nodejs_needs_yarn'] -%}
+ {%- if data.use_nodejs_needs_yarn -%}
+ {% if data.generator_mode == "tutorial" -%}
# This will configure an extra repository to install yarn dependency
+ {% endif -%}
extras.yarn.repo = "deb https://dl.yarnpkg.com/debian/ stable main"
extras.yarn.key = "https://dl.yarnpkg.com/debian/pubkey.gpg"
extras.yarn.packages = "yarn"
- {% endif -%}
- {% endif -%}
+ {%- endif %}
- {% if parameters['use_db'] != 'false' -%}
+ {%- if data.database != 'false' -%}
[resources.database]
- {% if parameters['tutorial'] -%}
+ {% if data.generator_mode == "tutorial" -%}
# This will automatically provision/deprovison a database and store the corresponding credentials in settings $db_user, $db_name, $db_pwd
- {% endif -%}
- type = "{{ parameters['use_db'] }}"
{% endif -%}
-
+ type = "{{ data.database }}"
+ {%- endif -%}
diff --git a/tools/app_generator/templates/nginx.j2 b/tools/app_generator/templates/nginx.j2
new file mode 100644
index 00000000..66124e28
--- /dev/null
+++ b/tools/app_generator/templates/nginx.j2
@@ -0,0 +1,35 @@
+#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent;
+location __PATH__/ {
+
+{% if data.main_technology in ["none", "php"] %}
+ # Path to source
+ alias __INSTALL_DIR__/;
+{% endif %}
+
+ client_max_body_size 10M;
+
+{% if data.main_technology == "php" %}
+ try_files $uri $uri/ index.php;
+ 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;
+ }
+{% elif data.main_technology not in ["php", "none"] %}
+ proxy_pass http://127.0.0.1:__PORT__;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "Upgrade";
+
+ # preserve client IP
+ proxy_set_header X-Forwarded-For $remote_addr;
+{% endif %}
+
+ # Include SSOWAT user panel's shortcut tile.
+ include conf.d/yunohost_panel.conf.inc;
+}
diff --git a/tools/app_generator/templates/remove.j2 b/tools/app_generator/templates/remove.j2
index c9cd966c..82c42369 100644
--- a/tools/app_generator/templates/remove.j2
+++ b/tools/app_generator/templates/remove.j2
@@ -1,9 +1,10 @@
#!/bin/bash
-#### App file generated with YoloGen, the YunoHost app generator, version {{ parameters['GENERATOR_VERSION'] }}.
-{% if parameters["tutorial"] -%} # This is the tutorial version of the app.
+
+{% if data.generator_mode == 'tutorial' -%} # This is the tutorial version of the app.
# It contains extra commands to explain what should be done in case you want to adjust some part of the script.
# Once you are done, you may remove them.
-{% endif -%}
+{% endif %}
+
#=================================================
# GENERIC START
#=================================================
@@ -12,7 +13,7 @@
source _common.sh
source /usr/share/yunohost/helpers
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# Settings are automatically loaded as bash variables
# in every app script context, therefore typically these will exist:
# - $domain
@@ -25,50 +26,48 @@ source /usr/share/yunohost/helpers
# For remove operations :
# - the core will deprovision every resource defined in the manifest **after** this script is ran
# this includes removing the install directory, and data directory (if --purge was used)
-{% endif -%}
+{% endif %}
#=================================================
# REMOVE SYSTEM CONFIGURATIONS
#=================================================
# REMOVE SYSTEMD SERVICE
#=================================================
-ynh_script_progression --message="Removing system configurations related to $app..." --weight=1
+ynh_script_progression --message="Removing system configurations related to $app..."
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# This should be a symetric version of what happens in the install script
-{% endif -%}
+{% endif %}
-{% if parameters["use_systemd_service"] -%}
+{% if data.main_technology not in ["php", "none"] -%}
# Remove the service from the list of services known by YunoHost (added from `yunohost service add`)
if ynh_exec_warn_less yunohost service status $app >/dev/null
then
- ynh_script_progression --message="Removing $app service integration..." --weight=1
+ ynh_script_progression --message="Removing $app service integration..."
yunohost service remove $app
fi
ynh_remove_systemd_config
-{% endif -%}
+{% endif %}
ynh_remove_nginx_config
-{% if parameters["use_php"] -%}
+{% if data.main_technology == "php" -%}
ynh_remove_fpm_config
-{% endif -%}
+{% endif %}
-{% if parameters["use_logrotate"] -%}
+{% if data.use_logrotate -%}
ynh_remove_logrotate
-{% endif -%}
+{% endif %}
-{% if parameters["use_fail2ban"] -%}
+{% if data.use_fail2ban -%}
ynh_remove_fail2ban_config
-{% endif -%}
+{% endif %}
# Remove other various files specific to the app... such as :
-{% if parameters["use_cron"] -%}
+{% if data.use_cron -%}
ynh_secure_remove --file="/etc/cron.d/$app"
-{% endif -%}
-
-ynh_secure_remove --file="/etc/$app"
+{% endif %}
ynh_secure_remove --file="/var/log/$app"
diff --git a/tools/app_generator/templates/restore.j2 b/tools/app_generator/templates/restore.j2
index 5ecef1f1..b039e8b1 100644
--- a/tools/app_generator/templates/restore.j2
+++ b/tools/app_generator/templates/restore.j2
@@ -1,9 +1,10 @@
#!/bin/bash
-#### App file generated with YoloGen, the YunoHost app generator, version {{ parameters['GENERATOR_VERSION'] }}.
-{% if parameters["tutorial"] -%} # This is the tutorial version of the app.
+
+{% if data.generator_mode == 'tutorial' -%} # This is the tutorial version of the app.
# It contains extra commands to explain what should be done in case you want to adjust some part of the script.
# Once you are done, you may remove them.
-{% endif -%}
+{% endif %}
+
#=================================================
# GENERIC START
#=================================================
@@ -14,6 +15,7 @@
source ../settings/scripts/_common.sh
source /usr/share/yunohost/helpers
+{% if data.install_dir %}
#=================================================
# RESTORE THE APP MAIN DIR
#=================================================
@@ -21,14 +23,15 @@ ynh_script_progression --message="Restoring the app main directory..." --weight=
ynh_restore_file --origin_path="$install_dir"
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# $install_dir will automatically be initialized with some decent
# permission by default ... however, you may need to recursively reapply
# ownership to all files such as after the ynh_setup_source step
-{% endif -%}
+{% endif %}
chown -R $app:www-data "$install_dir"
+{% endif %}
-{% if parameters["data_dir"] -%}
+{% if data.data_dir -%}
#=================================================
# RESTORE THE DATA DIRECTORY
#=================================================
@@ -38,73 +41,72 @@ ynh_restore_file --origin_path="$data_dir" --not_mandatory
# (Same as for install dir)
chown -R $app:www-data "$data_dir"
-{% endif -%}
+{% endif %}
-{% if parameters["use_db"] -%}
+{% if data.database -%}
#=================================================
# RESTORE THE MYSQL DATABASE
#=================================================
- {% if parameters["use_db"] == 'mysql' -%}
+{% if data.datase == 'mysql' -%}
ynh_script_progression --message="Restoring the MySQL database..." --weight=1
ynh_mysql_connect_as --user=$db_user --password=$db_pwd --database=$db_name < ./db.sql
- {% endif -%}
+{% endif %}
- {% if parameters["use_db"] == 'postgresql' -%}
+{% if data.database == 'postgresql' -%}
ynh_script_progression --message="Restoring the PostgreSQL database..." --weight=1
ynh_psql_connect_as --user=$db_user --password=$db_pwd --database=$db_name < ./db.sql
- {% endif -%}
-{% endif -%}
+{% endif %}
+{% endif %}
+
#=================================================
# RESTORE SYSTEM CONFIGURATIONS
#=================================================
-# RESTORE THE PHP-FPM CONFIGURATION
-#=================================================
ynh_script_progression --message="Restoring system configurations related to $app..." --weight=1
# This should be a symetric version of what happens in the install script
-{% if parameters["use_php"] -%}
+{% if data.main_technology == "php" -%}
ynh_restore_file --origin_path="/etc/php/$phpversion/fpm/pool.d/$app.conf"
-{% endif -%}
+{% endif %}
ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
-{% if parameters["use_systemd_service"] -%}
+{% if data.main_technology not in ["php", "none"] -%}
ynh_restore_file --origin_path="/etc/systemd/system/$app.service"
systemctl enable $app.service --quiet
-yunohost service add $app --description="{{ parameters['systemd_service_description'] }}" --log="/var/log/$app/$app.log"
-{% endif -%}
+yunohost service add $app --log="/var/log/$app/$app.log"
+{% endif %}
-{% if parameters["use_logrotate"] -%}
+{% if data.use_logrotate -%}
ynh_restore_file --origin_path="/etc/logrotate.d/$app"
-{% endif -%}
-{% if parameters["use_fail2ban"] -%}
+{% endif %}
+
+{% if data.use_fail2ban -%}
ynh_restore_file --origin_path="/etc/fail2ban/jail.d/$app.conf"
ynh_restore_file --origin_path="/etc/fail2ban/filter.d/$app.conf"
ynh_systemd_action --action=restart --service_name=fail2ban
-{% endif -%}
+{% endif %}
+
# Other various files...
-
+{% if data.use_cron -%}
ynh_restore_file --origin_path="/etc/cron.d/$app"
-ynh_restore_file --origin_path="/etc/$app/"
+{% endif %}
-#=================================================
-# GENERIC FINALIZATION
#=================================================
# RELOAD NGINX AND PHP-FPM OR THE APP SERVICE
#=================================================
ynh_script_progression --message="Reloading NGINX web server and $app's service..." --weight=1
# Typically you only have either $app or php-fpm but not both at the same time...
-{% if parameters["use_systemd_service"] -%}
+{% if data.main_technology not in ["php", "none"] -%}
ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log"
-{% endif -%}
-{% if parameters["use_php"] -%}
+{% endif %}
+{% if data.main_technology == "php" -%}
ynh_systemd_action --service_name=php$phpversion-fpm --action=reload
-{% endif -%}
+{% endif %}
ynh_systemd_action --service_name=nginx --action=reload
diff --git a/tools/app_generator/templates/systemd.j2 b/tools/app_generator/templates/systemd.j2
new file mode 100644
index 00000000..ff53a24d
--- /dev/null
+++ b/tools/app_generator/templates/systemd.j2
@@ -0,0 +1,54 @@
+[Unit]
+Description=Service for {{ data.app_name }} (__APP__)
+After=network.target
+
+[Service]
+Type=simple
+User=__APP__
+Group=__APP__
+{% if data.custom_config_file == ".env" %}
+EnvironmentFile=__INSTALL_DIR__/.env
+{% endif %}
+WorkingDirectory=__INSTALL_DIR__/
+ExecStart={{ data.systemd_execstart }}
+StandardOutput=append:/var/log/__APP__/__APP__.log
+StandardError=inherit
+Restart=on-failure
+RestartSec=10
+
+# Sandboxing options to harden security
+# Depending on specificities of your service/app, you may need to tweak these
+# .. but this should be a good baseline
+# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
+NoNewPrivileges=yes
+PrivateTmp=yes
+PrivateDevices=yes
+RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
+RestrictNamespaces=yes
+RestrictRealtime=yes
+DevicePolicy=closed
+ProtectClock=yes
+ProtectHostname=yes
+ProtectProc=invisible
+ProtectSystem=full
+ProtectControlGroups=yes
+ProtectKernelModules=yes
+ProtectKernelTunables=yes
+LockPersonality=yes
+SystemCallArchitectures=native
+SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap @cpu-emulation @privileged
+
+# Denying access to capabilities that should not be relevant for webapps
+# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html
+CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD
+CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE
+CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT
+CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK
+CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM
+CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
+CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE
+CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW
+CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG
+
+[Install]
+WantedBy=multi-user.target
diff --git a/tools/app_generator/templates/upgrade.j2 b/tools/app_generator/templates/upgrade.j2
index 4e001ca1..8802ab42 100644
--- a/tools/app_generator/templates/upgrade.j2
+++ b/tools/app_generator/templates/upgrade.j2
@@ -1,9 +1,10 @@
#!/bin/bash
-#### App file generated with YoloGen, the YunoHost app generator, version {{ parameters['GENERATOR_VERSION'] }}.
-{% if parameters["tutorial"] -%} # This is the tutorial version of the app.
+
+{% if data.generator_mode == 'tutorial' -%} # This is the tutorial version of the app.
# It contains extra commands to explain what should be done in case you want to adjust some part of the script.
# Once you are done, you may remove them.
-{% endif -%}
+{% endif %}
+
#=================================================
# GENERIC START
#=================================================
@@ -13,7 +14,7 @@
source _common.sh
source /usr/share/yunohost/helpers
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# Settings are automatically loaded as bash variables
# in every app script context, therefore typically these will exist:
# - $domain
@@ -33,7 +34,7 @@ source /usr/share/yunohost/helpers
### - UPGRADE_PACKAGE if only the YunoHost package has changed
### ynh_check_app_version_changed will stop the upgrade if the app is up to date.
### UPGRADE_APP should be used to upgrade the core app only if there's an upgrade to do.
-{% endif -%}
+{% endif %}
upgrade_type=$(ynh_check_app_version_changed)
#=================================================
@@ -41,8 +42,8 @@ upgrade_type=$(ynh_check_app_version_changed)
#=================================================
# ENSURE DOWNWARD COMPATIBILITY
#=================================================
-{% if parameters["tutorial"] -%}
-#ynh_script_progression --message="Ensuring downward compatibility..." --weight=1
+{% if data.generator_mode == 'tutorial' -%}
+#ynh_script_progression --message="Ensuring downward compatibility..."
#
# N.B. : the followings setting migrations snippets are provided as *EXAMPLES*
@@ -51,26 +52,27 @@ upgrade_type=$(ynh_check_app_version_changed)
#
# If db_name doesn't exist, create it
-#if [ -z "$db_name" ]; then
+#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 install_dir doesn't exist, create it
-#if [ -z "$install_dir" ]; then
+#if [ -z "${install_dir:-}" ]; then
# install_dir=/var/www/$app
# ynh_app_setting_set --app=$app --key=install_dir --value=$install_dir
#fi
-{% endif -%}
+{% endif %}
-{% if parameters["use_systemd_service"] -%}
+{% if data.main_technology not in ["php", "none"] -%}
#=================================================
# STOP SYSTEMD SERVICE
#=================================================
-ynh_script_progression --message="Stopping a systemd service..." --weight=1
+ynh_script_progression --message="Stopping a systemd service..."
ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app/$app.log"
-{% endif -%}
+{% endif %}
+
#=================================================
# "REBUILD" THE APP (DEPLOY NEW SOURCES, RERUN NPM BUILD...)
#=================================================
@@ -79,100 +81,98 @@ ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app
if [ "$upgrade_type" == "UPGRADE_APP" ]
then
- ynh_script_progression --message="Upgrading source files..." --weight=1
+ ynh_script_progression --message="Upgrading source files..."
# Download, check integrity, uncompress and patch the source from app.src
ynh_setup_source --dest_dir="$install_dir"
fi
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# $install_dir will automatically be initialized with some decent
# permission by default ... however, you may need to recursively reapply
# ownership to all files such as after the ynh_setup_source step
-{% endif -%}
+{% endif %}
chown -R $app:www-data "$install_dir"
#=================================================
# REAPPLY SYSTEM CONFIGURATIONS
#=================================================
-ynh_script_progression --message="Upgrading system configurations related to $app..." --weight=1
+ynh_script_progression --message="Upgrading system configurations related to $app..."
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# This should be a literal copypasta of what happened in the install's "System configuration" section
-{% endif -%}
+{% endif %}
-{% if parameters["use_php"] -%}
+{% if data.main_technology == "php" -%}
ynh_add_fpm_config
-{% endif -%}
+{% endif %}
ynh_add_nginx_config
-{% if parameters["use_systemd_service"] -%}
+{% if data.main_technology not in ["php", "none"] -%}
ynh_add_systemd_config
-yunohost service add $app --description="{{ parameters['systemd_service_description'] }}" --log="/var/log/$app/$app.log"
-{% endif -%}
+yunohost service add $app --log="/var/log/$app/$app.log"
+{% endif %}
-{% if parameters["use_logrotate"] -%}
+{% if data.use_logrotate -%}
ynh_use_logrotate --non-append
-{% endif -%}
+{% endif %}
-{% if parameters["use_fail2ban"] -%}
+{% if data.use_fail2ban -%}
# Create a dedicated Fail2Ban config
-ynh_add_fail2ban_config --logpath="/var/log/nginx/${domain}-error.log" --failregex="{{ parameters['fail2ban_regex'] }}"
-{% endif -%}
+ynh_add_fail2ban_config --logpath="/var/log/nginx/${domain}-error.log" --failregex="{{ data.fail2ban_regex }}"
+{% endif %}
-{% if parameters["use_cron"] -%}
-#=================================================
-# UPDATE THE CRON JOB
-#=================================================
+{% if data.use_cron -%}
cron_path="/etc/cron.d/$app"
ynh_add_config --template="../conf/task.cron" --destination="$cron_path"
chown root: "$cron_path"
chmod 644 "$cron_path"
-{% endif -%}
+{% endif %}
#=================================================
# RECONFIGURE THE APP (UPDATE CONF, APPLY MIGRATIONS...)
#=================================================
# UPDATE A CONFIG FILE
#=================================================
-ynh_script_progression --message="Updating a configuration file..." --weight=1
+ynh_script_progression --message="Updating a configuration file..."
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
### 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)
-{% endif -%}
+{% endif %}
-ynh_add_config --template="{{ parameters['custom_config_file'] }}" --destination="$install_dir/{{ parameters['custom_config_file'] }}"
+ynh_add_config --template="{{ data.custom_config_file }}" --destination="$install_dir/{{ data.custom_config_file }}"
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
# 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
-{% endif -%}
+{% endif %}
chmod 400 "$install_dir/some_config_file"
chown $app:$app "$install_dir/some_config_file"
-{% if parameters["tutorial"] -%}
+{% if data.generator_mode == 'tutorial' -%}
### 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="$install_dir/some_config_file"
### ynh_store_file_checksum --file="$install_dir/some_config_file"
-{% endif -%}
+{% endif %}
-{% if parameters["use_systemd_service"] -%}
+{% if data.main_technology not in ["php", "none"] -%}
#=================================================
# START SYSTEMD SERVICE
#=================================================
-ynh_script_progression --message="Starting a systemd service..." --weight=1
+ynh_script_progression --message="Starting a systemd service..."
ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log"
-{% endif -%}
+{% endif %}
+
#=================================================
# END OF SCRIPT
#=================================================