From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id eOL/Iptv0WKgNAAAbAwnHQ (envelope-from ) for ; Fri, 15 Jul 2022 15:46:03 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id oJzYIZtv0WKbZQAAG6o9tA (envelope-from ) for ; Fri, 15 Jul 2022 15:46:03 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 51678F0C4 for ; Fri, 15 Jul 2022 15:46:02 +0200 (CEST) Received: from localhost ([::1]:33020 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oCLdp-0006Fp-EV for larch@yhetil.org; Fri, 15 Jul 2022 09:46:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52772) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oCLbO-0004LY-H9 for guix-devel@gnu.org; Fri, 15 Jul 2022 09:43:31 -0400 Received: from mail-qv1-xf30.google.com ([2607:f8b0:4864:20::f30]:44004) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oCLbM-000635-8J for guix-devel@gnu.org; Fri, 15 Jul 2022 09:43:30 -0400 Received: by mail-qv1-xf30.google.com with SMTP id m6so3682905qvq.10 for ; Fri, 15 Jul 2022 06:43:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=JdaWL6/EbCILSNc9UAIO34FyC+WbHuj5/De7LSernAU=; b=hunlWFRQ5N0kGSTphqKDPnigI/DFnJy4hhuxenDoh2TNA3r8UTe+VNwTknRJ0eeL0J JtMp2S8SOo9BgPk/vt326OwtMy/ZcPWeg/7+/HYprKJME53FRgMYY/UkwlEtWWzUp73v CFnEq0LkGCfZV21hNagdy97ByF/S7JHIhAA6KtDT2w3a9Oa5eovVKuZdvRpTCbxdffDH r3TfvWSIG62HXvTrCmEvdBFfeGERcWWu+kdGMgeg4ihJ7d8not9df+/4EQEMspdGuy+y W5r9pBQZB5uoKOQYBSHYZ8ZpU00hBZkpvIKVMFmjrhnIhRy/eKH1uWq/C4MezD6r+HjT OeQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=JdaWL6/EbCILSNc9UAIO34FyC+WbHuj5/De7LSernAU=; b=j5fVW3/vcZ7YwEX5kyODd9wlcfgsOasCGfPhbhltj7Vq2xc90FTaINX4YiKyW1OX1S 7gPESRzP2gqls9yzXgsvAiw1nNHOPwHvf9fkRWNMIK8dNKFBjdHgK2vmYqRh0U6A6FJt L3suKWdmCR/R9cYQZmfBUFlrU+Pe6K07jRAcmA0v16OlHfmTI/XSky/DsbGUyhtY1FNT vvA7p4XdusG67loZFkv0tOuvH3dCmH4nAQCdlCBLX+EiD+PA3qY8/OMnmp52K5qcN6q5 PEI5JE/HJN7Ko/1340eSgC+SRHXhi3lXO/g+KuPsD/HMimtldZOC3V4iHEPO+08jDJgR O9+w== X-Gm-Message-State: AJIora+1Dzcmml58dHrCfi2HZOreSDQNMiDNgxdswcb0M//KwRNsKwyT GvQXALUN6vgDFquKXKaXHfDs0COhWIL/GQ== X-Google-Smtp-Source: AGRyM1vCEIDIzTwSDJxxW3ZC4b/mceDp4nYOdUVXxdJv7EG0/LbnuaMa6MTmT+C6MQ///HUQCSpNxA== X-Received: by 2002:a05:6214:519b:b0:473:1c23:f871 with SMTP id kl27-20020a056214519b00b004731c23f871mr11706087qvb.28.1657892606127; Fri, 15 Jul 2022 06:43:26 -0700 (PDT) Received: from hurd (dsl-205-233-125-176.b2b2c.ca. [205.233.125.176]) by smtp.gmail.com with ESMTPSA id i21-20020a05620a405500b006b5cd76a2e7sm2077276qko.111.2022.07.15.06.43.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 06:43:25 -0700 (PDT) From: Maxim Cournoyer To: John Kehayias Cc: "guix-devel@gnu.org" Subject: Re: [WIP Patch] Adding an FHS container to guix shell References: Date: Fri, 15 Jul 2022 09:43:24 -0400 In-Reply-To: (John Kehayias's message of "Tue, 12 Jul 2022 15:59:14 +0000") Message-ID: <871qumwkxv.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass client-ip=2607:f8b0:4864:20::f30; envelope-from=maxim.cournoyer@gmail.com; helo=mail-qv1-xf30.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guix-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+larch=yhetil.org@gnu.org Sender: "Guix-devel" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1657892762; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post:dkim-signature; bh=JdaWL6/EbCILSNc9UAIO34FyC+WbHuj5/De7LSernAU=; b=Lrira2ZEO0oPZikE5QIOkkFKX7Ab/Nxeb3aokLulisitYf7RLAmpxc/PZNHFckALeI/Iew mvDO0zzseZFU0ckBLHXmlelg5T0D+iDGRt9YtPd9rh1RlqUm+KOFnRKDNdJXIKKbXZd6o5 kybNFY7EMn/2cQvCpqYJU5vazIbpPXSoTEVyIkBiB3+iOb3YV8oCBsFnHBl9iJ8IT7Qg7K Psw9FgdIBRHGJmFzR47deJ4cKOKbud0a8E4J3RyquV7PJusYrT2sGNjscVaGjZ4iAyR/8z AM49859LQKqhRXjbZQgxW6ZcurTGfFTuS84rkQDrJcXbAz/9rOqxu241Fc7PnA== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1657892762; a=rsa-sha256; cv=none; b=fbF3u6AAMXSX8+bfnYLcyagNpLbOikVglVOzGoFRRCnrOUKHT196/UXCLKX0o1kes6EcmZ zFKP6/jVm1w/+zs3Vb0zDpFGPKn/+3yrrVQ0eK3N9KSDDahQz30+aMI/p6LqRNSrYYmSBW B/pmAvYQpcSOqHgh+Pt60rCQef/9ds2n/nEZaBOYiyfZBSn0LzRimugWOhwCd/BYbykW8u aJk/vAOHK2hli/zfmUn+gCjjFhGdOuwuYnvHiZKQwLTwzgs1t7MeLd3Jv7PIhE97jnKq0/ 8jePtYvpdtS/ezZ2fZUrwUTWmZaAzrx4E6ekF241hEzeK7LpxMB95cHR94j7rA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=hunlWFRQ; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -3.95 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=hunlWFRQ; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 51678F0C4 X-Spam-Score: -3.95 X-Migadu-Scanner: scn0.migadu.com X-TUID: Box01QJFiUUL Hi John, John Kehayias writes: > Hi Guixers, > > Apologies for the long email, so let me start with the punchline: > attached is a diff which adds an '--fhs-container' (or -F) option to > guix shell/environment to set up an FHS-like container. This includes > the usual /lib directory and a glibc which loads (a generated in the > container) /etc/ld.so.cache. This should allow running most things > that expect a more "typical" Linux environment. Give it a try! Neat hack! [...] > diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm > index 4bdc3e7792..1b4c99d3e9 100644 > --- a/gnu/packages/base.scm > +++ b/gnu/packages/base.scm > @@ -928,6 +928,20 @@ (define-public glibc > (license lgpl2.0+) > (home-page "https://www.gnu.org/software/libc/"))) > > +;; Define glibc-for-fhs (with a name that allows grafts for glibc), a va= riation > +;; of glibc which uses the default ld.so.cache, useful in FHS containers. > +;; Note: should this be hidden? ^ This should definitely be hidden since it's for internal consumption only. Also, if grafting ended up not being needed, the variable should eb renamed 'glibc-for-fhs', an mentions of grafting in the comments removed. > +(define-public gcfhs > + (package > + (inherit glibc) > + (name "gcfhs") > + (source (origin (inherit (package-source glibc)) > + ;; Remove Guix's patch to read ld.so.cache from /gnu= /store > + ;; directories, re-enabling the default /etc/ld.so.c= ache > + ;; behavior. > + (patches (delete (car (search-patches "glibc-dl-cach= e.patch")) > + (origin-patches (package-source gli= bc)))))))) > + > ;; Below are old libc versions, which we use mostly to build locale data= in > ;; the old format (which the new libc cannot cope with.) > (define-public glibc-2.32 > diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm > index 3216235937..425649b843 100644 > --- a/guix/scripts/environment.scm > +++ b/guix/scripts/environment.scm > @@ -2,6 +2,7 @@ > ;;; Copyright =C2=A9 2014, 2015, 2018 David Thompson > ;;; Copyright =C2=A9 2015-2022 Ludovic Court=C3=A8s > ;;; Copyright =C2=A9 2018 Mike Gerwitz > +;;; Copyright =C2=A9 2021 John Kehayias > ;;; > ;;; This file is part of GNU Guix. > ;;; > @@ -45,6 +46,7 @@ (define-module (guix scripts environment) > #:autoload (guix build syscalls) (set-network-interface-up openpty l= ogin-tty) > #:use-module (gnu system file-systems) > #:autoload (gnu packages) (specification->package+output) > + #:autoload (gnu packages base) (gcfhs) > #:autoload (gnu packages bash) (bash) > #:autoload (gnu packages bootstrap) (bootstrap-executable %bootstrap= -guile) > #:use-module (ice-9 match) > @@ -101,6 +103,8 @@ (define (show-environment-options-help) > (display (G_ " > -C, --container run command within an isolated container")) > (display (G_ " > + -F, --fhs-container run command within an isolated FHS container")) > + (display (G_ " > -N, --network allow containers to access the network")) > (display (G_ " > -P, --link-profile link environment profile to ~/.guix-profile wit= hin > @@ -229,6 +233,10 @@ (define %options > (option '(#\C "container") #f #f > (lambda (opt name arg result) > (alist-cons 'container? #t result))) > + (option '(#\F "fhs-container") #f #f > + (lambda (opt name arg result) > + (alist-cons 'fhs-container? #t > + (alist-cons 'container? #t result)))) > (option '(#\N "network") #f #f > (lambda (opt name arg result) > (alist-cons 'network? #t result))) > @@ -606,9 +614,10 @@ (define* (launch-environment/fork command profile ma= nifest > ((_ . status) > (validate-exit-status profile command status)))))) > > -(define* (launch-environment/container #:key command bash user user-mapp= ings > - profile manifest link-profile? ne= twork? > - map-cwd? (white-list '())) > +(define* (launch-environment/container #:key command bash fhs-container?= user > + user-mappings profile manifest > + link-profile? network? map-cwd? > + (white-list '())) > "Run COMMAND within a container that features the software in PROFILE. > Environment variables are set according to the search paths of MANIFEST. > The global shell is BASH, a file name for a GNU Bash binary in the > @@ -709,6 +718,49 @@ (define* (launch-environment/container #:key command= bash user user-mappings > (mkdir-p home-dir) > (setenv "HOME" home-dir) > > + ;; Set up an FHS container. I feel like FHS should be spelled in full somewhere (in the doc would be nice). > + (when fhs-container? > + ;; Set up the expected bin and library directories as syml= inks to > + ;; the profile lib directory. Note that this is assuming = a 64bit > + ;; architecture. > + (let ((lib-dir (string-append profile "/lib"))) > + (symlink lib-dir "/lib64") I think /lib64 is not needed (see below). > + (symlink lib-dir "/lib") > + (mkdir-p "/usr") > + (symlink lib-dir "/usr/lib")) > + ;; Note: can't symlink full /bin in the container due to t= he sh > + ;; symlink. Can you explain more exactly why symlinks prevent this to work? I think I've had issues like this before (e.g., #46782), but couldn't really pinpoint the exact nature of the limitation. > + (symlink (string-append profile "/bin") "/usr/bin") > + (symlink (string-append profile "/sbin") "/sbin") > + (symlink (string-append profile "/sbin") "/usr/sbin") Other symbolic links I think we should include: * /include -> /usr/include (section 4.3 of the FHS 3.0 spec) * /libexec -> /usr/libexec (optional, section 4.7) * /share -> /usr/share (section 4.11) > + ;; Provide a frequently expected 'cc' symlink to gcc, thou= gh this > + ;; could also be done by the user in the container, e.g. in > + ;; $HOME/.local/bin and adding that to $PATH. Note: we do= this > + ;; in /bin since that already has the sh symlink and can't= write > + ;; to the other bin directories that are already symlinks = themselves. > + (symlink (string-append profile "/bin/gcc") "/bin/cc") > + ;; TODO: python may also be expected to symlink to python3. No need for a TODO, I think users wanting that could simply use 'python-wrapper', which exists for this purpose, no? > + ;; Guix's ldconfig doesn't seem to search in FHS default > + ;; locations, so provide a minimal ld.so.conf. > + ;; TODO: this may need more, e.g. libnss3 is in /lib/nss > + (call-with-output-file "/tmp/ld.so.conf" > + (lambda (port) > + (display "/lib64" port) > + (newline port))) Shouldn't this be '/lib' rather than '/lib64'? Per sections 3.9 and 3.10 of the FHS 3.0 [0], '/lib' is essential, while '/lib' is optional. [0] https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.pdf > + ;; Define an entry script to start the container: generate > + ;; ld.so.cache, supplement $PATH, and include command. > + (call-with-output-file "/tmp/fhs.sh" > + (lambda (port) > + (display "ldconfig -X -f /tmp/ld.so.conf" port) > + (newline port) > + (display "export PATH=3D/bin:/usr/bin:/sbin:/usr/sbin:= $PATH" port) > + (newline port) > + (display (car command) port) > + (newline port)))) > + > ;; If requested, link $GUIX_ENVIRONMENT to $HOME/.guix-profi= le; > ;; this allows programs expecting that path to continue work= ing as > ;; expected within a container. > @@ -746,7 +798,12 @@ (define* (launch-environment/container #:key command= bash user user-mappings > (primitive-exit/status > ;; A container's environment is already purified, so no nee= d to > ;; request it be purified again. > - (launch-environment command > + (launch-environment (if fhs-container? > + ;; Use the FHS start script. > + ;; FIXME: probably the default comm= and should > + ;; be different as it spawns a diff= erent shell? > + '("/bin/sh" "/tmp/fhs.sh") I'm not sure what could be improved here (why the FIXME?); could you explain what you had on mind in more details? > + command) > (if link-profile? > (string-append home-dir "/.guix-pro= file") > profile) > @@ -874,15 +931,16 @@ (define (guix-environment* opts) > "Run the 'guix environment' command on OPTS, an alist resulting for > command-line option processing with 'parse-command-line'." > (with-error-handling > - (let* ((pure? (assoc-ref opts 'pure)) > - (container? (assoc-ref opts 'container?)) > - (link-prof? (assoc-ref opts 'link-profile?)) > - (network? (assoc-ref opts 'network?)) > - (no-cwd? (assoc-ref opts 'no-cwd?)) > - (user (assoc-ref opts 'user)) > - (bootstrap? (assoc-ref opts 'bootstrap?)) > - (system (assoc-ref opts 'system)) > - (profile (assoc-ref opts 'profile)) > + (let* ((pure? (assoc-ref opts 'pure)) > + (container? (assoc-ref opts 'container?)) > + (fhs-container? (assoc-ref opts 'fhs-container?)) > + (link-prof? (assoc-ref opts 'link-profile?)) > + (network? (assoc-ref opts 'network?)) > + (no-cwd? (assoc-ref opts 'no-cwd?)) > + (user (assoc-ref opts 'user)) > + (bootstrap? (assoc-ref opts 'bootstrap?)) > + (system (assoc-ref opts 'system)) > + (profile (assoc-ref opts 'profile)) > (command (or (assoc-ref opts 'exec) > ;; Spawn a shell if the user didn't specify > ;; anything in particular. > @@ -927,7 +985,16 @@ (define (guix-environment* opts) > (with-store/maybe store > (with-status-verbosity (assoc-ref opts 'verbosity) > (define manifest-from-opts > - (options/resolve-packages store opts)) > + (options/resolve-packages store > + ;; For an FHS-container, add a gli= bc that uses > + ;; /etc/ld.so.cache. > + (if fhs-container? > + (alist-cons 'package '(ad-hoc-= package "gcfhs") > + opts) > + ;; Alternatively, could graft = all packages with > + ;; this glibc, though that see= ms unnecessary. > + ;; (alist-cons 'with-graft "gl= ibc=3Dgcfhs" opts) > + opts))) It's interesting that it's unnecessary. If we're confident it really is, then I'd remove this dead code and comment. > > (define manifest > (if profile > @@ -994,6 +1061,7 @@ (define (guix-environment* opts) > "/bin/sh")))) > (launch-environment/container #:command command > #:bash bash-binary > + #:fhs-container? fhs= -container? > #:user user > #:user-mappings mapp= ings > #:profile profile That's surprisingly little code, which is nice! Thanks for looking into it :-). I've yet to try it, but I will shortly. Thank you, Maxim