1
Fork 0
mirror of https://github.com/Steffo99/sophon.git synced 2024-12-22 06:44:21 +00:00

💥 I'm not sure I understand what I'm writing anymore.

This commit is contained in:
Steffo 2021-11-05 04:24:49 +01:00
parent 4f467b242a
commit b88c592aab
12 changed files with 155 additions and 12 deletions

View file

@ -0,0 +1,18 @@
# Generated by Django 3.2.8 on 2021-11-05 02:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('notebooks', '0014_alter_notebook_container_image'),
]
operations = [
migrations.AlterField(
model_name='notebook',
name='container_image',
field=models.CharField(choices=[('ghcr.io/steffo99/sophon-jupyter', 'Jupyter (Sophon)')], default='ghcr.io/steffo99/sophon-jupyter',
help_text='The Docker image to run for this notebook.', max_length=256, verbose_name='Docker image'),
),
]

View file

@ -18,7 +18,7 @@ from sophon.notebooks.apache import get_ephemeral_port
from sophon.notebooks.docker import client as docker_client from sophon.notebooks.docker import client as docker_client
from sophon.notebooks.docker import sleep_until_container_has_started, get_proxy_container from sophon.notebooks.docker import sleep_until_container_has_started, get_proxy_container
from sophon.notebooks.jupyter import generate_secure_token from sophon.notebooks.jupyter import generate_secure_token
from sophon.notebooks.validators import DisallowedValuesValidator from sophon.notebooks.validators import DisallowedValuesValidator, NotStartingWithDashValidator
from sophon.projects.models import ResearchProject from sophon.projects.models import ResearchProject
module_name = __name__ module_name = __name__
@ -51,7 +51,8 @@ class Notebook(SophonGroupModel):
"backend", # reserved for future use "backend", # reserved for future use
"frontend", # reserved for future use "frontend", # reserved for future use
"src", # reserved for future use "src", # reserved for future use
]) ]),
NotStartingWithDashValidator(),
] ]
) )
@ -486,9 +487,6 @@ class Notebook(SophonGroupModel):
"8888/tcp": (f"127.0.0.1", f"{self.port}/tcp") "8888/tcp": (f"127.0.0.1", f"{self.port}/tcp")
} if self.port else {}, } if self.port else {},
environment={ environment={
"JUPYTER_ENABLE_LAB": "yes",
"RESTARTABLE": "yes",
"GRANT_SUDO": "yes",
"JUPYTER_TOKEN": self.jupyter_token, "JUPYTER_TOKEN": self.jupyter_token,
}, },
volumes={ volumes={

View file

@ -14,3 +14,13 @@ class DisallowedValuesValidator:
_("%(value)s is a disallowed value."), _("%(value)s is a disallowed value."),
params={"value": value}, params={"value": value},
) )
@deconstructible
class NotStartingWithDashValidator:
def __call__(self, value):
if value.startswith("-") or value.endswith("-"):
raise ValidationError(
_("%(value)s starts or ends with a dash."),
params={"value": value},
)

View file

@ -20,6 +20,8 @@ Per sviluppare Sophon sono usati i seguenti strumenti:
- `GitHub Containers`_, un registro di container Docker integrato in `GitHub`_; - `GitHub Containers`_, un registro di container Docker integrato in `GitHub`_;
- `CodeQL`_, un tool di analisi statica integrato in `GitHub`_; - `CodeQL`_, un tool di analisi statica integrato in `GitHub`_;
- `Sphinx`_, uno strumento per la creazione di documentazione.
.. _IntelliJ IDEA Ultimate: https://www.jetbrains.com/idea/ .. _IntelliJ IDEA Ultimate: https://www.jetbrains.com/idea/
.. _Git: https://git-scm.com/ .. _Git: https://git-scm.com/
.. _GitHub: https://github.com/ .. _GitHub: https://github.com/
@ -29,6 +31,7 @@ Per sviluppare Sophon sono usati i seguenti strumenti:
.. _Continuous Deployment: https://en.wikipedia.org/wiki/Continuous_deployment .. _Continuous Deployment: https://en.wikipedia.org/wiki/Continuous_deployment
.. _CodeQL: https://codeql.github.com/ .. _CodeQL: https://codeql.github.com/
.. _GitHub Containers: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry .. _GitHub Containers: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry
.. _Sphinx: https://www.sphinx-doc.org/
.. seealso:: .. seealso::

