From c5934fdf88939fe79100ec31cc282de380ad11b7 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Fri, 11 Mar 2022 00:23:07 +0100 Subject: [PATCH 1/3] Apply last example_ynh --- check_process | 6 +- conf/nginx.conf | 1 + conf/systemd.service | 10 +-- doc/.gitkeep | 0 doc/DESCRIPTION.md | 1 + doc/DISCLAIMER.md | 0 doc/screenshots/.gitkeep | 0 doc/screenshots/jupyterlab.png | Bin 0 -> 71284 bytes manifest.json | 21 +++--- scripts/backup | 2 +- scripts/change_url | 16 +++-- scripts/install | 79 +++++++++------------- scripts/remove | 28 +++----- scripts/restore | 35 +++------- scripts/upgrade | 120 ++++++++++++++------------------- 15 files changed, 134 insertions(+), 185 deletions(-) create mode 100644 doc/.gitkeep create mode 100644 doc/DESCRIPTION.md create mode 100644 doc/DISCLAIMER.md create mode 100644 doc/screenshots/.gitkeep create mode 100644 doc/screenshots/jupyterlab.png diff --git a/check_process b/check_process index c42f668..ce98261 100644 --- a/check_process +++ b/check_process @@ -2,8 +2,8 @@ ; Manifest domain="domain.tld" path="/jupyterlab" - admin="john" is_public=1 + admin="john" ; Checks pkg_linter=1 setup_sub_dir=1 @@ -12,9 +12,11 @@ setup_private=1 setup_public=1 upgrade=1 + # 3.0.16~ynh1 + upgrade=1 from_commit=197dca5095e29abe8d4a560a5a2ba2984045c989 backup_restore=1 multi_instance=1 - port_already_use=1 + port_already_use=0 change_url=1 ;;; Options Email= diff --git a/conf/nginx.conf b/conf/nginx.conf index 4d70d5a..4de7a6a 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,3 +1,4 @@ +#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; location __PATH__/ { proxy_pass http://localhost:__PORT__; proxy_redirect off; diff --git a/conf/systemd.service b/conf/systemd.service index c10f8f0..a6c56ff 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -3,13 +3,15 @@ Description=JupyterLab After=syslog.target network.target [Service] +Type=simple +User=root +WorkingDirectory=__FINALPATH__/ Environment="LC_ALL=C.UTF-8" Environment="LANG=C.UTF-8" -Environment="PATH=__NODE_PATH__:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -ExecStart=/usr/local/bin/pipenv run jupyterhub -f __FINALPATH__/config/jupyterhub_config.py +Environment="__YNH_NODE_LOAD_PATH__:__FINALPATH__/.venv/bin" +ExecStart=__FINALPATH__/.venv/bin/jupyterhub -f __FINALPATH__/config/jupyterhub_config.py --upgrade-db Restart=always RestartSec=10 -WorkingDirectory=__FINALPATH__ [Install] -WantedBy=multi-user.target \ No newline at end of file +WantedBy=multi-user.target diff --git a/doc/.gitkeep b/doc/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md new file mode 100644 index 0000000..5572589 --- /dev/null +++ b/doc/DESCRIPTION.md @@ -0,0 +1 @@ +JupyterLab is the next-generation user interface for Project Jupyter offering all the familiar building blocks of the classic Jupyter Notebook (notebook, terminal, text editor, file browser, rich outputs, etc.) in a flexible and powerful user interface. JupyterLab will eventually replace the classic Jupyter Notebook. diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/screenshots/.gitkeep b/doc/screenshots/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/screenshots/jupyterlab.png b/doc/screenshots/jupyterlab.png new file mode 100644 index 0000000000000000000000000000000000000000..54dac357147fc7addeb9ecf41bc336f82eb30d98 GIT binary patch literal 71284 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

