From patchwork Mon Sep 20 22:25:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jesse Gibbons X-Patchwork-Id: 33219 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 93FEF27BBE4; Mon, 20 Sep 2021 23:34:52 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H2, SPF_HELO_PASS,T_DKIM_INVALID,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id D63D127BBE1 for ; Mon, 20 Sep 2021 23:34:51 +0100 (BST) Received: from localhost ([::1]:41516 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mSRsB-0000Pk-08 for patchwork@mira.cbaines.net; Mon, 20 Sep 2021 18:34:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41726) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mSRje-0004gc-Md for guix-patches@gnu.org; Mon, 20 Sep 2021 18:26:04 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:60931) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mSRje-000569-Fi for guix-patches@gnu.org; Mon, 20 Sep 2021 18:26:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1mSRje-0000jH-C5 for guix-patches@gnu.org; Mon, 20 Sep 2021 18:26:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#50708] [PATCH] gnu: web: Add jupyter-service Resent-From: Jesse Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 20 Sep 2021 22:26:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 50708 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 50708@debbugs.gnu.org X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.16321767562786 (code B ref -1); Mon, 20 Sep 2021 22:26:02 +0000 Received: (at submit) by debbugs.gnu.org; 20 Sep 2021 22:25:56 +0000 Received: from localhost ([127.0.0.1]:44244 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mSRjY-0000ir-2I for submit@debbugs.gnu.org; Mon, 20 Sep 2021 18:25:56 -0400 Received: from lists.gnu.org ([209.51.188.17]:54398) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mSRjV-0000ig-LR for submit@debbugs.gnu.org; Mon, 20 Sep 2021 18:25:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41686) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mSRjR-0004X3-OC for guix-patches@gnu.org; Mon, 20 Sep 2021 18:25:53 -0400 Received: from mail-pl1-x630.google.com ([2607:f8b0:4864:20::630]:34523) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mSRjO-0004v2-Oi for guix-patches@gnu.org; Mon, 20 Sep 2021 18:25:49 -0400 Received: by mail-pl1-x630.google.com with SMTP id a7so3397866plm.1 for ; Mon, 20 Sep 2021 15:25:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:subject:to:message-id:date:user-agent:mime-version :content-language; bh=thbxJPHfEQ1dJ0W8SVrkY2HYxLO7oMMAN2QuFO0/pb4=; b=qUue2kPBinJjtIS6te7ql56K+GTI8Vk8mQk/eoWo959NaKkCuJKIp2nfoJNsKkd1iu AopOzbVyd6j5ww5d5AQElRxIZT9DTkPsvDrLj6YBIMwgyw0T76fZE1TRIg6lZfW5rMPG aRZ5+VoVHd5mKlx0dMXUPaAsY1DdvZEM0DUJNnX7tCtvhu8xdPMHon/purUcSB210f8p CxiLwjnz00vM02/dhryDs7uKEDNSG6g98CMSZ6X2djMrqd3Msx0+CowJQXhCSKnz3kpg BmnObeqfUx3ocnim+ZA9g2SHnzMlaGLya0s5ge7FiP5mFh1FAC9ujOFkKIj47/gNn/ok MHHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-language; bh=thbxJPHfEQ1dJ0W8SVrkY2HYxLO7oMMAN2QuFO0/pb4=; b=UjwwJ6LtLTkpvLeCtmwuKTgWMAuVLZaZ2riWoiz2TEXdoot9PUKX6vJUE81sw2t3IO HYpE8bk7mf/NPISMm6cHp6Vp63Bzb8Kwo7DgcPyboZDQGX7VzVsk56U3nZxdYrklTiD7 WeiN7u4PSSjYtqt+n+vpMYj5RRrAwpNWd0+0i3W5tawogSFxzxbqz9SSdfS1NnTGTBPd yoWo0FA4lhO9FV/RddxT9U7T3jMKrA/+G/W9SQmj4P+GVfvC7fvwoz7HepNgX1on8N/O Q0v9VC58kx00uqaMDGXW5gU9SIV+S8+i/79N3xJWOJHFtlIn9ezEIzdHKhL1PSUz/Jq8 tV6g== X-Gm-Message-State: AOAM532+zn/HqEikG+1/9Iq+qp9ZzgHkMlYU/K2e517TfO7dT2kvvTYH plXwQSKkTnChBZ/Ug6sslu+n4KoweiwFxQ== X-Google-Smtp-Source: ABdhPJzQ1YteXFoZJW/3pLeQDcCHyzCdc91+2rRx6IL/nK6bgAXcs5zsJhSiBV6dOkZtjShySymZCA== X-Received: by 2002:a17:902:bd45:b0:13d:b4d1:eb39 with SMTP id b5-20020a170902bd4500b0013db4d1eb39mr4875375plx.53.1632176744533; Mon, 20 Sep 2021 15:25:44 -0700 (PDT) Received: from [192.168.1.220] ([38.141.58.134]) by smtp.gmail.com with ESMTPSA id c16sm15008872pfo.163.2021.09.20.15.25.43 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 20 Sep 2021 15:25:43 -0700 (PDT) From: Jesse Message-ID: <565a1b21-aefa-4129-a024-52517fdff9bd@gmail.com> Date: Mon, 20 Sep 2021 16:25:42 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Icedove/78.13.0 MIME-Version: 1.0 Content-Language: en-US Received-SPF: pass client-ip=2607:f8b0:4864:20::630; envelope-from=jgibbons2357@gmail.com; helo=mail-pl1-x630.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches The attached patch adds the jupyter service, which automatically starts a jupyter notebook server at startup. It also includes documentation for the Jupyter service. Go ahead, tell me how awful it is. -Jesse From ab82ebef9666f57c53342d042f21303b3babcb4b Mon Sep 17 00:00:00 2001 From: Jesse Date: Mon, 20 Sep 2021 16:01:22 -0600 Subject: [PATCH] gnu: web: Add jupyter-service * gnu/services/web.scm (gitile-service-type): New variable. * doc/guix.texi (Version Control Services): Document it. --- doc/guix.texi | 52 +++++++++++++++++++ gnu/services/web.scm | 120 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/doc/guix.texi b/doc/guix.texi index 6436e83a7c..0f8aaca413 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -26197,6 +26197,58 @@ The file which should store the logging output of Agate. @end table @end deftp +@cindex jupyter +The Jupyter Notebook is a web application that allows you to create +and share documents that contain live code, equations, visualizations +and explanatory text. Uses include: data cleaning and transformation, +numerical simulation, statistical modeling, machine learning and much +more. + +@deffn (Scheme Variable) jupyter-service-type +This is the type of the agate service, whose value should be an +@code{jupyter-service-type} object, as in this example: + +@lisp +(service jupyter-service-type + (jupyter-configuration + (log-file "/var/log/jupyter.log") + (server-config + (kernels + (list jupyter-guile-kernel))))) + +@end lisp + +The example above tells the the Jupyter service to provide the +@code{jupyter-guile-kernel} as an optional kernel. +@end deffn + +@deftp {Data Type} jupyter-configuration +Data type representing the configuration of Agate. + +@table @asis +@item @code{jupyter-package} (default: @code{jupyter}) +The jupyter package to use. + + +@item @code{kernels} (default: @code{'()} +A list of kernel packages to use with the jupyter service. + +@item @code{root-dir} (default: @file{"/var/lib/jupyter/notebooks"}) +The directory where the jupyter server looks for jupyter notebooks. + +@item @code{log-file} (default: @code{#f}) +The location of the log file. If #f is given, no log is produced. + +@item @code{shell} (default: @code{(file-append bash "/bin/bash")} +The location of the shell used when starting a web terminal (if it is configured to allow terminals). + +@item @code{server-config} (default: @code{#f}) +A file contianing the jupyter server's config file. If @code{#f} is given, an empty file is produced, and the default settings are used. + +@end table +@end deftp + + @node Certificate Services @subsection Certificate Services diff --git a/gnu/services/web.scm b/gnu/services/web.scm index 6a093cf4e4..2ceaa20864 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -15,6 +15,7 @@ ;;; Copyright © 2020 Arun Isaac ;;; Copyright © 2020 Oleg Pykhalov ;;; Copyright © 2020, 2021 Alexandru-Sergiu Marton +;;; Copyright © 2020, 2021 Jesse Gibbons ;;; ;;; This file is part of GNU Guix. ;;; @@ -41,11 +42,13 @@ #:use-module (gnu system shadow) #:use-module (gnu packages admin) #:use-module (gnu packages base) + #:use-module (gnu packages bash) #:use-module (gnu packages databases) #:use-module (gnu packages web) #:use-module (gnu packages patchutils) #:use-module (gnu packages php) #:use-module (gnu packages python) + #:use-module (gnu packages python-xyz) #:use-module (gnu packages gnupg) #:use-module (gnu packages guile) #:use-module (gnu packages logging) @@ -91,6 +94,8 @@ httpd-service-type + jupyter-configuration + nginx-configuration nginx-configuration? nginx-configuration-nginx @@ -1994,3 +1999,118 @@ root=/srv/gemini (service-extension shepherd-root-service-type agate-shepherd-service))) (default-value (agate-configuration)))) + + +;;; Jupyter configuration +;;; Jupyter server configuration +;;; -> includes a list of kernels to allow in the jupyter server +;;; -> includes a list of configuration options specifically for the jupyter server +;;; --> These options can be concatenated to a python file +;;; --> Nested alist +;;; ---> '((NotebookApp (allow-remote-access #t))) -> "c.NotebookApp.allow_remote_access = True" +;;; -> Include some settings specifying how to run the daemon +;;; --> location of log file +;;; --> If a console should be allowed, the location of the shell to be used. +;;; --> The package containing the jupyter server itself, default jupyter +(define-public default-jupyter-config "#") + +(define-record-type* jupyter-configuration + this-jupyter-configuration jupyter-configuration? + (jupyter-package jupyter-configuration-jupyter-package + (default jupyter)) + (kernels jupyter-configuration-kernels + (default '())) + (root-dir jupyter-configuration-root-dir + (default "/var/lib/jupyter/notebooks")) + (log-file jupyter-configuration-log-file + (default #f)) + (shell jupyter-configuration-shell + (default (file-append bash "/bin/bash"))) + (server-config jupyter-configuration-server-config + (default #f))); TODO: Make configuration DSL. + + +(define (search-path-string search-path-pair) + (string-append (search-path-specification-variable (car search-path-pair)) + "=" + (cdr search-path-pair))) + +;;;TODO: Add actions to list jupyter servers, change passwords, etc. +(define (jupyter-shepherd-service config) + (list (shepherd-service + (provision '(jupyter)) ;TODO: Add magic to allow multiple Jupyter servers + (requirement '(loopback)) + (start #~(make-forkexec-constructor + (list "/run/current-system/profile/bin/jupyter" + "notebook" + (string-append "--config=" + #$(or (jupyter-configuration-server-config config) + (plain-file "jupyter_notebook_config.py" + default-jupyter-config)) + #$(jupyter-configuration-root-dir config)) + #:user "jupyter" + #:group "jupyter" + #:environment-variables ; TODO use search-paths magic instead of hard-coding these things. + (list "GI_TYPELIB_PATH=/run/current-system/profile/lib/girepository-1.0" + "GUILE_LOAD_COMPILED_PATH=/run/current-system/profile/lib/guile/3.0/site-ccache:/run/current-system/profile/share/guile/site/3.0" + "GUILE_LOAD_PATH=/run/current-system/profile/share/guile/site/3.0" + "HOME=/var/lib/jupyter" + "JUPYTER_PATH=/run/current-system/profile/share/jupyter" + "PATH=/run/current-system/profile/bin:/run/current-system/profile/sbin" + "PYTHONPATH=/run/current-system/profile/lib/python3.8/site-packages" + "R_LIBS_SITE=/run/current-system/profile/site-library/" + "TEXMF=/run/current-system/profile/share/texmf-dist" + "TEXMFCNF=/run/current-system/profile//share/texmf-dist/web2c" + "XDG_DATA_DIRS=/run/current-system/profile/share") + + #:directory #$(jupyter-configuration-root-dir config) + #:log-file #$(jupyter-configuration-log-file config))) + (stop #~(make-kill-destructor)) + (documentation "Runs a Jupyter Notebook server. A Jupyter Notebook is a web application that allows you to create and share documents that contain live code, equations, visualizations, and explanatory text.")))) + +(define (jupyter-account config) + (list + (user-account + (name "jupyter") + (group "jupyter") + (comment "Jupyter Notebook Server") + (home-directory "/var/lib/jupyter") + (shell (jupyter-configuration-shell config)) + (system? #t)) + (user-group + (name "jupyter") + (system? #t)))) + +(define (jupyter-profile config) + (cons* + (jupyter-configuration-jupyter-package config) + (jupyter-configuration-kernels config))) + +(define (jupyter-activation config) + #~(begin + (let ((root-dir #$(jupyter-configuration-root-dir config)) + (pw (getpwnam "jupyter"))) + (unless (file-exists? root-dir) + (mkdir root-dir) + (chown root-dir (passwd:uid pw) + (passwd:gid pw)) + (chmod root-dir #o700))))) + +;;; Jupyter service type +;;; -> Information vital to settinng up the server, like the port and accepted parameters +;;; -> list of kernels considered permissible. +;;; -> a shepherd service extension that runs the jupyter server +;;; --> shepherd service to list the running servers, set the password, etc. +;;; --> Make a log file only readable by root? +;;; -> an accounts service extension describing the user that runs the accounts +;;; --> group "jupyter" +(define-public jupyter-service-type + (service-type + (name "jupyter") + (extensions (list + (service-extension shepherd-root-service-type jupyter-shepherd-service) + (service-extension account-service-type jupyter-account) + (service-extension activation-service-type jupyter-activation) + (service-extension profile-service-type jupyter-profile))) + (description "Runs a Jupyter Notebook server. A Jupyter Notebook is a web application that allows you to create and share documents that contain live code, equations, visualizations, and explanatory text.") + (default-value (jupyter-configuration))))