Naranden writes:

> On 5/19/25 00:24, James Thomas wrote:
>> Naranden writes:
>>> On 5/16/25 04:14, James Thomas wrote:
>>>> Naranden writes:
>>>>> I suppose there must be some way to make this work like Guix system
>>>>> containers, where everything the container needs is loaded from the
>>>>> store rather than through Docker.
>>>>
>>>> Why not build the 'container' script for the users and let them run it?
>>>
>>> I'm not sure what you mean. The goal isn't to ship to other users but
>>> to declare a specific, reproducible operating-system with services
>>> that can be deployed on a local (real) system, in a VM, or remotely.
>>> More specifically, the goal is to include a guix system container
>>> service in an operating-system definition--in other words,
>> 
>>> a Guix operating-system (container) nested in another operating-system
>>> (parent).
>> 
>> That's what running the script of ‘container’ in (info "(guix) Invoking
>> guix system") gets you, no?
>
> Yes, running the script written by `guix system container` does provide
> a Guix operating-system container on the local system. But the system
> must have a read-write /gnu/store and be capable of building/acquiring
> the dependencies.

That's AFAIU of "The container shares its store with the host system".
If not, have 'guix' in the OS and expose the store and daemon socket?

> For example, it does not work for guix system vm, which uses a
> read-only /gnu/store. (See example 1 below.)

Ok, but I thought:

>>>>> but I need something lightweight like containers.

>> No new 'service' should be required.
>
> The goal is to get something managed by Shepherd (so it is started at
> boot, is automatically respawned, etc.). That's why a service is
> required (unless there is some other way to accomplish those things).

I was talking about the guix-daemon being sufficient. For this:

> See example 2 below.
>
> Also I found a project that seems to maybe have a similar goal, but
> there hasn't been any activity there since about 1.5 years ago:
>
> https://github.com/BIMSBbioinfo/swineherd
>
>>> 1. I can bundle a package (and its dependencies) and run a command in a
>>> container with `guix shell --container $package -- run`. Can I set up
>>> the same thing to happen as a Shepherd-managed service (in an
>>> operating-system definition)?
>>>
>>> 2. And if that can be done, can I set the channels and use package
>>> inferiors so I would get the equivalent of `guix time-machine -C
>>> $channels -- shell ...` but in a Shepherd-managed service as in (1)?
>>>
>>> 3. And if *that* can be done, can I do the same with an entire nested
>>> operating-system as in my original question and example?! That is,
>>> equivalent to `guix time-machine -C $channels -- system vm $file` but as
>>> a Shepherd-managed service nested inside a parent operating-system
>>> definition, where the parent operating-system definition could itself be
>>> executed in a VM with `guix time-machine -C $channels -- system vm
>>> $file`. (It's amazing that this level of reproducibility might actually
>>> be possible with Guix.)
>> 
>> AFAIU your requirements, they're possible with the shepherd-transient
>> service and 'guix time-machine' prefixing the command mentioned above.
>
> I looked at transient services but from what I understand they don't run
> on boot (only the parent transient-service does). It just allows the
> user to run transient services during run-time. I am trying to run
> something at boot, managed by Shepherd.

