mirror of
https://github.com/Steffo99/sophon.git
synced 2024-12-22 14:54:22 +00:00
💥 I'm not sure I understand what I'm writing anymore.
This commit is contained in:
parent
4f467b242a
commit
b88c592aab
12 changed files with 155 additions and 12 deletions
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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={
|
||||||
|
|
|
@ -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},
|
||||||
|
)
|
||||||
|
|
|
@ -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::
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
BIN
docs/source/3_dev/2_structure/1_backend/notebooks_diagram.png
(Stored with Git LFS)
Normal file
BIN
docs/source/3_dev/2_structure/1_backend/notebooks_diagram.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue