Hi Sébastien,
Sébastien Gendre <[email protected]> writes:
Hi Ian,
Thank you very much for your reply and your help.
I wrote my replies after the quotes.
Ian Eure <[email protected]> writes:
Sébastien Gendre <[email protected]> writes:
;; Define serializer functions
(define (serialize-luanti-admin-name field-name value)
"Serialize the Luanti admin name field for the config
file."
(let ((field-real-name "name"))
#~(string-append #$field-real-name " = " #$value)))
Since you’re only building strings, you don’t need a gexp, nor
do you
need the let binding. Here’s a simplified version:
(define (serialize-luanti-admin-name _ value)
"Serialize the Luanti admin name field for the config
file."
(string-append "name = " #$value))
Thank you very much. I'm still very new with gexp. The
`define-configuration' documentation was saying that the
serializer
procedure should return a gexp. But if it can be done without
gexp, that
make it easy.
I think there’s actually a documentation issue, this whole section
is
worded very strangely. It looks like `@ref{G-Expressions}' is
being
represented as "see G-Expressions" in the text for some reason.
The relevant part of the docs is this, though:
The procedure should return a string or *note G-Expressions::
that
represents the content that will be serialized to the
configuration file.
Which should properly say "a string or g-expression."
;; Define the Luanti Game configuration
(define-configuration luanti-game-configuration
(admin-name
maybe-string
"Username of the administrator."
(serializer serialize-luanti-admin-name)))
This is mixing an optional predicate with a required
serializer, which
won’t work right. While it’s boilerplatey, I find that the
best
approach is to make one type per field:
(define admin-name? string?)
(define (serialize-admin-name field-name value) "do the
right
thing here")
Then use `define-maybe' and the predicate & serializer it
expands to:
(define-maybe admin-name)
(define-configuration luanti-game-configuration
(admin-name maybe-admin-name "Username of the
administrator."))
Within the configuration system, "type" covers both the value
*and*
how it’s handled, which can cause problems when you have two
fields
which take string, but need different serialize-string handling
--
like one needing to be quoted, or one representing an INI-style
[section] and another a key = value pair. Starting here gives
you
clean separation you can merge later, if you like.
I thought that I could use an existing type (string) and only
specify a
specific serializer for this parameter. An then, define a
generic string
serializer for the simple string parameters.
You can. It’s a matter of whether you prefer boilerplate in the
form
of (serializer serialize-foo) or (define foo? string?).
When I define a maybe and a serializer procedure for a type, the
serializer procedure didn't have to adapt its behavior based on
the
"maybe" part ? Like returning something only if the value is not
empty ?
That’s the problem, your custom serializer doesn’t handle
`%unset-marker', so it won’t serialize unset optional values
correctly. In this case, I think it’s simpler to define a
predicate
and serializer for your type, then use `define-maybe'. The
alternative is adding `%unset-marker' handling to any custom
serializer for an optional field.
I took inspiration of `libvirt-conf-file' (in file
gnu/services/virtualization.scm:486). How is it working in the
case
of `libvirt-conf-file' ? Is it only working in the context of a
system service activation ?
The serializers for the fields in libvirt-configuration all use
`(format #t ...)', which prints the output. I don’t know why it’s
like that, it seems like an approach that isn’t in line with the
intentions of the configuration system.
On a closing note, I’ll share that I’ve also struggled a lot
with the
configuration system in Guix, both in its documentation and
implementation. Implementation-wise, the system feels both
barebones
and verbose. I’ve run into some stuff with unsatisfying
expressions,
like fields whose names aren’t needed, config subsections, and
configurations spanning multiple files. These all require
workarounds
which feel more like subverting the system than using it as
intended.
I have the same problem. I have more experience with Ansible and
it's
template module. I thought that `define-configuration' would
serve the
same goal but using Scheme programming instead of template. I
bit like
the HTML export backend of Org-mode is, compared to usual
template
system of static and dynamic web pages generators.
Yeah, it’s not a system like that at all. The goal is to insulate
users of the configuration records you define from the details of
the
underlying program’s file format. That allows the whole system to
be
configured entirely with Scheme. It’s like creating Python
classes
representing the whole configuration, and a mechanism to convert
those
to the text file representation the program expects.
On the documentation side, the Guix manual is an invaluable
reference,
but a lot of it feels like just that -- a reference. It has
great
"what" and "how" information, but in my opinion, sorely lacks
the
contextual "why" and "when" to effectively apply it.
Yes, I get what you mean about the manual. I think the
contextual "why"
and "when" is more in the cookbook. But, for now, there is no
section
about writing a system service step by step. Or a home
service. I would
love to help, but my actual understanding of it is not a the
required
level to write a good tutorial.
The cookbook has some good stuff, but doesn’t seem like it’s
always as
up-to-date as the manual.
And, about the manual, I noticed that as a new Guix and Guix
system
user, I have some difficulties to understand some parts. It's
like I
miss an information, or a details, in the manual. But I didn't
note it
somewhere, so now it would be difficult to notice it again. At
least,
for parts I understand now.
Yes, there are a lot of terms thrown out before they’re defined,
or
which have definitions which are hard for new users to understand.
When I’m writing technical documentation, I try my best to define
terms and outline high-level concepts before getting into the
technical details -- having an understanding of the general shape
of
the system helps me contextualize the more tecnical stuff.
While I freely admit this is a personal opinion/preference, I’ve
found
that it seems to be a method of communicating which works for a
lot of
people.
-- Ian