diff --git a/README.md b/README.md index 34887f3..4893d77 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in 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:** 4.0.9~ynh1 +**Shipped version:** 4.1.0~ynh1 **Demo:** https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo @@ -27,39 +27,6 @@ JupyterLab is the next-generation user interface for Project Jupyter offering al ![Screenshot of JupyterLab](./doc/screenshots/jupyterlab.png) -## Disclaimers / important information - -## Updating configuration files - -Install the new version of the app with: - -```bash -sudo yunohost app install https://github.com/YunoHost-Apps/jupyterlab_ynh/tree/testing -``` - -Navigate to the installation path (`/opt/jupyterlab` by default), and run : - -```bash -pipenv shell -``` - -You are now in the virtual environment of jupyterlab. You can execute these two commands: - -- To generate the `jupyterhub_config.py` file: - -```bash -jupyterhub --generate-config -``` - -- To generate the `jupyter_notebook_config.py` file: - -```bash -jupyter notebook --generate-config -cp $HOME/.jupyter/jupyter_notebook_config.py ./ -``` - -You can now update the old template files with the new one. - ## Documentation and resources * Official app website: diff --git a/README_fr.md b/README_fr.md index 7cae254..034b658 100644 --- a/README_fr.md +++ b/README_fr.md @@ -19,7 +19,7 @@ Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) po 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. -**Version incluse :** 4.0.9~ynh1 +**Version incluse :** 4.1.0~ynh1 **Démo :** https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo @@ -27,39 +27,6 @@ JupyterLab is the next-generation user interface for Project Jupyter offering al ![Capture d’écran de JupyterLab](./doc/screenshots/jupyterlab.png) -## Avertissements / informations importantes - -## Updating configuration files - -Install the new version of the app with: - -```bash -sudo yunohost app install https://github.com/YunoHost-Apps/jupyterlab_ynh/tree/testing -``` - -Navigate to the installation path (`/opt/jupyterlab` by default), and run : - -```bash -pipenv shell -``` - -You are now in the virtual environment of jupyterlab. You can execute these two commands: - -- To generate the `jupyterhub_config.py` file: - -```bash -jupyterhub --generate-config -``` - -- To generate the `jupyter_notebook_config.py` file: - -```bash -jupyter notebook --generate-config -cp $HOME/.jupyter/jupyter_notebook_config.py ./ -``` - -You can now update the old template files with the new one. - ## Documentations et ressources * Site officiel de l’app : diff --git a/check_process b/check_process deleted file mode 100644 index ade6cd8..0000000 --- a/check_process +++ /dev/null @@ -1,27 +0,0 @@ -;; Test complet - ; Manifest - domain="domain.tld" - path="/jupyterlab" - is_public=1 - admin="john" - ; Checks - pkg_linter=1 - setup_sub_dir=1 - setup_root=1 - setup_nourl=0 - setup_private=1 - setup_public=1 - upgrade=1 - # 3.6.1~ynh2 - upgrade=1 from_commit=68367353eb4782f10fbb1e2e58832a43c72e0248 - backup_restore=1 - multi_instance=1 - port_already_use=0 - change_url=1 -;;; Options -Email= -Notification=none -;;; Upgrade options - ; commit=68367353eb4782f10fbb1e2e58832a43c72e0248 - name=3.6.1~ynh2 - manifest_arg=domain=DOMAIN&path=PATH&is_public=1&language=fr&admin=USER&password=pass&port=666& diff --git a/conf/jupyterhub_config.py b/conf/jupyterhub_config.py index 6e7330d..d6d4842 100644 --- a/conf/jupyterhub_config.py +++ b/conf/jupyterhub_config.py @@ -22,17 +22,17 @@ ## An Application for starting a Multi-User Jupyter Notebook server. ## Maximum number of concurrent servers that can be active at a time. -# +# # Setting this can limit the total resources your users can consume. -# +# # An active server is any server that's not fully stopped. It is considered # active from the time it has been requested until the time that it has # completely stopped. -# +# # If this many user servers are active, users will not be able to launch new # servers until a server is shutdown. Spawn requests will be rejected with a 429 # error asking them to try again. -# +# # If set to 0, no limit is enforced. #c.JupyterHub.active_server_limit = 0 @@ -40,15 +40,15 @@ #c.JupyterHub.active_user_window = 1800 ## Resolution (in seconds) for updating activity -# +# # If activity is registered that is less than activity_resolution seconds more # recent than the current value, the new value will be ignored. -# +# # This avoids too many writes to the Hub database. #c.JupyterHub.activity_resolution = 30 ## Grant admin users permission to access single-user servers. -# +# # Users should be properly informed if this is enabled. #c.JupyterHub.admin_access = False @@ -62,12 +62,12 @@ #c.JupyterHub.answer_yes = False ## PENDING DEPRECATION: consider using services -# +# # Dict of token:username to be loaded into the database. -# +# # Allows ahead-of-time generation of API tokens for use by externally managed # services, which authenticate as JupyterHub users. -# +# # Consider using services for general services that talk to the JupyterHub API. #c.JupyterHub.api_tokens = {} @@ -75,79 +75,79 @@ #c.JupyterHub.authenticate_prometheus = True ## Class for authenticating users. -# +# # This should be a subclass of :class:`jupyterhub.auth.Authenticator` -# +# # with an :meth:`authenticate` method that: -# +# # - is a coroutine (asyncio or tornado) # - returns username on success, None on failure # - takes two arguments: (handler, data), # where `handler` is the calling web.RequestHandler, # and `data` is the POST form data from the login page. -# +# # .. versionchanged:: 1.0 # authenticators may be registered via entry points, # e.g. `c.JupyterHub.authenticator_class = 'pam'` -# -# Currently installed: +# +# Currently installed: # - default: jupyterhub.auth.PAMAuthenticator # - pam: jupyterhub.auth.PAMAuthenticator # - dummy: jupyterhub.auth.DummyAuthenticator c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator' ## The base URL of the entire application. -# +# # Add this to the beginning of all JupyterHub URLs. Use base_url to run # JupyterHub within an existing website. -# +# # .. deprecated: 0.9 # Use JupyterHub.bind_url #c.JupyterHub.base_url = '/' ## The public facing URL of the whole JupyterHub application. -# +# # This is the address on which the proxy will bind. Sets protocol, ip, base_url -c.JupyterHub.bind_url = 'http://:__PORT____PATH__' +c.JupyterHub.bind_url = 'http://:__PORT____PATH_NO_SLASH__' ## Whether to shutdown the proxy when the Hub shuts down. -# +# # Disable if you want to be able to teardown the Hub while leaving the proxy # running. -# +# # Only valid if the proxy was starting by the Hub process. -# +# # If both this and cleanup_servers are False, sending SIGINT to the Hub will # only shutdown the Hub, leaving everything else running. -# +# # The Hub should be able to resume from database state. #c.JupyterHub.cleanup_proxy = True ## Whether to shutdown single-user servers when the Hub shuts down. -# +# # Disable if you want to be able to teardown the Hub while leaving the single- # user servers running. -# +# # If both this and cleanup_proxy are False, sending SIGINT to the Hub will only # shutdown the Hub, leaving everything else running. -# +# # The Hub should be able to resume from database state. #c.JupyterHub.cleanup_servers = True ## Maximum number of concurrent users that can be spawning at a time. -# +# # Spawning lots of servers at the same time can cause performance problems for # the Hub or the underlying spawning system. Set this limit to prevent bursts of # logins from attempting to spawn too many servers at the same time. -# +# # This does not limit the number of total running servers. See # active_server_limit for that. -# +# # If more than this many users attempt to spawn at a time, their requests will # be rejected with a 429 error asking them to try again. Users will have to wait # for some of the spawning services to finish starting before they can start # their own. -# +# # If set to 0, no limit is enforced. #c.JupyterHub.concurrent_spawn_limit = 100 @@ -161,9 +161,9 @@ c.JupyterHub.bind_url = 'http://:__PORT____PATH__' #c.JupyterHub.cookie_max_age_days = 14 ## The cookie secret to use to encrypt cookies. -# +# # Loaded from the JPY_COOKIE_SECRET env variable by default. -# +# # Should be exactly 256 bits (32 bytes). #c.JupyterHub.cookie_secret = b'' @@ -191,37 +191,37 @@ c.JupyterHub.bind_url = 'http://:__PORT____PATH__' #c.JupyterHub.default_server_name = '' ## The default URL for users when they arrive (e.g. when user directs to "/") -# +# # By default, redirects users to their own server. #c.JupyterHub.default_url = '' ## Dict authority:dict(files). Specify the key, cert, and/or ca file for an # authority. This is useful for externally managed proxies that wish to use # internal_ssl. -# +# # The files dict has this format (you must specify at least a cert):: -# +# # { # 'key': '/path/to/key.key', # 'cert': '/path/to/cert.crt', # 'ca': '/path/to/ca.crt' # } -# +# # The authorities you can override: 'hub-ca', 'notebooks-ca', 'proxy-api-ca', # 'proxy-client-ca', and 'services-ca'. -# +# # Use with internal_ssl #c.JupyterHub.external_ssl_authorities = {} ## Register extra tornado Handlers for jupyterhub. -# +# # Should be of the form ``("", Handler)`` -# +# # The Hub prefix will be added, so `/my-page` will be served at `/hub/my-page`. #c.JupyterHub.extra_handlers = [] ## DEPRECATED: use output redirection instead, e.g. -# +# # jupyterhub &>> /var/log/jupyterhub.log #c.JupyterHub.extra_log_file = '' @@ -237,98 +237,98 @@ c.JupyterHub.bind_url = 'http://:__PORT____PATH__' ## The URL on which the Hub will listen. This is a private URL for internal # communication. Typically set in combination with hub_connect_url. If a unix # socket, hub_connect_url **must** also be set. -# +# # For example: -# +# # "http://127.0.0.1:8081" # "unix+http://%2Fsrv%2Fjupyterhub%2Fjupyterhub.sock" -# +# # .. versionadded:: 0.9 c.JupyterHub.hub_bind_url = 'http://127.0.0.1:__PORT_HUB__' c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' ## The ip or hostname for proxies and spawners to use for connecting to the Hub. -# +# # Use when the bind address (`hub_ip`) is 0.0.0.0 or otherwise different from # the connect address. -# +# # Default: when `hub_ip` is 0.0.0.0, use `socket.gethostname()`, otherwise use # `hub_ip`. -# +# # Note: Some spawners or proxy implementations might not support hostnames. # Check your spawner or proxy documentation to see if they have extra # requirements. -# +# # .. versionadded:: 0.8 #c.JupyterHub.hub_connect_ip = '' ## DEPRECATED -# +# # Use hub_connect_url -# +# # .. versionadded:: 0.8 -# +# # .. deprecated:: 0.9 # Use hub_connect_url #c.JupyterHub.hub_connect_port = 0 ## The URL for connecting to the Hub. Spawners, services, and the proxy will use # this URL to talk to the Hub. -# +# # Only needs to be specified if the default hub URL is not connectable (e.g. # using a unix+http:// bind url). -# +# # .. seealso:: # JupyterHub.hub_connect_ip # JupyterHub.hub_bind_url -# +# # .. versionadded:: 0.9 #c.JupyterHub.hub_connect_url = '' ## The ip address for the Hub process to *bind* to. -# +# # By default, the hub listens on localhost only. This address must be accessible # from the proxy and user servers. You may need to set this to a public ip or '' # for all interfaces if the proxy or user servers are in containers or on a # different host. -# +# # See `hub_connect_ip` for cases where the bind and connect address should # differ, or `hub_bind_url` for setting the full bind URL. #c.JupyterHub.hub_ip = '127.0.0.1' ## The internal port for the Hub process. -# +# # This is the internal port of the hub itself. It should never be accessed # directly. See JupyterHub.port for the public port to use when accessing # jupyterhub. It is rare that this port should be set except in cases of port # conflict. -# +# # See also `hub_ip` for the ip and `hub_bind_url` for setting the full bind URL. #c.JupyterHub.hub_port = 8081 ## Timeout (in seconds) to wait for spawners to initialize -# +# # Checking if spawners are healthy can take a long time if many spawners are # active at hub start time. -# +# # If it takes longer than this timeout to check, init_spawner will be left to # complete in the background and the http server is allowed to start. -# +# # A timeout of -1 means wait forever, which can mean a slow startup of the Hub # but ensures that the Hub is fully consistent by the time it starts responding # to requests. This matches the behavior of jupyterhub 1.0. -# +# # .. versionadded: 1.1.0 #c.JupyterHub.init_spawners_timeout = 10 ## The location to store certificates automatically created by JupyterHub. -# +# # Use with internal_ssl #c.JupyterHub.internal_certs_location = 'internal-ssl' ## Enable SSL for all internal communication -# +# # This enables end-to-end encryption between all JupyterHub components. # JupyterHub will automatically create the necessary certificate authority and # sign notebook certificates as they're created. @@ -336,11 +336,11 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' ## The public facing ip of the whole JupyterHub application (specifically # referred to as the proxy). -# +# # This is the address on which the proxy will listen. The default is to listen # on all interfaces. This is the only address through which JupyterHub should be # accessed by users. -# +# # .. deprecated: 0.9 # Use JupyterHub.bind_url #c.JupyterHub.ip = '' @@ -352,9 +352,9 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #c.JupyterHub.last_activity_interval = 300 ## Dict of 'group': ['usernames'] to load at startup. -# +# # This strictly *adds* groups and users to groups. -# +# # Loading one set of groups, then starting JupyterHub again with a different set # will not remove users or groups from previous launches. That must be done # through the API. @@ -365,9 +365,9 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' ## Maximum number of concurrent named servers that can be created by a user at a # time. -# +# # Setting this can limit the total resources a user can consume. -# +# # If set to 0, no limit is enforced. #c.JupyterHub.named_server_limit_per_user = 0 @@ -375,10 +375,10 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #c.JupyterHub.pid_file = '' ## The public facing port of the proxy. -# +# # This is the port on which the proxy will listen. This is the only port through # which JupyterHub should be accessed by users. -# +# # .. deprecated: 0.9 # Use JupyterHub.bind_url #c.JupyterHub.port = 8000 @@ -396,14 +396,14 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #c.JupyterHub.proxy_check_interval = 30 ## The class to use for configuring the JupyterHub proxy. -# +# # Should be a subclass of :class:`jupyterhub.proxy.Proxy`. -# +# # .. versionchanged:: 1.0 # proxies may be registered via entry points, # e.g. `c.JupyterHub.proxy_class = 'traefik'` -# -# Currently installed: +# +# Currently installed: # - default: jupyterhub.proxy.ConfigurableHTTPProxy # - configurable-http-proxy: jupyterhub.proxy.ConfigurableHTTPProxy #c.JupyterHub.proxy_class = 'jupyterhub.proxy.ConfigurableHTTPProxy' @@ -412,9 +412,9 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #c.JupyterHub.proxy_cmd = [] ## Recreate all certificates used within JupyterHub on restart. -# +# # Note: enabling this feature requires restarting all notebook servers. -# +# # Use with internal_ssl #c.JupyterHub.recreate_internal_certs = False @@ -429,17 +429,17 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #c.JupyterHub.service_check_interval = 60 ## Dict of token:servicename to be loaded into the database. -# +# # Allows ahead-of-time generation of API tokens for use by externally managed # services. #c.JupyterHub.service_tokens = {} ## List of service specification dictionaries. -# +# # A service -# +# # For instance:: -# +# # services = [ # { # 'name': 'cull_idle', @@ -458,26 +458,26 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #c.JupyterHub.shutdown_on_logout = False ## The class to use for spawning single-user servers. -# +# # Should be a subclass of :class:`jupyterhub.spawner.Spawner`. -# +# # .. versionchanged:: 1.0 # spawners may be registered via entry points, # e.g. `c.JupyterHub.spawner_class = 'localprocess'` -# -# Currently installed: +# +# Currently installed: # - default: jupyterhub.spawner.LocalProcessSpawner # - simple: jupyterhub.spawner.SimpleLocalProcessSpawner # - localprocess: jupyterhub.spawner.LocalProcessSpawner #c.JupyterHub.spawner_class = 'jupyterhub.spawner.LocalProcessSpawner' ## Path to SSL certificate file for the public facing interface of the proxy -# +# # When setting this, you should also set ssl_key #c.JupyterHub.ssl_cert = '' ## Path to SSL key file for the public facing interface of the proxy -# +# # When setting this, you should also set ssl_cert #c.JupyterHub.ssl_key = '' @@ -492,17 +492,17 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #c.JupyterHub.statsd_prefix = 'jupyterhub' ## Run single-user servers on subdomains of this host. -# +# # This should be the full `https://hub.domain.tld[:port]`. -# +# # Provides additional cross-site protections for javascript served by single- # user servers. -# +# # Requires `.hub.domain.tld` to resolve to the same host as # `hub.domain.tld`. -# +# # In general, this is most easily achieved with wildcard DNS. -# +# # When using SSL (i.e. always) this also requires a wildcard SSL certificate. #c.JupyterHub.subdomain_host = '' @@ -517,35 +517,35 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' ## Trust user-provided tokens (via JupyterHub.service_tokens) to have good # entropy. -# +# # If you are not inserting additional tokens via configuration file, this flag # has no effect. -# +# # In JupyterHub 0.8, internally generated tokens do not pass through additional # hashing because the hashing is costly and does not increase the entropy of # already-good UUIDs. -# +# # User-provided tokens, on the other hand, are not trusted to have good entropy # by default, and are passed through many rounds of hashing to stretch the # entropy of the key (i.e. user-provided tokens are treated as passwords instead # of random keys). These keys are more costly to check. -# +# # If your inserted tokens are generated by a good-quality mechanism, e.g. # `openssl rand -hex 32`, then you can set this flag to True to reduce the cost # of checking authentication tokens. #c.JupyterHub.trust_user_provided_tokens = False ## Names to include in the subject alternative name. -# +# # These names will be used for server name verification. This is useful if # JupyterHub is being run behind a reverse proxy or services using ssl are on # different hosts. -# +# # Use with internal_ssl #c.JupyterHub.trusted_alt_names = [] ## Downstream proxy IP addresses to trust. -# +# # This sets the list of IP addresses that are trusted and skipped when # processing the `X-Forwarded-For` header. For example, if an external proxy is # used for TLS termination, its IP address should be added to this list to @@ -554,18 +554,18 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #c.JupyterHub.trusted_downstream_ips = [] ## Upgrade the database automatically on start. -# +# # Only safe if database is regularly backed up. Only SQLite databases will be # backed up to a local file automatically. #c.JupyterHub.upgrade_db = False ## Callable to affect behavior of /user-redirect/ -# +# # Receives 4 parameters: 1. path - URL path that was provided after /user- # redirect/ 2. request - A Tornado HTTPServerRequest representing the current # request. 3. user - The currently authenticated user. 4. base_url - The # base_url of the current hub, for relative redirects -# +# # It should return the new URL to redirect to, or None to preserve current # behavior. #c.JupyterHub.user_redirect_hook = None @@ -575,43 +575,43 @@ c.ConfigurableHTTPProxy.api_url = 'http://127.0.0.1:__PORT_HTTP_PROXY__' #------------------------------------------------------------------------------ ## Base class for spawning single-user notebook servers. -# +# # Subclass this, and override the following methods: -# +# # - load_state - get_state - start - stop - poll -# +# # As JupyterHub supports multiple users, an instance of the Spawner subclass is # created for each user. If there are 20 JupyterHub users, there will be 20 # instances of the subclass. ## Extra arguments to be passed to the single-user server. -# +# # Some spawners allow shell-style expansion here, allowing you to use # environment variables here. Most, including the default, do not. Consult the # documentation for your spawner to verify! -c.Spawner.args = ['--config=__FINAL_PATH__/config/jupyter_notebook_config.py'] +c.Spawner.args = ['--config=__INSTALL_DIR__/config/jupyter_notebook_config.py'] ## An optional hook function that you can implement to pass `auth_state` to the # spawner after it has been initialized but before it starts. The `auth_state` # dictionary may be set by the `.authenticate()` method of the authenticator. # This hook enables you to pass some or all of that information to your spawner. -# +# # Example:: -# +# # def userdata_hook(spawner, auth_state): # spawner.userdata = auth_state["userdata"] -# +# # c.Spawner.auth_state_hook = userdata_hook #c.Spawner.auth_state_hook = None ## The command used for starting the single-user server. -# +# # Provide either a string or a list containing the path to the startup script # command. Extra arguments, other than this path, should be provided via `args`. -# +# # This is usually set if you want to start the single-user server in a different # python environment (with virtualenv/conda) than JupyterHub itself. -# +# # Some spawners allow shell-style expansion here, allowing you to use # environment variables. Most, including the default, do not. Consult the # documentation for your spawner to verify! @@ -619,20 +619,20 @@ c.Spawner.args = ['--config=__FINAL_PATH__/config/jupyter_notebook_config.py'] ## Maximum number of consecutive failures to allow before shutting down # JupyterHub. -# +# # This helps JupyterHub recover from a certain class of problem preventing # launch in contexts where the Hub is automatically restarted (e.g. systemd, # docker, kubernetes). -# +# # A limit of 0 means no limit and consecutive failures will not be tracked. #c.Spawner.consecutive_failure_limit = 0 ## Minimum number of cpu-cores a single-user notebook server is guaranteed to # have available. -# +# # If this value is set to 0.5, allows use of 50% of one CPU. If this value is # set to 2, allows use of up to 2 CPUs. -# +# # **This is a configuration setting. Your spawner must implement support for the # limit to work.** The default spawner, `LocalProcessSpawner`, does **not** # implement this support. A custom spawner **must** add support for this setting @@ -640,14 +640,14 @@ c.Spawner.args = ['--config=__FINAL_PATH__/config/jupyter_notebook_config.py'] #c.Spawner.cpu_guarantee = None ## Maximum number of cpu-cores a single-user notebook server is allowed to use. -# +# # If this value is set to 0.5, allows use of 50% of one CPU. If this value is # set to 2, allows use of up to 2 CPUs. -# +# # The single-user notebook server will never be scheduled by the kernel to use # more cpu-cores than this. There is no guarantee that it can access this many # cpu-cores. -# +# # **This is a configuration setting. Your spawner must implement support for the # limit to work.** The default spawner, `LocalProcessSpawner`, does **not** # implement this support. A custom spawner **must** add support for this setting @@ -658,11 +658,11 @@ c.Spawner.args = ['--config=__FINAL_PATH__/config/jupyter_notebook_config.py'] #c.Spawner.debug = False ## The URL the single-user server should start in. -# +# # `{username}` will be expanded to the user's username -# +# # Example uses: -# +# # - You can set `notebook_dir` to `/` and `default_url` to `/tree/home/{username}` to allow people to # navigate the whole filesystem from their notebook server, but still start in their home directory. # - Start with `/notebooks` instead of `/tree` if `default_url` points to a notebook instead of a directory. @@ -670,10 +670,10 @@ c.Spawner.args = ['--config=__FINAL_PATH__/config/jupyter_notebook_config.py'] c.Spawner.default_url = '/lab' ## Disable per-user configuration of single-user servers. -# +# # When starting the user's single-user server, any config file found in the # user's $HOME directory will be ignored. -# +# # Note: a user could circumvent this if the user modifies their Python # environment, such as when they have their own conda environments / virtualenvs # / containers. @@ -681,52 +681,52 @@ c.Spawner.default_url = '/lab' ## Whitelist of environment variables for the single-user server to inherit from # the JupyterHub process. -# +# # This whitelist is used to ensure that sensitive information in the JupyterHub # process's environment (such as `CONFIGPROXY_AUTH_TOKEN`) is not passed to the # single-user server's process. #c.Spawner.env_keep = ['PATH', 'PYTHONPATH', 'CONDA_ROOT', 'CONDA_DEFAULT_ENV', 'VIRTUAL_ENV', 'LANG', 'LC_ALL'] ## Extra environment variables to set for the single-user server's process. -# +# # Environment variables that end up in the single-user server's process come from 3 sources: # - This `environment` configurable # - The JupyterHub process' environment variables that are whitelisted in `env_keep` # - Variables to establish contact between the single-user notebook and the hub (such as JUPYTERHUB_API_TOKEN) -# +# # The `environment` configurable should be set by JupyterHub administrators to # add installation specific environment variables. It is a dict where the key is # the name of the environment variable, and the value can be a string or a # callable. If it is a callable, it will be called with one parameter (the # spawner instance), and should return a string fairly quickly (no blocking # operations please!). -# +# # Note that the spawner class' interface is not guaranteed to be exactly same # across upgrades, so if you are using the callable take care to verify it # continues to work after upgrades! #c.Spawner.environment = {} ## Timeout (in seconds) before giving up on a spawned HTTP server -# +# # Once a server has successfully been spawned, this is the amount of time we # wait before assuming that the server is unable to accept connections. #c.Spawner.http_timeout = 30 ## The IP address (or hostname) the single-user server should listen on. -# +# # The JupyterHub proxy implementation should be able to send packets to this # interface. #c.Spawner.ip = '' ## Minimum number of bytes a single-user notebook server is guaranteed to have # available. -# +# # Allows the following suffixes: # - K -> Kilobytes # - M -> Megabytes # - G -> Gigabytes # - T -> Terabytes -# +# # **This is a configuration setting. Your spawner must implement support for the # limit to work.** The default spawner, `LocalProcessSpawner`, does **not** # implement this support. A custom spawner **must** add support for this setting @@ -734,17 +734,17 @@ c.Spawner.default_url = '/lab' #c.Spawner.mem_guarantee = None ## Maximum number of bytes a single-user notebook server is allowed to use. -# +# # Allows the following suffixes: # - K -> Kilobytes # - M -> Megabytes # - G -> Gigabytes # - T -> Terabytes -# +# # If the single user server tries to allocate more memory than this, it will # fail. There is no guarantee that the single-user notebook server will be able # to allocate this much memory - only that it can not allocate more than this. -# +# # **This is a configuration setting. Your spawner must implement support for the # limit to work.** The default spawner, `LocalProcessSpawner`, does **not** # implement this support. A custom spawner **must** add support for this setting @@ -752,26 +752,26 @@ c.Spawner.default_url = '/lab' #c.Spawner.mem_limit = None ## Path to the notebook directory for the single-user server. -# +# # The user sees a file listing of this directory when the notebook interface is # started. The current interface does not easily allow browsing beyond the # subdirectories in this directory's tree. -# +# # `~` will be expanded to the home directory of the user, and {username} will be # replaced with the name of the user. -# +# # Note that this does *not* prevent users from accessing files outside of this # path! They can do so with many other means. #c.Spawner.notebook_dir = '' ## An HTML form for options a user can specify on launching their server. -# +# # The surrounding `
` element and the submit button are already provided. -# +# # For example: -# +# # .. code:: html -# +# # Set your key: # #
@@ -780,10 +780,10 @@ c.Spawner.default_url = '/lab' # # # -# +# # The data from this form submission will be passed on to your spawner in # `self.user_options` -# +# # Instead of a form snippet string, this could also be a callable that takes as # one parameter the current spawner instance and returns a string. The callable # will be called asynchronously if it returns a future, rather than a str. Note @@ -793,7 +793,7 @@ c.Spawner.default_url = '/lab' ## Interval (in seconds) on which to poll the spawner for single-user server's # status. -# +# # At every poll interval, each spawner's `.poll` method is called, which checks # if the single-user server is still running. If it isn't running, then # JupyterHub modifies its own state accordingly and removes appropriate routes @@ -801,41 +801,41 @@ c.Spawner.default_url = '/lab' #c.Spawner.poll_interval = 30 ## The port for single-user servers to listen on. -# +# # Defaults to `0`, which uses a randomly allocated port number each time. -# +# # If set to a non-zero value, all Spawners will use the same port, which only # makes sense if each server is on a different address, e.g. in containers. -# +# # New in version 0.7. #c.Spawner.port = 0 ## An optional hook function that you can implement to do work after the spawner # stops. -# +# # This can be set independent of any concrete spawner implementation. #c.Spawner.post_stop_hook = None ## An optional hook function that you can implement to do some bootstrapping work # before the spawner starts. For example, create a directory for your user or # load initial content. -# +# # This can be set independent of any concrete spawner implementation. -# +# # This maybe a coroutine. -# +# # Example:: -# +# # from subprocess import check_call # def my_hook(spawner): # username = spawner.user.name # check_call(['./examples/bootstrap-script/bootstrap.sh', username]) -# +# # c.Spawner.pre_spawn_hook = my_hook #c.Spawner.pre_spawn_hook = None ## List of SSL alt names -# +# # May be set in config if all spawners should have the same value(s), or set at # runtime by Spawner that know their names. #c.Spawner.ssl_alt_names = [] @@ -844,7 +844,7 @@ c.Spawner.default_url = '/lab' #c.Spawner.ssl_alt_names_include_local = True ## Timeout (in seconds) before giving up on starting of single-user server. -# +# # This is the timeout for start to return, not the timeout for the server to # respond. Callers of spawner.start will assume that startup has failed if it # takes longer than this. start should return when the server process is started @@ -858,81 +858,81 @@ c.Spawner.default_url = '/lab' ## Base class for implementing an authentication provider for JupyterHub ## Set of users that will have admin rights on this JupyterHub. -# +# # Admin users have extra privileges: # - Use the admin panel to see list of users logged in # - Add / remove users in some authenticators # - Restart / halt the hub # - Start / stop users' single-user servers # - Can access each individual users' single-user server (if configured) -# +# # Admin access should be treated the same way root access is. -# +# # Defaults to an empty set, in which case no user has admin access. c.Authenticator.admin_users = ["__ADMIN__"] ## The max age (in seconds) of authentication info before forcing a refresh of # user auth info. -# +# # Refreshing auth info allows, e.g. requesting/re-validating auth tokens. -# +# # See :meth:`.refresh_user` for what happens when user auth info is refreshed # (nothing by default). #c.Authenticator.auth_refresh_age = 300 ## Automatically begin the login process -# +# # rather than starting with a "Login with..." link at `/hub/login` -# +# # To work, `.login_url()` must give a URL other than the default `/hub/login`, # such as an oauth handler or another automatic login handler, registered with # `.get_handlers()`. -# +# # .. versionadded:: 0.8 #c.Authenticator.auto_login = False ## Blacklist of usernames that are not allowed to log in. -# +# # Use this with supported authenticators to restrict which users can not log in. # This is an additional blacklist that further restricts users, beyond whatever # restrictions the authenticator has in place. -# +# # If empty, does not perform any additional restriction. -# +# # .. versionadded: 0.9 #c.Authenticator.blacklist = set() ## Enable persisting auth_state (if available). -# +# # auth_state will be encrypted and stored in the Hub's database. This can # include things like authentication tokens, etc. to be passed to Spawners as # environment variables. -# +# # Encrypting auth_state requires the cryptography package. -# +# # Additionally, the JUPYTERHUB_CRYPT_KEY environment variable must contain one # (or more, separated by ;) 32B encryption keys. These can be either base64 or # hex-encoded. -# +# # If encryption is unavailable, auth_state cannot be persisted. -# +# # New in JupyterHub 0.8 #c.Authenticator.enable_auth_state = False ## An optional hook function that you can implement to do some bootstrapping work # during authentication. For example, loading user account details from an # external system. -# +# # This function is called after the user has passed all authentication checks # and is ready to successfully authenticate. This function must return the # authentication dict reguardless of changes to it. -# +# # This maybe a coroutine. -# +# # .. versionadded: 1.0 -# +# # Example:: -# +# # import os, pwd # def my_hook(authenticator, handler, authentication): # user_data = pwd.getpwnam(authentication['name']) @@ -940,47 +940,47 @@ c.Authenticator.admin_users = ["__ADMIN__"] # 'pw_data': user_data # 'gid_list': os.getgrouplist(authentication['name'], user_data.pw_gid) # } -# +# # if authentication['auth_state'] is None: # authentication['auth_state'] = {} # authentication['auth_state']['spawn_data'] = spawn_data -# +# # return authentication -# +# # c.Authenticator.post_auth_hook = my_hook #c.Authenticator.post_auth_hook = None ## Force refresh of auth prior to spawn. -# +# # This forces :meth:`.refresh_user` to be called prior to launching a server, to # ensure that auth state is up-to-date. -# +# # This can be important when e.g. auth tokens that may have expired are passed # to the spawner via environment variables from auth_state. -# +# # If refresh_user cannot refresh the user auth data, launch will fail until the # user logs in again. #c.Authenticator.refresh_pre_spawn = False ## Dictionary mapping authenticator usernames to JupyterHub users. -# +# # Primarily used to normalize OAuth user names to local users. #c.Authenticator.username_map = {} ## Regular expression pattern that all valid usernames must match. -# +# # If a username does not match the pattern specified here, authentication will # not be attempted. -# +# # If not set, allow any username. #c.Authenticator.username_pattern = '' ## Whitelist of usernames that are allowed to log in. -# +# # Use this with supported authenticators to restrict which users can log in. # This is an additional whitelist that further restricts users, beyond whatever # restrictions the authenticator has in place. -# +# # If empty, does not perform any additional restriction. #c.Authenticator.whitelist = set() @@ -989,10 +989,10 @@ c.Authenticator.admin_users = ["__ADMIN__"] #------------------------------------------------------------------------------ ## Encapsulate encryption configuration -# +# # Use via the encryption_config singleton below. -## +## #c.CryptKeeper.keys = [] ## The number of threads to allocate for encryption diff --git a/conf/systemd.service b/conf/systemd.service index e6fbc31..3d62b9d 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -5,11 +5,11 @@ After=syslog.target network.target [Service] Type=simple User=root -WorkingDirectory=__FINALPATH__/ +WorkingDirectory=__INSTALL_DIR__/ Environment="LC_ALL=C.UTF-8" Environment="LANG=C.UTF-8" -Environment="__YNH_NODE_LOAD_PATH__:__FINALPATH__/venv/bin" -ExecStart=__FINALPATH__/venv/bin/jupyterhub -f __FINALPATH__/config/jupyterhub_config.py --upgrade-db +Environment="__YNH_NODE_LOAD_PATH__:__INSTALL_DIR__/venv/bin" +ExecStart=__INSTALL_DIR__/venv/bin/jupyterhub -f __INSTALL_DIR__/config/jupyterhub_config.py --upgrade-db Restart=always RestartSec=10 diff --git a/doc/DISCLAIMER.md b/doc/ADMIN.md similarity index 100% rename from doc/DISCLAIMER.md rename to doc/ADMIN.md diff --git a/manifest.json b/manifest.json deleted file mode 100644 index 5f4c0dd..0000000 --- a/manifest.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "JupyterLab", - "id": "jupyterlab", - "packaging_format": 1, - "description": { - "en": "Code console environment for running Python code interactively", - "fr": "Console de code pour exécuter du code Python de manière interactive" - }, - "version": "4.0.9~ynh1", - "url": "https://jupyter.org", - "upstream": { - "license": "BSD-3-Clause", - "website": "https://jupyter.org", - "demo": "https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo", - "admindoc": "https://jupyterlab.readthedocs.io/en/stable/", - "code": "https://github.com/jupyterhub/jupyterhub", - "cpe": "cpe:2.3:a:jupyter:nbdime-jupyterlab" - }, - "license": "BSD-3-Clause", - "maintainer": { - "name": "kay0u", - "email": "pierre@kayou.io" - }, - "requirements": { - "yunohost": ">= 11.2" - }, - "multi_instance": true, - "services": [ - "nginx" - ], - "arguments": { - "install": [ - { - "name": "domain", - "type": "domain" - }, - { - "name": "path", - "type": "path", - "example": "/jupyterlab", - "default": "/jupyterlab" - }, - { - "name": "is_public", - "type": "boolean", - "default": true - }, - { - "name": "admin", - "type": "user" - }, - { - "name": "enable_terminal", - "type": "boolean", - "ask": { - "en": "Enable terminal in the lab?", - "fr": "Activer le terminal dans le lab ?" - }, - "default": true - } - ] - } -} \ No newline at end of file diff --git a/manifest.toml b/manifest.toml new file mode 100644 index 0000000..d62f854 --- /dev/null +++ b/manifest.toml @@ -0,0 +1,89 @@ +#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/manifest.v2.schema.json + +packaging_format = 2 + +id = "jupyterlab" +name = "JupyterLab" +description.en = "Code console environment for running Python code interactively" +description.fr = "Console de code pour exécuter du code Python de manière interactive" + +version = "4.1.0~ynh1" + +maintainers = ["kay0u"] + +[upstream] +license = "BSD-3-Clause" +website = "https://jupyter.org" +demo = "https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo" +admindoc = "https://jupyterlab.readthedocs.io/en/stable/" +code = "https://github.com/jupyterhub/jupyterhub" + +[integration] +yunohost = ">= 11.2" +architectures = "all" +multi_instance = false + +ldap = true + +sso = false + +disk = "50M" +ram.build = "50M" +ram.runtime = "50M" + +[install] + [install.domain] + type = "domain" + + [install.path] + type = "path" + default = "/jupyterlab" + + [install.init_main_permission] + type = "group" + default = "visitors" + + [install.admin] + type = "user" + + [install.enable_terminal] + ask.en = "Enable terminal in the lab?" + ask.fr = "Activer le terminal dans le lab ?" + type = "boolean" + default = true + +[resources] + [resources.sources.main] + url = "https://github.com/jupyterhub/jupyterhub/archive/refs/tags/4.1.0.tar.gz" + sha256 = "2afed4c1cbd7c83d72ad1015a7955bb0f49e82cbe6ba896ee198ecb049b08749" + # Only used for autoupdate, code will checkout the commit + prefetch = false + + autoupdate.strategy = "latest_github_tag" + + [resources.system_user] + + [resources.install_dir] + # Using /opt because /var/www has ACLs that prevent users to access it + dir = "/opt/__APP__" + + [resources.ports] + main.default = 8080 + hub.default = 8081 + http_proxy.default = 8082 + + [resources.permissions] + main.url = "/" + + [resources.apt] + packages = [ + "python3-dev", + "python3-pip", + "python3-venv", + "pipenv", + ] + + [resources.apt.extras.yarn] + repo = "deb https://dl.yarnpkg.com/debian/ stable main" + key = "https://dl.yarnpkg.com/debian/pubkey.gpg" + packages = ["yarn"] diff --git a/scripts/_common.sh b/scripts/_common.sh index 1ae6a31..bb10598 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,17 +4,19 @@ # COMMON VARIABLES #================================================= -# dependencies used by the app -pkg_dependencies="python3-dev python3-pip python3-venv" - nodejs_version="18" -jupyterlab_version="4.0.9" - #================================================= # PERSONAL HELPERS #================================================= +jupyterlab_upstream_version() { + upstream_repository=$(ynh_read_manifest --manifest_key='upstream.code') + upstream_url=$(ynh_read_manifest --manifest_key='resources.sources.main.url') + upstream_commit=$(echo "$upstream_url" | sed -e "s|^${upstream_repository}/archive/refs/tags/\(.*\)\.tar\.gz|\1|") + echo "$upstream_commit" +} + #================================================= # EXPERIMENTAL HELPERS #================================================= diff --git a/scripts/backup b/scripts/backup index d72c557..398b0e3 100644 --- a/scripts/backup +++ b/scripts/backup @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -10,26 +8,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - true -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -ynh_print_info --message="Loading installation settings..." - -app=$YNH_APP_INSTANCE_NAME - -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -domain=$(ynh_app_setting_get --app=$app --key=domain) - #================================================= # DECLARE DATA AND CONF FILES TO BACKUP #================================================= @@ -39,20 +17,14 @@ ynh_print_info --message="Declaring files to be backed up..." # BACKUP THE APP MAIN DIR #================================================= -ynh_backup --src_path="$final_path" +ynh_backup --src_path="$install_dir" #================================================= -# BACKUP THE NGINX CONFIGURATION +# BACKUP THE SYSTEM CONFIGURATION #================================================= ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" -#================================================= -# SPECIFIC BACKUP -#================================================= -# BACKUP SYSTEMD -#================================================= - ynh_backup --src_path="/etc/systemd/system/$app.service" #================================================= diff --git a/scripts/change_url b/scripts/change_url index e26ce2d..a58afb0 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC STARTING #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -9,131 +7,36 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# RETRIEVE ARGUMENTS -#================================================= - -old_domain=$YNH_APP_OLD_DOMAIN -old_path=$YNH_APP_OLD_PATH - -new_domain=$YNH_APP_NEW_DOMAIN -new_path=$YNH_APP_NEW_PATH - -app=$YNH_APP_INSTANCE_NAME - -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." - -# Needed for helper "ynh_add_nginx_config" -final_path=$(ynh_app_setting_get --app=$app --key=final_path) - -# 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 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" - - # Restore it if the upgrade fails - ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# CHECK WHICH PARTS SHOULD BE CHANGED -#================================================= - -change_domain=0 -if [ "$old_domain" != "$new_domain" ] -then - change_domain=1 -fi - -change_path=0 -if [ "$old_path" != "$new_path" ] -then - change_path=1 -fi - -#================================================= -# STANDARD MODIFICATIONS #================================================= # STOP SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Stopping a systemd service..." +ynh_script_progression --message="Stopping $app's systemd service..." --weight=1 -ynh_systemd_action --service_name=$app --action="stop" +ynh_systemd_action --service_name=$app --action="stop" --log_path="systemd" #================================================= # MODIFY URL IN NGINX CONF #================================================= -ynh_script_progression --message="Updating NGINX web server configuration..." +ynh_script_progression --message="Updating NGINX web server configuration..." --weight=1 -nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf +ynh_change_url_nginx_config -# Change the path in the NGINX config file -if [ $change_path -eq 1 ] -then - # Make a backup of the original NGINX config file if modified - ynh_backup_if_checksum_is_different --file="$nginx_conf_path" - # Set global variables for NGINX helper - domain="$old_domain" - path_url="$new_path" - # Create a dedicated NGINX config - ynh_add_nginx_config -fi - -# Change the domain for NGINX -if [ $change_domain -eq 1 ] -then - # Delete file checksum for the old conf file location - ynh_delete_file_checksum --file="$nginx_conf_path" - mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf - # Store file checksum for the new config file location - ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" -fi - -#================================================= -# SPECIFIC MODIFICATIONS #================================================= # CONFIGURE JUPYTERLAB #================================================= domain=$new_domain -path=${new_path%/} +path_no_slash=${new_path%/} -ynh_add_config --template="../conf/jupyterhub_config.py" --destination="$final_path/config/jupyterhub_config.py" +ynh_add_config --template="jupyterhub_config.py" --destination="$install_dir/config/jupyterhub_config.py" -#================================================= -# GENERIC FINALISATION #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." +ynh_script_progression --message="Starting $app's systemd service..." --weight=1 # 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_systemd_action --service_name=nginx --action=reload +ynh_systemd_action --service_name="$app" --action="start" --line_match="JupyterHub is now running at" --log_path="systemd" #================================================= # END OF SCRIPT diff --git a/scripts/install b/scripts/install index a660ea3..c09a1be 100644 --- a/scripts/install +++ b/scripts/install @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -9,158 +7,71 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# RETRIEVE ARGUMENTS FROM THE MANIFEST -#================================================= - -domain=$YNH_APP_ARG_DOMAIN -path_url=$YNH_APP_ARG_PATH -is_public=$YNH_APP_ARG_IS_PUBLIC -admin=$YNH_APP_ARG_ADMIN -enable_terminal=$YNH_APP_ARG_ENABLE_TERMINAL - -app=$YNH_APP_INSTANCE_NAME - -#================================================= -# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS -#================================================= -ynh_script_progression --message="Validating installation parameters..." --weight=1 - -final_path=/opt/$app -test ! -e "$final_path" || ynh_die --message="This path already contains a folder" - -# Register (book) web path -ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url - -#================================================= -# STORE SETTINGS FROM MANIFEST -#================================================= -ynh_script_progression --message="Storing installation settings..." --weight=1 - -ynh_app_setting_set --app=$app --key=domain --value=$domain -ynh_app_setting_set --app=$app --key=path --value=$path_url -ynh_app_setting_set --app=$app --key=admin --value=$admin -ynh_app_setting_set --app=$app --key=enable_terminal --value=$enable_terminal - -#================================================= -# STANDARD MODIFICATIONS -#================================================= -# FIND AND OPEN A PORT -#================================================= -ynh_script_progression --message="Finding an available port..." --weight=1 - -# Find an available port -port=$(ynh_find_port --port=8080) -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 - #================================================= # INSTALL DEPENDENCIES #================================================= -ynh_script_progression --message="Installing dependencies..." --weight=23 +ynh_script_progression --message="Installing NodeJS..." --weight=15 -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 + +ynh_exec_warn_less "$ynh_npm" install -g configurable-http-proxy #================================================= -# NGINX CONFIGURATION +# SET ADMIN GROUP #================================================= -ynh_script_progression --message="Configuring NGINX web server..." --weight=1 +ynh_script_progression --message="Adding $admin to $app's group..." --weight=5 -# Create a dedicated NGINX config -ynh_add_nginx_config +usermod -a -G "$app" "$admin" -#================================================= -# SPECIFIC SETUP #================================================= # BUILD APP #================================================= -ynh_script_progression --message="Building app..." +ynh_script_progression --message="Building app..." --weight=5 -ynh_app_setting_set --app=$app --key=final_path --value=$final_path -mkdir -p "$final_path" +python3 -m venv "$install_dir/venv" -pushd $final_path - python3 -m venv $final_path/venv - source $final_path/venv/bin/activate - ynh_exec_warn_less pip install jupyterlab==$jupyterlab_version jupyterhub jupyter_collaboration notebook jupyterhub-ldapauthenticator pyzmq jupyterlab-language-pack-fr-FR -popd +ynh_exec_warn_less "$install_dir/venv/bin/python3" -m pip install \ + jupyterlab=="$(jupyterlab_upstream_version)" \ + jupyterhub \ + jupyter_collaboration \ + notebook \ + jupyterhub-ldapauthenticator \ + pyzmq \ + jupyterlab-language-pack-fr-FR #================================================= # ADD A CONFIGURATION #================================================= -ynh_script_progression --message="Adding a configuration file..." +ynh_script_progression --message="Adding $app's configuration file..." --weight=1 -mkdir -p "$final_path/config" +mkdir -p "$install_dir/config" -path=${path_url%/} +path_no_slash=${path%/} +ynh_add_config --template="jupyterhub_config.py" --destination="$install_dir/config/jupyterhub_config.py" +ynh_add_config --template="jupyter_notebook_config.py" --destination="$install_dir/config/jupyter_notebook_config.py" -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" - -chown -R root: $final_path/ -chown -R $admin: $final_path/venv/ +chown -R "$app:$app" "$install_dir" #================================================= -# SETUP SYSTEMD +# SYSTEM CONFIGURATION #================================================= -ynh_script_progression --message="Configuring a systemd service..." --weight=3 +ynh_script_progression --message="Adding system configurations related to $app..." --weight=1 + +# Create a dedicated NGINX config +ynh_add_nginx_config # 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" +yunohost service add "$app" --description="Console environment for running Python code" --log="/var/log/$app/$app.log" #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." --weight=3 +ynh_script_progression --message="Starting $app's systemd service..." --weight=3 # Start a systemd service -ynh_systemd_action --service_name=$app --action="start" --line_match="JupyterHub is now running at" --log_path="systemd" - -#================================================= -# SETUP SSOWAT -#================================================= -ynh_script_progression --message="Configuring permissions..." --weight=4 - -# Make app public if necessary -if [ $is_public -eq 1 ] -then - ynh_permission_update --permission="main" --add="visitors" -fi - -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 - -ynh_systemd_action --service_name=nginx --action=reload +ynh_systemd_action --service_name="$app" --action="start" --line_match="JupyterHub is now running at" --log_path="systemd" #================================================= # END OF SCRIPT diff --git a/scripts/remove b/scripts/remove index 71f2e5b..c63999b 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -10,59 +8,21 @@ source _common.sh source /usr/share/yunohost/helpers #================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 - -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) - -#================================================= -# STANDARD REMOVE -#================================================= -# REMOVE SERVICE INTEGRATION IN YUNOHOST +# REMOVE SYSTEM CONFIGURATIONS #================================================= +ynh_script_progression --message="Removing system configurations related to $app..." --weight=1 # 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=2 - yunohost service remove $app +if ynh_exec_warn_less yunohost service status "$app" >/dev/null; then + yunohost service remove "$app" fi -#================================================= -# STOP AND REMOVE SERVICE -#================================================= -ynh_script_progression --message="Stopping and removing the systemd service..." --weight=2 - # Remove the dedicated systemd config ynh_remove_systemd_config -#================================================= -# REMOVE APP MAIN DIR -#================================================= -ynh_script_progression --message="Removing app main directory..." --weight=1 - -# Remove the app directory securely -ynh_secure_remove --file="$final_path" - -#================================================= -# REMOVE NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Removing NGINX web server configuration..." --weight=1 - # Remove the dedicated NGINX config ynh_remove_nginx_config -#================================================= -# REMOVE DEPENDENCIES -#================================================= -ynh_script_progression --message="Removing dependencies..." --weight=4 - -# Remove metapackage and its dependencies -ynh_remove_app_dependencies ynh_remove_nodejs #================================================= diff --git a/scripts/restore b/scripts/restore index e7d4bc8..dcaec30 100644 --- a/scripts/restore +++ b/scripts/restore @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -11,95 +9,48 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers #================================================= -# MANAGE SCRIPT FAILURE +# REINSTALL DEPENDENCIES #================================================= +ynh_script_progression --message="Reinstalling NodeJS..." --weight=15 -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors +ynh_exec_warn_less ynh_install_nodejs --nodejs_version="$nodejs_version" +ynh_use_nodejs + +ynh_exec_warn_less "$ynh_npm" install -g configurable-http-proxy #================================================= -# LOAD SETTINGS +# SET ADMIN GROUP #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 +ynh_script_progression --message="Adding $admin to $app's group..." --weight=5 -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -path_url=$(ynh_app_setting_get --app=$app --key=path) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -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 - -test ! -d $final_path \ - || ynh_die --message="There is already a directory: $final_path " - -#================================================= -# STANDARD RESTORATION STEPS -#================================================= -# 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" +usermod -a -G "$app" "$admin" #================================================= # RESTORE THE APP MAIN DIR #================================================= ynh_script_progression --message="Restoring the app main directory..." --weight=5 -ynh_restore_file --origin_path="$final_path" +ynh_restore_file --origin_path="$install_dir" -chown -R root: $final_path/ -chown -R $admin: $final_path/venv/ - -#================================================= -# SPECIFIC RESTORATION -#================================================= -# REINSTALL DEPENDENCIES -#================================================= -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 +chown -R "$app:$app" "$install_dir" #================================================= # RESTORE SYSTEMD #================================================= -ynh_script_progression --message="Restoring the systemd configuration..." --weight=2 +ynh_script_progression --message="Restoring system configurations related to $app..." --weight=1 + +ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" ynh_restore_file --origin_path="/etc/systemd/system/$app.service" -systemctl enable $app.service --quiet +systemctl enable "$app.service" --quiet +yunohost service add "$app" --description="Console environment for running Python code" --log="/var/log/$app/$app.log" #================================================= -# INTEGRATE SERVICE IN YUNOHOST +# RELOAD NGINX AND PHP-FPM OR THE APP SERVICE #================================================= -ynh_script_progression --message="Integrating service in YunoHost..." +ynh_script_progression --message="Reloading NGINX web server and $app's service..." --weight=1 -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" - -#================================================= -# GENERIC FINALIZATION -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 +ynh_systemd_action --service_name="$app" --action="start" --line_match="JupyterHub is now running at" --log_path="systemd" ynh_systemd_action --service_name=nginx --action=reload diff --git a/scripts/upgrade b/scripts/upgrade index 871c306..17e1d57 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,7 +1,5 @@ #!/bin/bash -#================================================= -# GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= @@ -9,155 +7,78 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." --weight=3 - -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -path_url=$(ynh_app_setting_get --app=$app --key=path) -admin=$(ynh_app_setting_get --app=$app --key=admin) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -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) -enable_terminal=$(ynh_app_setting_get --app=$app --key=enable_terminal) - -#================================================= -# CHECK 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_script_progression --message="Stopping $app's systemd service..." --weight=2 -ynh_systemd_action --service_name=$app --action="stop" - -#================================================= -# ENSURE DOWNWARD COMPATIBILITY -#================================================= -ynh_script_progression --message="Ensuring downward compatibility..." - -# If final_path doesn't exist, create it -if [ -z "$final_path" ]; then - final_path=/opt/$app - mkdir -p $final_path - ynh_app_setting_set --app=$app --key=final_path --value=$final_path -fi - -# Cleaning legacy permissions -if ynh_legacy_permissions_exists; then - ynh_legacy_permissions_delete_all - - ynh_app_setting_delete --app=$app --key=is_public -fi - -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 - -# Create a dedicated NGINX config -ynh_add_nginx_config +ynh_systemd_action --service_name="$app" --action="stop" #================================================= # UPGRADE DEPENDENCIES #================================================= ynh_script_progression --message="Upgrading dependencies..." --weight=10 -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 npm +ynh_exec_warn_less "$ynh_npm" install -g configurable-http-proxy #================================================= -# SPECIFIC UPGRADE +# SET ADMIN GROUP +#================================================= +ynh_script_progression --message="Adding $admin to $app's group..." --weight=5 + +usermod -a -G "$app" "$admin" + #================================================= # BUILD APP #================================================= +ynh_script_progression --message="Building app..." --weight=15 -if [ "$upgrade_type" == "UPGRADE_APP" ] -then - ynh_script_progression --message="Building app..." --weight=160 +ynh_secure_remove --file="$install_dir/.venv" +python3 -m venv "$install_dir/venv" - ynh_secure_remove $final_path/.venv - python3 -m venv $final_path/venv - source $final_path/venv/bin/activate - - pushd $final_path - ynh_exec_warn_less pip install jupyterlab==$jupyterlab_version jupyterhub notebook jupyter_collaboration jupyterhub-ldapauthenticator pyzmq - popd -fi +ynh_exec_warn_less "$install_dir/venv/bin/python3" -m pip install \ + jupyterlab=="$(jupyterlab_upstream_version)" \ + jupyterhub \ + jupyter_collaboration \ + notebook \ + jupyterhub-ldapauthenticator \ + pyzmq \ + jupyterlab-language-pack-fr-FR #================================================= # UPDATE A CONFIG FILE #================================================= -ynh_script_progression --message="Updating a configuration file..." +ynh_script_progression --message="Updating a configuration file..." --weight=1 -mkdir -p "$final_path/config" +mkdir -p "$install_dir/config" -path=${path_url%/} +path_no_slash=${path%/} -ynh_add_config --template="../conf/jupyterhub_config.py" --destination="$final_path/config/jupyterhub_config.py" +ynh_add_config --template="jupyterhub_config.py" --destination="$install_dir/config/jupyterhub_config.py" +ynh_add_config --template="jupyter_notebook_config.py" --destination="$install_dir/config/jupyter_notebook_config.py" -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/ +chown -R "$app:$app" "$install_dir" #================================================= # SETUP SYSTEMD #================================================= -ynh_script_progression --message="Upgrading systemd configuration..." +ynh_script_progression --message="Upgrading systemd configuration..." --weight=1 + +ynh_add_nginx_config # 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" +yunohost service add "$app" --description="Console environment for running Python code" --log="/var/log/$app/$app.log" #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." +ynh_script_progression --message="Starting $app's systemd service..." --weight=1 -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_systemd_action --service_name=nginx --action=reload +ynh_systemd_action --service_name="$app" --action="start" --line_match="JupyterHub is now running at" --log_path="systemd" #================================================= # END OF SCRIPT diff --git a/tests.toml b/tests.toml new file mode 100644 index 0000000..030c471 --- /dev/null +++ b/tests.toml @@ -0,0 +1,19 @@ +test_format = 1.0 + +[default] + + # ------------ + # Tests to run + # ------------ + + # ------------------------------------------------------------------------------- + # EVERYTHING PAST THIS POINT IS OPTIONAL AND MOST LIKELY UNNECESSARY FOR NEW APPS + #-------------------------------------------------------------------------------- + + exclude = ["install.multi"] + + # ------------------------------- + # Default args to use for install + # ------------------------------- + + args.enable_terminal = "true"