The simple shepherd-service (with auto-start), then? To run the script
(I'm a bit confused as to your need). There's also (info "(guix)
Invoking guix container") to enter it.

>
> ======================================================================
>
> Example 1: Trying to use `guix system container` in a VM
>
> os.scm:
>
> ```
> (use-modules (gnu))
>
> (operating-system
>  (host-name "os")
>  (file-systems (cons (file-system
>                       (device (file-system-label "does-not-matter"))
>                       (mount-point "/")
>                       (type "ext4"))
>                      %base-file-systems))
>  (bootloader (bootloader-configuration
>               (bootloader grub-bootloader))))
> ```
>
>
> In the shell:
>
> ```
> $ $(guix system --no-graphic vm os.scm) -m 1G
>
> ## Log in as root
>
> # nano os.scm
>
> ## Write the above `os.scm` file inside the VM
>
> # guix system container os.scm
> guix system: error: changing ownership of path '/gnu/store': Read-only
> file system
> ```
>
> ======================================================================
>
> Example 2: mlauncher (manifest launcher) service
>
> This shows implementation and use of a rudimentary service that:
>
> - is managed by Shepherd,
> - uses a profile defined by a package manifest, and
> - runs a specified command using that profile.
>
> However:
>
> - there is no Linux container or other isolation and
> - it does not accept a Guix operating-system definition.
>
> In the context of this discussion, it may be reasonable to skip the
> "Implementing" part and go to the "Using" part.
>
> I have not found out a way to use something like the output of `(gnu
> build linux-container)` module's `(container-script os)` in
> `mlauncher-shepherd-service` below to get a container as provided by
> `guix system container`.
>
> os.scm:
>
> ```
> (use-modules (gnu bootloader))
> (use-modules (gnu bootloader grub))
> (use-modules (gnu packages))
> (use-modules (gnu services base))
> (use-modules (gnu services shepherd))
> (use-modules (gnu system file-systems))
> (use-modules (guix gexp))
> (use-modules (guix profiles))
> (use-modules (guix records))
>
> ;; Implementing the service.
> (define-record-type* <mlauncher-configuration>
>   mlauncher-configuration make-mlauncher-configuration
>   mlauncher-configuration?
>   (command mlauncher-configuration-command)
>   (manifest mlauncher-configuration-manifest)
>   (name mlauncher-configuration-name))
>
> (define (mlauncher-shepherd-service config)
>   "Return a <shepherd-service> for mlauncher with CONFIG."
>   (define mlauncher-command
>     (cons*
>      (file-append (profile
>                    (content (mlauncher-configuration-manifest config)))
>                   (car (mlauncher-configuration-command config)))
>      (cdr (mlauncher-configuration-command config))))
>   (list
>    (shepherd-service
>     (documentation "mlauncher service")
>     (provision
>      (list
>       (string->symbol
>        (string-append "mlauncher-"
>                       (mlauncher-configuration-name config)))))
>     (requirement '(syslogd))
>     (start #~(make-forkexec-constructor '#$mlauncher-command)))))
>
> (define mlauncher-service-type
>   (service-type
>    (name 'mlauncher)
>    (extensions
>     (list (service-extension shepherd-root-service-type
>                              mlauncher-shepherd-service)))
>    (description "Run a command in a profile defined by a manifest.")))
>
> ;; Using the service.
> (define test-manifest
>   (specifications->manifest
>    (list
>     "python-minimal")))
>
> (define test-mlauncher-service
>   (service
>    mlauncher-service-type
>    (mlauncher-configuration
>     (command
>      (list
>       "/bin/python3"
>       "-c"
>       "import sys,time;print('hi',file=sys.stderr);time.sleep(60)"))
>     (manifest test-manifest)
>     (name "test"))))
>
> (define runner-mlauncher-service
>   (service mlauncher-service-type
>            (mlauncher-configuration
>             (command (list "/bin/runner"))
>             (manifest test-manifest)
>             (name "runner"))))
>
> (operating-system
>  (host-name "host-os")
>  (file-systems (cons (file-system
>                       (device (file-system-label "does-not-matter"))
>                       (mount-point "/")
>                       (type "ext4"))
>                      %base-file-systems))
>  (bootloader (bootloader-configuration
>               (bootloader grub-bootloader)))
>  (services
>   (cons* test-mlauncher-service %base-services)))
> ```
>
> In the shell:
>
> ```
> $ $(guix system --no-graphic vm os.scm) -m 1G
>
> ## Log in as root
>
> # herd status mlauncher-test
> ● Status of mlauncher-test:
>   It is running since 07:14:51 PM (38 seconds ago).
>   Main PID: 105
>   Command:
> /gnu/store/yf4k9v2kw3hcy2567pf30m3r2l4800gc-profile/bin/python3 -c
> "import sys,time;print('hi',file=sys.stderr);time.sleep(60)"
>   It is enabled.
>   Provides: mlauncher-test
>   Requires: syslogd
>   Will be respawned.
>
> Recent messages (use '-n' to view more or less):
>   2025-05-21 19:14:52 hi
> ```
>
> ======================================================================
>
> I appreciate your feedback.

Thanks but sorry I couldn't be of more help.

(Btw we have this in our workplace code of conduct: "The onus of
clearing up any misunderstanding is on the one who's sent the longest
message in that chain." ;-))

Regards,
James

Reply via email to