tVW%G_PjVnk8-1f{EW!NbHb_XwZU+lg(t0%S80- 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 4.1.7" + "yunohost": ">= 4.3.0" }, "multi_instance": true, "services": [ @@ -24,8 +31,7 @@ "install": [ { "name": "domain", - "type": "domain", - "example": "example.com" + "type": "domain" }, { "name": "path", @@ -33,16 +39,15 @@ "example": "/jupyterlab", "default": "/jupyterlab" }, - { - "name": "admin", - "type": "user", - "example": "johndoe" - }, { "name": "is_public", "type": "boolean", "default": true }, + { + "name": "admin", + "type": "user" + }, { "name": "enable_terminal", "type": "boolean", diff --git a/scripts/backup b/scripts/backup index 2938068..d72c557 100644 --- a/scripts/backup +++ b/scripts/backup @@ -6,7 +6,7 @@ # IMPORT GENERIC HELPERS #================================================= -#Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers diff --git a/scripts/change_url b/scripts/change_url index df385d7..e26ce2d 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -24,23 +24,26 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." +ynh_script_progression --message="Loading installation settings..." # Needed for helper "ynh_add_nginx_config" final_path=$(ynh_app_setting_get --app=$app --key=final_path) + +# Add settings here as needed by your application port=$(ynh_app_setting_get --app=$app --key=port) port_hub=$(ynh_app_setting_get --app=$app --key=port_hub) port_http_proxy=$(ynh_app_setting_get --app=$app --key=port_http_proxy) admin=$(ynh_app_setting_get --app=$app --key=admin) #================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +# BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP #================================================= ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --weight=1 # Backup the current version of the app ynh_backup_before_upgrade ynh_clean_setup () { + ynh_clean_check_starting # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" @@ -71,14 +74,14 @@ fi #================================================= # STOP SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Stopping a systemd service..." +ynh_script_progression --message="Stopping a systemd service..." ynh_systemd_action --service_name=$app --action="stop" #================================================= # MODIFY URL IN NGINX CONF #================================================= -ynh_script_progression --message="Updating NGINX web server configuration..." +ynh_script_progression --message="Updating NGINX web server configuration..." nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf @@ -120,14 +123,15 @@ ynh_add_config --template="../conf/jupyterhub_config.py" --destination="$final_p #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." +ynh_script_progression --message="Starting a systemd service..." +# Start a systemd service ynh_systemd_action --service_name=$app --action="start" --line_match="JupyterHub is now running at" --log_path="systemd" #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." +ynh_script_progression --message="Reloading NGINX web server..." ynh_systemd_action --service_name=nginx --action=reload diff --git a/scripts/install b/scripts/install index 290fff2..7e63872 100644 --- a/scripts/install +++ b/scripts/install @@ -59,13 +59,14 @@ ynh_app_setting_set --app=$app --key=enable_terminal --value=$enable_terminal #================================================= ynh_script_progression --message="Finding an available port..." --weight=1 -# Find a free port +# Find an available port port=$(ynh_find_port --port=8080) -port_hub=$(ynh_find_port --port=$(($port + 1))) -port_http_proxy=$(ynh_find_port --port=$(($port_hub + 1))) - ynh_app_setting_set --app=$app --key=port --value=$port + +port_hub=$(ynh_find_port --port=$(($port + 1))) ynh_app_setting_set --app=$app --key=port_hub --value=$port_hub + +port_http_proxy=$(ynh_find_port --port=$(($port_hub + 1))) ynh_app_setting_set --app=$app --key=port_http_proxy --value=$port_http_proxy #================================================= @@ -74,83 +75,65 @@ ynh_app_setting_set --app=$app --key=port_http_proxy --value=$port_http_proxy ynh_script_progression --message="Installing dependencies..." --weight=23 ynh_install_app_dependencies $pkg_dependencies - ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$nodejs_version - +ynh_use_nodejs +$ynh_npm install -g configurable-http-proxy python3 -m pip install pipenv -npm install -g configurable-http-proxy - -#================================================= -# DOWNLOAD, CHECK AND UNPACK SOURCE -#================================================= -ynh_script_progression --message="Setting up source files..." --weight=64 - -ynh_app_setting_set --app=$app --key=final_path --value=$final_path - -mkdir -p $final_path - -pushd $final_path - -PIPENV_VENV_IN_PROJECT="enabled" PIPENV_SKIP_LOCK=true ynh_exec_warn_less python3 -m pipenv install jupyterlab==$jupyterlab_version jupyterhub notebook jupyterhub-ldapauthenticator pyzmq --three - -popd - #================================================= # NGINX CONFIGURATION #================================================= ynh_script_progression --message="Configuring NGINX web server..." --weight=1 -# Create a dedicated nginx config +# Create a dedicated NGINX config ynh_add_nginx_config -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Configuring system user..." --weight=1 - -# Create a system user -ynh_system_user_create --username=$app - #================================================= # SPECIFIC SETUP #================================================= -# SETUP SYSTEMD +# BUILD APP #================================================= -ynh_script_progression --message="Configuring a systemd service..." --weight=3 +ynh_script_progression --message="Building app..." -# Create a dedicated systemd config -ynh_replace_string --match_string="__NODE_PATH__" --replace_string="$nodejs_path" --target_file="../conf/systemd.service" +ynh_app_setting_set --app=$app --key=final_path --value=$final_path +mkdir -p "$final_path" -ynh_add_systemd_config +pushd $final_path + + PIPENV_VENV_IN_PROJECT="enabled" PIPENV_SKIP_LOCK=true ynh_exec_warn_less python3 -m pipenv install jupyterlab==$jupyterlab_version jupyterhub notebook jupyterhub-ldapauthenticator pyzmq --three +popd #================================================= -# MODIFY A CONFIG FILE +# ADD A CONFIGURATION #================================================= +ynh_script_progression --message="Adding a configuration file..." mkdir -p "$final_path/config" path=${path_url%/} ynh_add_config --template="../conf/jupyterhub_config.py" --destination="$final_path/config/jupyterhub_config.py" - ynh_add_config --template="../conf/jupyter_notebook_config.py" --destination="$final_path/config/jupyter_notebook_config.py" -#================================================= -# GENERIC FINALIZATION -#================================================= -# SECURE FILES AND DIRECTORIES -#================================================= - -# Set permissions to app files chown -R root: $final_path/ chown -R $admin: $final_path/.venv/ #================================================= -# ADVERTISE SERVICE IN ADMIN PANEL +# SETUP SYSTEMD #================================================= +ynh_script_progression --message="Configuring a systemd service..." --weight=3 -yunohost service add $app --description="$app daemon" --log="$app" +# Create a dedicated systemd config +ynh_add_systemd_config + +#================================================= +# GENERIC FINALIZATION +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." + +yunohost service add $app --description="$app daemon" #================================================= # START SYSTEMD SERVICE diff --git a/scripts/remove b/scripts/remove index 2fc6809..a4d5e6e 100644 --- a/scripts/remove +++ b/scripts/remove @@ -17,21 +17,18 @@ ynh_script_progression --message="Loading installation settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get --app=$app --key=domain) -port=$(ynh_app_setting_get --app=$app --key=port) -port_hub=$(ynh_app_setting_get --app=$app --key=port_hub) -port_http_proxy=$(ynh_app_setting_get --app=$app --key=port_http_proxy) final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= # STANDARD REMOVE #================================================= -# REMOVE SERVICE FROM ADMIN PANEL +# REMOVE SERVICE INTEGRATION IN YUNOHOST #================================================= -# Remove a service from the admin panel, added by `yunohost service add` +# 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..." --weight=2 + ynh_script_progression --message="Removing $app service integration..."--weight=2 yunohost service remove $app fi @@ -43,16 +40,6 @@ ynh_script_progression --message="Stopping and removing the systemd service..." # Remove the dedicated systemd config ynh_remove_systemd_config -#================================================= -# REMOVE DEPENDENCIES -#================================================= -ynh_script_progression --message="Removing dependencies..." --weight=4 - -# Remove metapackage and its dependencies -ynh_remove_app_dependencies - -ynh_remove_nodejs - #================================================= # REMOVE APP MAIN DIR #================================================= @@ -70,12 +57,13 @@ ynh_script_progression --message="Removing NGINX web server configuration..." -- ynh_remove_nginx_config #================================================= -# REMOVE DEDICATED USER +# REMOVE DEPENDENCIES #================================================= -ynh_script_progression --message="Removing the dedicated system user..." --weight=1 +ynh_script_progression --message="Removing dependencies..." --weight=4 -# Delete a system user -ynh_system_user_delete --username=$app +# Remove metapackage and its dependencies +ynh_remove_app_dependencies +ynh_remove_nodejs #================================================= # END OF SCRIPT diff --git a/scripts/restore b/scripts/restore index 5dc2da6..c2ff4d9 100644 --- a/scripts/restore +++ b/scripts/restore @@ -6,7 +6,7 @@ # IMPORT GENERIC HELPERS #================================================= -#Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers @@ -23,22 +23,20 @@ ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading settings..." --weight=1 +ynh_script_progression --message="Loading installation settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME -admin=$(ynh_app_setting_get --app=$app --key=admin) domain=$(ynh_app_setting_get --app=$app --key=domain) path_url=$(ynh_app_setting_get --app=$app --key=path) final_path=$(ynh_app_setting_get --app=$app --key=final_path) +admin=$(ynh_app_setting_get --app=$app --key=admin) #================================================= # CHECK IF THE APP CAN BE RESTORED #================================================= ynh_script_progression --message="Validating restoration parameters..." --weight=1 -ynh_webpath_available --domain=$domain --path_url=$path_url \ - || ynh_die --message="Path not available: ${domain}${path_url}" test ! -d $final_path \ || ynh_die --message="There is already a directory: $final_path " @@ -47,6 +45,7 @@ test ! -d $final_path \ #================================================= # RESTORE THE NGINX CONFIGURATION #================================================= +ynh_script_progression --message="Restoring the NGINX web server configuration..." ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" @@ -57,19 +56,6 @@ ynh_script_progression --message="Restoring the app main directory..." --weight= ynh_restore_file --origin_path="$final_path" -#================================================= -# RECREATE THE DEDICATED USER -#================================================= -ynh_script_progression --message="Recreating the dedicated system user..." --weight=1 - -# Create the dedicated user (if not existing) -ynh_system_user_create --username=$app - -#================================================= -# RESTORE USER RIGHTS -#================================================= - -# Restore permissions on app files chown -R root: $final_path/ chown -R $admin: $final_path/.venv/ @@ -82,13 +68,11 @@ ynh_script_progression --message="Reinstalling dependencies..." --weight=75 # Define and install dependencies ynh_install_app_dependencies $pkg_dependencies - ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$nodejs_version - +ynh_use_nodejs +$ynh_npm install -g configurable-http-proxy python3 -m pip install pipenv -npm install -g configurable-http-proxy - #================================================= # RESTORE SYSTEMD #================================================= @@ -98,17 +82,18 @@ ynh_restore_file --origin_path="/etc/systemd/system/$app.service" systemctl enable $app.service --quiet #================================================= -# ADVERTISE SERVICE IN ADMIN PANEL +# INTEGRATE SERVICE IN YUNOHOST #================================================= +ynh_script_progression --message="Integrating service in YunoHost..." -yunohost service add $app --description="$app daemon" --log="$app" +yunohost service add $app --description="$app daemon" #================================================= # START SYSTEMD SERVICE #================================================= ynh_script_progression --message="Starting a systemd service..." --weight=5 -ynh_systemd_action --service_name=$app --action=start --line_match="JupyterHub is now running at" --log_path="systemd" +ynh_systemd_action --service_name=$app --action="start" --line_match="JupyterHub is now running at" --log_path="systemd" #================================================= # GENERIC FINALIZATION diff --git a/scripts/upgrade b/scripts/upgrade index 5633efb..e34fec2 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -28,9 +28,34 @@ enable_terminal=$(ynh_app_setting_get --app=$app --key=enable_terminal) #================================================= # CHECK VERSION #================================================= +ynh_script_progression --message="Checking version..." upgrade_type=$(ynh_check_app_version_changed) +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=48 + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + ynh_clean_check_starting + # Restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# STOP SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Stopping a systemd service..." --weight=2 + +ynh_systemd_action --service_name=$app --action="stop" + #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= @@ -52,86 +77,45 @@ if ynh_legacy_permissions_exists; then ynh_app_setting_delete --app=$app --key=is_public fi -#================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP -#================================================= -ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=48 - -# Backup the current version of the app -ynh_backup_before_upgrade -ynh_clean_setup () { - ynh_clean_check_starting - - # restore it if the upgrade fails - ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# STANDARD UPGRADE STEPS -#================================================= -# STOP SYSTEMD SERVICE -#================================================= -ynh_script_progression --message="Stopping a systemd service..." --weight=2 - -ynh_systemd_action --service_name=$app --action="stop" - #================================================= # NGINX CONFIGURATION #================================================= ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 -# Create a dedicated nginx config +# Create a dedicated NGINX config ynh_add_nginx_config -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1 - -# Create a dedicated user (if not existing) -ynh_system_user_create --username=$app - #================================================= # UPGRADE DEPENDENCIES #================================================= ynh_script_progression --message="Upgrading dependencies..." --weight=83 ynh_install_app_dependencies $pkg_dependencies - ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$nodejs_version - -npm install -g configurable-http-proxy - +ynh_use_nodejs +$ynh_npm install -g configurable-http-proxy python3 -m pip install pipenv -#================================================= -# DOWNLOAD, CHECK AND UNPACK SOURCE -#================================================= - -if [ "$upgrade_type" == "UPGRADE_APP" ] -then - ynh_script_progression --message="Upgrading source files..." --weight=160 - - # Download, check integrity, uncompress and patch the source from app.src - mkdir -p $final_path - - pushd $final_path - - PIPENV_VENV_IN_PROJECT="enabled" PIPENV_SKIP_LOCK=true ynh_exec_warn_less python3 -m pipenv install jupyterlab==$jupyterlab_version jupyterhub notebook jupyterhub-ldapauthenticator pyzmq - - ynh_exec_warn_less python3 -m pipenv run jupyterhub upgrade-db - - popd -fi - #================================================= # SPECIFIC UPGRADE #================================================= -# STORE THE CONFIG FILE CHECKSUM +# BUILD APP #================================================= +if [ "$upgrade_type" == "UPGRADE_APP" ] +then + ynh_script_progression --message="Building app..." --weight=160 + + pushd $final_path + PIPENV_VENV_IN_PROJECT="enabled" PIPENV_SKIP_LOCK=true ynh_exec_warn_less python3 -m pipenv install jupyterlab==$jupyterlab_version jupyterhub notebook jupyterhub-ldapauthenticator pyzmq + popd +fi + +#================================================= +# UPDATE A CONFIG FILE +#================================================= +ynh_script_progression --message="Updating a configuration file..." + mkdir -p "$final_path/config" path=${path_url%/} @@ -140,29 +124,23 @@ ynh_add_config --template="../conf/jupyterhub_config.py" --destination="$final_p ynh_add_config --template="../conf/jupyter_notebook_config.py" --destination="$final_path/config/jupyter_notebook_config.py" +chown -R root: $final_path/ +chown -R $admin: $final_path/.venv/ + #================================================= # SETUP SYSTEMD #================================================= ynh_script_progression --message="Upgrading systemd configuration..." # Create a dedicated systemd config -ynh_replace_string --match_string="__NODE_PATH__" --replace_string="$nodejs_path" --target_file="../conf/systemd.service" - ynh_add_systemd_config #================================================= # GENERIC FINALIZATION #================================================= -# SECURE FILES AND DIRECTORIES -#================================================= - -# Set permissions on app files -chown -R root: $final_path/ -chown -R $admin: $final_path/.venv/ - -#================================================= -# ADVERTISE SERVICE IN ADMIN PANEL +# INTEGRATE SERVICE IN YUNOHOST #================================================= +ynh_script_progression --message="Integrating service in YunoHost..." yunohost service add $app --description="$app daemon" --log="$app" @@ -171,7 +149,7 @@ yunohost service add $app --description="$app daemon" --log="$app" #================================================= ynh_script_progression --message="Starting a systemd service..." -ynh_systemd_action --service_name=$app --action=start --line_match="JupyterHub is now running at" --log_path="systemd" +ynh_systemd_action --service_name=$app --action="start" --line_match="JupyterHub is now running at" --log_path="systemd" #================================================= # RELOAD NGINX From 3f80d663041505dbc2f74993bb432294d4137e75 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Fri, 11 Mar 2022 00:23:37 +0100 Subject: [PATCH 2/3] upgrade version number --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 2575aef..020ba4c 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "en": "Code console environment for running Python code interactively.", "fr": "Console de code pour exécuter du code Python de manière interactive." }, - "version": "3.0.16~ynh1", + "version": "3.0.16~ynh2", "url": "https://jupyterlab.readthedocs.io/en/stable/", "upstream": { "license": "BSD-3-Clause", From 15e98b73278c108bfedb4630b570d3b8c541447f Mon Sep 17 00:00:00 2001 From: Yunohost-Bot <> Date: Thu, 10 Mar 2022 23:23:43 +0000 Subject: [PATCH 3/3] Auto-update README --- README.md | 59 ++++++++++++++++++++-------------------------------- README_fr.md | 57 +++++++++++++++++--------------------------------- 2 files changed, 41 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index a34bc05..5512798 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ + + # JupyterLab for YunoHost [![Integration level](https://dash.yunohost.org/integration/jupyterlab.svg)](https://dash.yunohost.org/appci/app/jupyterlab) ![](https://ci-apps.yunohost.org/ci/badges/jupyterlab.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/jupyterlab.maintain.svg) @@ -5,55 +10,33 @@ *[Lire ce readme en français.](./README_fr.md)* -> *This package allow you to install JupyterLab quickly and simply on a YunoHost server. -If you don't have YunoHost, please see [here](https://yunohost.org/install) to know how to install and enjoy it.* +> *This package allows you to install JupyterLab quickly and simply on a YunoHost server. +If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.* ## Overview + JupyterLab is the next-generation user interface for Project Jupyter offering all the familiar building blocks of the classic Jupyter Notebook (notebook, terminal, text editor, file browser, rich outputs, etc.) in a flexible and powerful user interface. JupyterLab will eventually replace the classic Jupyter Notebook. -**Shipped version:** 3.0.16 + +**Shipped version:** 3.0.16~ynh2 + +**Demo:** https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo ## Screenshots -![](https://raw.githubusercontent.com/jupyterlab/jupyterlab/3e3a2c9e295703ff6d441589423e284cc6d5c245/docs/source/images/jupyterlab.png) +![](./doc/screenshots/jupyterlab.png) -## Demo - -* [Try it on Binder](https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo) - -## Configuration - -How to configure this app: by an admin panel, a plain file with SSH. - -## Documentation - -* Official documentation: https://jupyterlab.readthedocs.io/en/stable/ -* YunoHost documentation: https://yunohost.org/en/app_jupyterlab - -## YunoHost specific features - -#### Multi-users support - -* LDAP auth supported? **Yes** -* Can the app be used by multiple users? **Yes** - -#### Supported architectures - -* x86-64 - [![Build Status](https://ci-apps.yunohost.org/ci/logs/jupyterlab.svg)](https://ci-apps.yunohost.org/ci/apps/jupyterlab/) -* ARMv8-A - [![Build Status](https://ci-apps-arm.yunohost.org/ci/logs/jupyterlab.svg)](https://ci-apps-arm.yunohost.org/ci/apps/jupyterlab/) - -## Links +## Documentation and resources +* Official app website: https://jupyterlab.readthedocs.io/en/stable/ +* Official admin documentation: https://jupyterlab.readthedocs.io/en/stable/ +* Upstream app code repository: https://github.com/jupyterhub/jupyterhub +* YunoHost documentation for this app: https://yunohost.org/app_jupyterlab * Report a bug: https://github.com/YunoHost-Apps/jupyterlab_ynh/issues -* App website: https://jupyter.org -* Upstream app repository: https://github.com/jupyterhub/jupyterhub -* YunoHost website: https://yunohost.org/ ---- +## Developer info -## Developers info - -Please do your pull request to the [testing branch](https://github.com/YunoHost-Apps/jupyterlab_ynh/tree/testing). +Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/jupyterlab_ynh/tree/testing). To try the testing branch, please proceed like that. ``` @@ -61,3 +44,5 @@ sudo yunohost app install https://github.com/YunoHost-Apps/jupyterlab_ynh/tree/t or sudo yunohost app upgrade jupyterlab -u https://github.com/YunoHost-Apps/jupyterlab_ynh/tree/testing --debug ``` + +**More info regarding app packaging:** https://yunohost.org/packaging_apps \ No newline at end of file diff --git a/README_fr.md b/README_fr.md index 78836d3..48b784a 100644 --- a/README_fr.md +++ b/README_fr.md @@ -1,55 +1,34 @@ # JupyterLab pour YunoHost -[![Integration level](https://dash.yunohost.org/integration/jupyterlab.svg)](https://dash.yunohost.org/appci/app/jupyterlab) ![](https://ci-apps.yunohost.org/ci/badges/jupyterlab.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/jupyterlab.maintain.svg) +[![Niveau d'intégration](https://dash.yunohost.org/integration/jupyterlab.svg)](https://dash.yunohost.org/appci/app/jupyterlab) ![](https://ci-apps.yunohost.org/ci/badges/jupyterlab.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/jupyterlab.maintain.svg) [![Installer JupyterLab avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=jupyterlab) -*[Read this readme in english.](./README.md)* +*[Read this readme in english.](./README.md)* +*[Lire ce readme en français.](./README_fr.md)* -> *Ce package vous permet d’installer JupyterLab rapidement et simplement sur un serveur YunoHost. -Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/install) pour savoir comment l’installer et en profiter.* +> *Ce package vous permet d'installer JupyterLab rapidement et simplement sur un serveur YunoHost. +Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* -## Vue d’ensemble -JupyterLab est une interface utilisateur de nouvelle génération pour le projet Jupyter offrant tous les modules de Jupyter Notebook (interpréteur Python, terminal, éditeur de texte, navigateur de fichiers, etc.) dans une interface utilisateur flexible et puissante. JupyterLab remplacera à terme Jupyter Notebook. +## Vue d'ensemble -**Version incluse :** 3.0.16 +JupyterLab is the next-generation user interface for Project Jupyter offering all the familiar building blocks of the classic Jupyter Notebook (notebook, terminal, text editor, file browser, rich outputs, etc.) in a flexible and powerful user interface. JupyterLab will eventually replace the classic Jupyter Notebook. -## Captures d’écran -![](https://raw.githubusercontent.com/jupyterlab/jupyterlab/3e3a2c9e295703ff6d441589423e284cc6d5c245/docs/source/images/jupyterlab.png) +**Version incluse :** 3.0.16~ynh2 -## Démo +**Démo :** https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo -* [Démo sur Binder](https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo) +## Captures d'écran -## Configuration +![](./doc/screenshots/jupyterlab.png) -Comment configurer cette application : via le panneau d'administration, un fichier brut en SSH. +## Documentations et ressources -## Documentation - -* Documentation officielle : https://jupyterlab.readthedocs.io/en/stable/ -* Documentation YunoHost : https://yunohost.org/fr/app_jupyterlab - -## Caractéristiques spécifiques YunoHost - -#### Support multi-utilisateurs - -* L’authentification LDAP est-elle prise en charge ? **Oui** -* L’application peut-elle être utilisée par plusieurs utilisateurs ? **Oui** - -#### Architectures supportées - -* x86-64 - [![Build Status](https://ci-apps.yunohost.org/ci/logs/jupyterlab.svg)](https://ci-apps.yunohost.org/ci/apps/jupyterlab/) -* ARMv8-A - [![Build Status](https://ci-apps-arm.yunohost.org/ci/logs/jupyterlab.svg)](https://ci-apps-arm.yunohost.org/ci/apps/jupyterlab/) - -## Liens - -* Signaler un bug : https://github.com/YunoHost-Apps/jupyterlab_ynh/issues -* Site de l’application : https://jupyter.org -* Dépôt de l’application principale : https://github.com/jupyterhub/jupyterhub -* Site web YunoHost : https://yunohost.org/ - ---- +* Site officiel de l'app : https://jupyterlab.readthedocs.io/en/stable/ +* Documentation officielle de l'admin : https://jupyterlab.readthedocs.io/en/stable/ +* Dépôt de code officiel de l'app : https://github.com/jupyterhub/jupyterhub +* Documentation YunoHost pour cette app : https://yunohost.org/app_jupyterlab +* Signaler un bug : https://github.com/YunoHost-Apps/jupyterlab_ynh/issues ## Informations pour les développeurs @@ -61,3 +40,5 @@ sudo yunohost app install https://github.com/YunoHost-Apps/jupyterlab_ynh/tree/t ou sudo yunohost app upgrade jupyterlab -u https://github.com/YunoHost-Apps/jupyterlab_ynh/tree/testing --debug ``` + +**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps \ No newline at end of file