View file

@ -8,7 +8,7 @@ L'app `sophon.projects` è un app secondaria che dipende da `sophon.core` che in
.. caution:: .. caution::
Anche se l'app `sophon.projects` è opzionale (il progetto può funzionare senza di essa), si sconsiglia di disattivarla, in quanto il :ref:`modulo frontend` si aspetta che l'app sia attiva e solleverà un errore nel caso il viewset fornito da questa app non sia disponibile. Anche se l'app `sophon.projects` è opzionale (il progetto può funzionare senza di essa), si sconsiglia di disattivarla, in quanto il :ref:`modulo frontend` si aspetta che l'app sia attiva e solleverà un errore nel caso che i viewset forniti da questa app non siano disponibile.
Modello del progetto di ricerca Modello del progetto di ricerca

View file

@ -4,3 +4,111 @@ L'app sophon.notebooks
.. default-role:: obj .. default-role:: obj
.. module:: sophon.notebooks .. module:: sophon.notebooks
L'app `sophon.notebooks` è un app secondaria che dipende da `sophon.projects` che introduce in Sophon il concetto di :ref:`notebook`.
.. caution::
Anche se l'app `sophon.notebooks` è opzionale (il progetto può funzionare senza di essa), si sconsiglia di disattivarla, in quanto il :ref:`modulo frontend` si aspetta che l'app sia attiva e solleverà un errore nel caso che i viewset forniti da questa app non siano disponibile.
Funzionamento di un notebook
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Internamente, un notebook non è altro che un container Docker accessibile ad un determinato indirizzo il cui stato è sincronizzato con un oggetto del database del :ref:`modulo backend`.
Modalità sviluppo
"""""""""""""""""
Per facilitare lo sviluppo di Sophon, sono previste due modalità di operazione di quest'ultimo:
- nella prima, la **modalità sviluppo**, il :ref:`modulo proxy` non è in esecuzione, ed è possibile collegarsi direttamente ai container attraverso collegamenti a ``localhost``;
- nella seconda, la **modalità produzione**, il :ref:`modulo proxy` è in esecuzione all'interno di un container Docker, e si collega agli altri container attraverso i rispettivi network Docker agli indirizzi comunicatogli dal :ref:`modulo backend`.
.. image:: notebooks_diagram.png
Gestione della rubrica del proxy
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.notebooks.apache
Viene creata una classe per la gestione della rubrica del proxy, utilizzando il modulo `dbm.gnu`, supportato da HTTPd.
.. class:: ApacheDB
Classe che permette il recupero, la creazione, la modifica e l'eliminazioni di chiavi di un database `dbm.gnu` come se quest'ultimo fosse un `dict` con supporto a chiavi e valori `str` e `bytes`.
.. staticmethod:: convert_to_bytes(item: typing.Union[str, bytes]) -> bytes
Tutte le `str` passate a questa classe vengono convertite in `bytes` attraverso questa funzione, che effettua un encoding in ASCII e solleva un errore se quest'ultimo fallisce.
Assegnazione porta effimera
^^^^^^^^^^^^^^^^^^^^^^^^^^^
In modalità sviluppo, è necessario trovare una porta libera a cui rendere accessibile i container Docker dei notebook.
.. function:: get_ephemeral_port() -> int
Questa funzione apre e chiude immediatamente un `socket.socket` all'indirizzo ``localhost:0`` in modo da ricevere dal sistema operativo un numero di porta sicuramente libero.
Modello dei notebook
^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.notebooks.models
Viene definito il modello rappresentante un :ref:`notebook`.
.. class:: Notebook(SophonGroupModel)
.. attribute:: slug: SlugField
.. attribute:: project: ForeignKey → sophon.projects.models.ResearchProject
.. attribute:: name: CharField
.. attribute:: locked_by: ForeignKey → django.contrib.auth.models.User
.. attribute:: container_image: CharField ["ghcr.io/steffo99/sophon-jupyter"]
.. attribute:: jupyter_token: CharField
Il token segreto che verrà passato attraverso le variabili di ambiente al container Docker dell'oggetto per permettere solo agli utenti autorizzati di accedere a quest'ultimo.
.. attribute:: container_id: CharField
.. attribute:: port: IntegerField
La porta assegnata al container Docker dell'oggetto nel caso in cui Sophon sia avviato in "modalità sviluppo", ovvero con il :ref:`modulo proxy` in esecuzione sul sistema host.
.. attribute:: internal_url: CharField
L'URL a cui è accessibile il container Docker dell'oggetto nel caso in cui Sophon non sia avviato in "modalità sviluppo", ovvero con il :ref:`modulo proxy` in esecuzione all'interno di un container.
.. method:: log(self) -> logging.Logger
:property:
Viene creato un `logging.Logger` per ogni oggetto della classe, in modo da facilitare il debug relativo ad uno specifico notebook.
Il nome del logger ha la forma :samp:`sophon.notebooks.models.Notebook.{NOTEBOOK_SLUG}`.
.. method:: enable_proxying(self) -> None
Aggiunge l'indirizzo del notebook alla rubrica del proxy.
.. method:: disable_proxying(self) -> None
Rimuove l'indirizzo del notebook dalla rubrica del proxy.
.. method:: sync_container(self) -> t.Optional[docker.models.containers.Container]
Sincronizza lo stato dell'oggetto nel database con lo stato del container Docker nel sistema.
.. method:: create_container(self) -> docker.models.containers.Container
Crea e configura un container Docker per l'oggetto, con l'immagine specificata in `.container_image`.
.. method:: stop_container(self) -> None
Arresta il container Docker dell'oggetto.
.. method:: sleep_until_container_has_started(self) -> None
Attende che il container Docker dell'oggetto si sia avviato.

View file

@ -10,6 +10,12 @@ Il *modulo backend* consiste in un server web che espone un'API e un sito web pe
È formato dal package Python `sophon`, che contiene al suo interno un progetto Django, che a sua volta contiene le tre app Django `sophon.core`, `sophon.projects` e `sophon.notebooks`. È formato dal package Python `sophon`, che contiene al suo interno un progetto Django, che a sua volta contiene le tre app Django `sophon.core`, `sophon.projects` e `sophon.notebooks`.
.. note::
A causa della dipendenza di Django da variabili globali, è stato impossibile utilizzare lo strumento di documentazione automatica `sphinx.ext.autodoc`.
Pertanto, si è deciso di documentare soltanto le classi e metodi più rilevanti ai fini di questa documentazione.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1

Binary file not shown.

View file

@ -26,13 +26,11 @@ Il modulo è composto da un singolo ``Dockerfile`` che crea un immagine Docker i
# Set the maintainer label # Set the maintainer label
LABEL maintainer="Stefano Pigozzi <me@steffo.eu>" LABEL maintainer="Stefano Pigozzi <me@steffo.eu>"
#. **Env**: Configura le variabili di ambiente dell'immagine, dando il nome "sophon" all'utente non-privilegiato, attivando JupyterLab, configurando il riavvio automatico di Jupyter e permettendo all'utente non-privilegiato di acquisire i privilegi di root attraverso il comando ``sudo``; #. **Env**: Configura le variabili di ambiente dell'immagine, attivando JupyterLab, configurando il riavvio automatico di Jupyter e permettendo all'utente non-privilegiato di acquisire i privilegi di root attraverso il comando ``sudo``;
.. code-block:: docker .. code-block:: docker
FROM base AS env FROM base AS env
# Override the default "jovyan" user
ARG NB_USER="sophon"
# Set useful envvars for Sophon notebooks # Set useful envvars for Sophon notebooks
ENV JUPYTER_ENABLE_LAB=yes ENV JUPYTER_ENABLE_LAB=yes
ENV RESTARTABLE=yes ENV RESTARTABLE=yes

View file

@ -34,7 +34,8 @@ Si è cercato di mantenere il registro di ciascuna parte al livello tecnico del
3_dev/1_tools/index 3_dev/1_tools/index
3_dev/2_structure/index 3_dev/2_structure/index
3_dev/3_differences/index 3_dev/3_differences/index
3_dev/4_license/index 3_dev/4_tests/index
3_dev/5_license/index
Pagine speciali Pagine speciali

View file

@ -6,8 +6,6 @@ LABEL maintainer="Stefano Pigozzi <me@steffo.eu>"
FROM base AS env FROM base AS env
# Override the default "jovyan" user
ARG NB_USER="sophon"
# Set useful envvars for Sophon notebooks # Set useful envvars for Sophon notebooks
ENV JUPYTER_ENABLE_LAB=yes ENV JUPYTER_ENABLE_LAB=yes
ENV RESTARTABLE=yes ENV RESTARTABLE=yes