all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Sergio Pastor Pérez" <sergio.pastorperez@outlook.es>
To: guix-devel@gnu.org
Cc: michal_atlas+gnu@posteo.net
Subject: System deployment commands hoarding all RAM
Date: Sun, 26 May 2024 14:44:52 +0200	[thread overview]
Message-ID: <AS8P251MB0337E3439FE24C98DA02D6BBF3F72@AS8P251MB0337.EURP251.PROD.OUTLOOK.COM> (raw)

Hello all.

Michal and I have been experimenting with a recursive function to apply
procedures to all elements that match a certain type within a
collection.

With this new procedure one could write something like this:
--8<---------------cut here---------------start------------->8---
(apply-to-record-type
  (lambda (_)
    (@ (gnu packages games) cowsay))
  (@ (guix packages) <package>)
  my-operating-system)
--8<---------------cut here---------------end--------------->8---

Which will replace every package on the system for the cowsay
package. Albeit a cowsified OS will not be very useful, other kinds of
transformations could greatly simplify OS definitions. It would make it
very convenient to deploy systems with grafts on important libraries
that are part of many packages. A more useful example would be this
syntax rule:
--8<---------------cut here---------------start------------->8---
(define-syntax-rule (custom-libc-operating-system exp ...)
  "Like 'operating-system' but graft 'libc' with the a custom 'libc'
package."
  (apply-to-record-type
    replace-libc
    (@ (guix packages) <package>)
    (operating-system exp ...)))
--8<---------------cut here---------------end--------------->8---

Which, if `replace-libc` grafts your custom libc using
`package-input-rewriting`, would allow you to define a system like so:
--8<---------------cut here---------------start------------->8---
(custom-libc-operating-system
  ...)
--8<---------------cut here---------------end--------------->8---

Instead of having to manually apply the function to every package in the
system which is very cumbersome to do for packages within services.

The function that provides this convenience is this one:
--8<---------------cut here---------------start------------->8---
(define (apply-to-record-type fn type var)
  "Recursing into child fields, apply FN to every element of VAR which holds a
value of TYPE."
  (let ((type-predicate (record-predicate type)))
    (cond ((type-predicate var)
           (fn var))
          ((procedure? var)
           (lambda args
             (apply values
                    (map
                     (lambda (var)
                       (apply-to-record-type fn type var))
                     (call-with-values
                         (lambda () (apply var args))
                       list)))))
          ((list? var)
           (map (lambda (elt)
                  (apply-to-record-type fn type elt))
                var))
          ((vector? var)
           (vector-map (lambda (vec elt)
                         (apply-to-record-type fn type elt))
                       var))
          ((and (record? var)
                (not (eq? (@ (gnu services) <service-type>)
                          (record-type-descriptor var))))
           (let* ((record-type (record-type-descriptor var))
                  (record-fields (record-type-fields record-type)))
             (apply
              (record-constructor record-type)
              (map (lambda (field)
                     (let* ((accessor (record-accessor record-type field))
                            (val (accessor var)))
                       (apply-to-record-type fn type val)))
                   record-fields))))
          (else
           var))))
--8<---------------cut here---------------end--------------->8---

During our testing, we have observed that it successfully applies the
function to every element of the record and it's child. Also, innocuous
transformations output the same system derivation. For example:
--8<---------------cut here---------------start------------->8---
(apply-to-record-type
   (lambda (var)
     var)
   (@ (guix packages) <package>)
   my-operating-system)
--8<---------------cut here---------------end--------------->8---

Should return the same OS applied or not, since it is not doing
anything. And, as expected, we see:
--8<---------------cut here---------------start------------->8---
λ guix system build sheepbook.scm
/gnu/store/kpk9la4h9xwp6n7vabd5lfs6kbhb2f2d-system

λ guix system build transformed-sheepbook.scm
/gnu/store/kpk9la4h9xwp6n7vabd5lfs6kbhb2f2d-system
--8<---------------cut here---------------end--------------->8---

All this is well and good but we have noticed this issue when trying to
deploy the system. Issuing the `reconfigure` or `vm` subcomands hoards
all the RAM of the system until the OS kills the process. This is the
output when trying to build the images:
--8<---------------cut here---------------start------------->8---
λ guix system vm sheepbook.scm
/gnu/store/c3pv8hwckbl01qacdpckn9yfwr74k629-run-vm.sh

λ guix system vm transformed-sheepbook.scm 
Killed
--8<---------------cut here---------------end--------------->8---

Monitoring the RAM usage of the second process, one can see that it will
take all the RAM available. Given that both system definitions produce
the same output, I would expect the deployment process to be identical.

Is this a bug on how Guix deploys the system? Or the transformation we
are applying introduces a cycle somewhere that only affects the
deployment commands?

Thanks for your time. Have a nice evening.
Sergio.


             reply	other threads:[~2024-05-26 12:50 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-26 12:44 Sergio Pastor Pérez [this message]
  -- strict thread matches above, loose matches on Subject: below --
2024-06-02 22:10 System deployment commands hoarding all RAM Juliana Sims
2024-06-10 18:02 ` Sergio Pastor Pérez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AS8P251MB0337E3439FE24C98DA02D6BBF3F72@AS8P251MB0337.EURP251.PROD.OUTLOOK.COM \
    --to=sergio.pastorperez@outlook.es \
    --cc=guix-devel@gnu.org \
    --cc=michal_atlas+gnu@posteo.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.