guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: XWayland, /tmp/.X11-unix


From: Thorsten Wilms
Subject: Re: XWayland, /tmp/.X11-unix
Date: Thu, 29 Mar 2018 16:37:48 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0

Thank you, Chris, for taking the time to go into such detail! However, as mentioned later in the thread, I arrived at a solution days ago. It just took finding a close match among existing services and recalling some basics about Scheme evaluation :)

Your write-up did improve my idea of what is going on, though I guess I may have to reread it later on, to get more out of it.


On 29.03.2018 08:18, Chris Marusich wrote:
> Thorsten Wilms <address@hidden> writes:
>
>> On 22.03.2018 00:00, Ricardo Wurmus wrote:
>>>
>>> Thorsten Wilms <address@hidden> writes:
>>>
>>>> Initially I thought creation of /tmp/.X11-unix should be tied to the
>>>> xorg-server-xwayland package, but since it is more generic: which
>>>> component should create that dir on Guix SD (based on what)?
>>>
>>> It is needed at run-time (because packages cannot create files outside
>>> of their store prefix at build time), so it should be created by a
>>> system service.  A service is not the same as a shepherd service; we
>>> also have activation services that run once and only create a file or a
>>> directory.
>>
>> After 2 to 3 hours of research, going through documentation and
>> various .scm, I still don't even manage to write a service for my
>> system configuration that just does a (mkdir-p "/tmp/.X11-uni"), so
>> figuring out how to make that dependent on the actual need is way
>> outside my capabilities.
>
> Take heart: it is not easy for me, either.  :-)
>
>> Should I file a bug, and if so, against what?
>
> If this is a problem that is preventing you from building something new,
> then discussing it here is probably the right approach.  If it's
> affecting an existing package or service in Guix, then you might want to
> create a bug for it by emailing address@hidden
>
> By the way, to create a "service" that does what you need, you might
> find it useful to look at an existing example service.  For example, the
> procedure nscd-activation in gnu/services/base.scm does something
> similar.  So does the procedure exim-activation in
> gnu/services/mail.scm.
>
> The manual does explain what is going on (see: (guix) Service
> Reference), but I have read it multiple times and examined the source
> multiple times, and I still have trouble remembering exactly how it all
> fits together.
>
> I'll try to explain how I understand it.  In Guix, a service is a
> <service> object; sometimes this is also referred to as a service
> "instance".  A <service> object contains two other objects: a "type" and
> a "value".  The "type" is a <service-type> object and is sometimes
> referred to as the service "kind" (because it represents what kind of
> service it is).  The "value" is whatever that particular service type
> requires, and sometimes it is also referred to as a service's
> "parameter", "parameters", or "parameter value".  Usually the value is a
> configuration object of some kind.  For example, the Guix service
> expects its value to be a <guix-configuration> object.
>
> By the way, these objects with angle brackets, like <service>, are
> defined using the define-record-type* syntax (which itself is defined in
> guix/records.scm).  They are similar to normal Scheme records (see:
> (guile) Record Overview), if you're familiar with those.
>
> Guix has an "activation service".  Its purpose, as described in the
> manual (see: (guix) Service Types and Services), is to run a code
> snippet "at activation time - e.g., when the service is booted".  The
> basic contract for extending the "activation service" is that if you
> define an extension of the activation service which specifies a
> "compute" procedure foo, where foo is a procedure that returns a
> G-Expression that takes some action (e.g., create the "/tmp/.X11-uni"
> directory), then that action will be taken at activation time.  The
> "foo" procedure will receive a single argument as input: the argument
> will be the value of the service (your service!) that is extending the
> activation service.
>
> Confused?  I know I was when I first looked into this.  But stay with me
> - together we can make it through!  The mechanism that implements the
> extension logic can be found in the fold-services procedure in
> gnu/services.scm.  Specifically, when a service like the Guix service
> extends an extensible service like the activation service, we have the
> following situation:
>
> * A guix-service-type is defined (in gnu/services/base.scm).  It
>    contains a <service-extension> for which the "target" is the
>    activation-service-type and the "compute" is the guix-activation
>    procedure.
>
> * We add an instance of the Guix service to the %base-services list by
>    calling the guix-service procedure.  This procedure creates an
>    instance of the service and uses %default-guix-configuration as its
>    value (which is a <guix-configuration> object).
>
> * The activation-service-type is defined (in gnu/services.scm).  Its
>    "compose" is the append procedure (see: (guile) Append/Reverse), and
>    its "extend" is the second-argument procedure.
>
> * We add an instance of the activation service to the essential-services
>    list.  The activation service's initial value is #t.
>
> When Guix builds all the system services, it will do the following:
>
> * Guix will find a service of the activation-service-type.  This is the
>    activation service.
>
> * Guix will find a service of the guix-service-type.  This is the Guix
>    service.
>
> * Guix will recognize that the Guix service extends the activation
>    service.
>
> * Guix will pass the Guix service's value to the guix-service-type's
>    "compute" procedure defined earlier.  This means that Guix will call
>    the guix-activation procedure with a single argument: the
>    %default-guix-configuration.  The guix-activation procedure returns an
>    appropriate G-Expression that takes steps to activate Guix according
>    to the provided configuration.
>
> * If there are any other services that extend the
>    activation-service-type, Guix will call their "compute" procedures in
>    a similar fashion.
>
> * Guix will collect all of the objects returned by the various "compute"
>    procedures in a list.  The G-Expression returned by guix-activation
>    will be one element of this list.  Guix will pass this list to the
>    activation-service-type's "compose" procedure.  This means that it
>    will call append with a single argument: the list.  This will actually
>    return the same list, since appending a single list returns the same
>    list.  (As explained elsewhere on the guix-devel email list, this
>    should really be the "identity" procedure, not the "append" procedure,
>    since it more accurately reflects the intent [1].)
>
> * Guix will call the activation-service-type's "extend" procedure with
>    two arguments: the first argument is the value of the activation
>    service found earlier, and the second argument is the result of the
>    "compose" procedure from the previous step.  This means that Guix will
>    call the second-argument procedure with the value #t as its first
>    argument, and the list of G-Expressions from above as its second
>    argument.  Because the second-argument procedure simply returns the
>    second argument, the value #t will be ignored, and the result will be
>    the list of G-Expressions.
>
> * Guix replaces the activation service with a new service instance that
>    has the same type but a new value.  The new value is set to the result
>    of calling the "extend" procedure.  This means that the activation
>    service will be replaced with a new activation service that uses the
>    list of G-Expressions from the previous step as its value.
>
> Guix repeats this process recursively for all services defined in your
> <operating-system> declaration.  In this way, even though the high-level
> contract for how services extend one another is dictated by Guix, the
> interpretation of the objects and procedures involved is largely
> determined by the service that is being extended.  For example, Guix
> promises the activation service that it will collect objects from
> services that extend the activation service and then call the activation
> service's "compose" and "extend" procedures as described above to create
> a new, modified activation service.  However, the structure of those
> objects and the behavior of those procedures are largely determined by
> the activation-service-type itself.  A different type of service may
> very well define a different contract.
>
> To re-iterate what I wrote earlier, the activation-service-type's
> contract is as follows: when you define a service that extends it (i.e.,
> when you define a <service-type> that extends the
> activation-service-type), your service will define a "compute" procedure
> that returns a G-Expression that performs some action (e.g., create a
> directory).  The activation service will then arrange to run that action
> at activation time.  This means that if your service needs a
> "/tmp/.X11-uni" directory to exist before it runs, you need to define a
> "compute" procedure that accepts a single argument (which will be your
> service's value) and returns a G-Expression that creates the directory.
> Different extensible services have different expectations, so you would
> need to implement different "compute" procedures to extend them.
> Thankfully, even if an extensible service is not clearly documented, you
> can usually tell what its contract is by looking at some services that
> extend it already.
>
> I hope that helps!
>
> Footnotes:
> [1]  https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00307.html
>

--
Thorsten Wilms

thorwil's design for free software:
http://thorwil.wordpress.com/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]