[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 2/2] gnu: Add dovecot service
From: |
Andy Wingo |
Subject: |
Re: [PATCH 2/2] gnu: Add dovecot service |
Date: |
Wed, 16 Dec 2015 08:04:19 +0000 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) |
Greets,
On Tue 15 Dec 2015 22:58, address@hidden (Ludovic Courtès) writes:
> Andy Wingo <address@hidden> skribis:
>
>> * gnu/services/mail.scm: New file.
>
> Regarding the Schemefied configuration, do you think Dovecot’s
> configuration model is stable enough that this won’t have to change
> much? Is a “cheat mode” (where one can pass raw strings to paste into
> the configuration file) needed?
I don't think dovecot configuration changes too much, no. It's pretty
stable AFAIU but I am not actually a dovecot expert. I mostly use it to
proxy a local maildir forest as IMAP, because I use an MTA that doesn't
(didn't used to?) deal with Maildir very well.
That said... the Scheme configuration interface is complete. If it's
not, that's a bug, and I think we can expect a Guix user to file a patch
:)
More than that, though, I think that we should be doing something like
this for all services that we implement, at least as the standard way to
integrate a service. For example the nginx service should have a Scheme
configuration interface, and when we start to compose multiple web
services into a nginx server, we should compose them on the Scheme
configuration level, not as .conf snippets. Of course, there's also
room for a Scheme configuration that abstracts over different web
servers, but there should also be a complete Scheme configuration level
for any particular web server.
You might have read Olin Shiver's thing on 100% and 80% solutions, from
http://www.ccs.neu.edu/home/shivers/papers/sre.txt, but I know not
everyone has, so I copy the preamble here :)
* Preamble: 100% and 80% solutions
----------------------------------
There's a problem with tool design in the free software and academic
community. The tool designers are usually people who are building tools for
some larger goal. For example, let's take the case of someone who wants to
do
web hacking in Scheme. His Scheme system doesn't have a sockets interface,
so
he sits down and hacks one up for his particular Scheme implementation. Now,
socket API's are not what this programmer is interested in; he wants to get
on
with things and hack the exciting stuff -- his real interest is Web
services.
So he does a quick 80% job, which is adequate to get him up and running, and
then he's on to his orignal goal.
Unfortunately, his quickly-built socket interface isn't general. It just
covers the bits this particular hacker needed for his applications. So the
next guy that comes along and needs a socket interface can't use this one.
Not only does it lack coverage, but the deep structure wasn't thought out
well
enough to allow for quality extension. So *he* does his *own* 80%
implementation. Five hackers later, five different, incompatible, ungeneral
implementations had been built. No one can use each others code.
The alternate way systems like this end up going over a cliff is that the
initial 80% system gets patched over and over again by subsequent hackers,
and
what results is 80% bandaids and 20% structured code. When systems evolve
organically, it's unsuprising and unavoidable that what one ends up with is
a
horrible design -- consider the DOS -> Win95 path.
As an alternative to five hackers doing five 80% solutions of the same
problem, we would be better off if each programmer picked a different task,
and really thought it through -- a 100% solution. Then each time a
programmer
solved a problem, no one else would have to redo the effort. Of course, it's
true that 100% solutions are significantly harder to design and build than
80%
solutions. But they have one tremendous labor-savings advantage: you don't
have to constantly reinvent the wheel. The up-front investment buys you
forward progress; you aren't trapped endlessly reinventing the same awkward
wheel.
Examples: I've done this three times. The first time was when I needed an
emacs mode in graduate school for interacting with Scheme processes. I
looked
around, and I found a snarled up mess of many, many 80% solutions, some for
Lisp, some for Scheme, some for shells, some for gdb, and so forth. These
modes had all started off at some point as the original emacs shell.el mode,
then had been hacked up, eventually drifting into divergence. The
keybindings
had no commonality. Some modes recovered old commands with a "yank" type
form,
on c-c y. Some modes recovered old commands with m-p and m-n. It was hugely
confusing and not very functional.
The right thing to do was to carefully implement one, common base mode for
process interaction, and to carefully put in hooks for customising this base
mode into language-specific modes -- lisp, shell, Scheme, etc. So that's
what
I did. I carefully went over the keybindings and functionality of all the
process modes I could find -- even going back to old Lisp Machine bindings
for
Zwei -- and then I designed and implemented a base mode called comint. Now,
all process modes are implemented on top of comint, and no one, ever, has to
re-implement this code. Users only have to learn one set of bindings for
the common functions. Features put into the common code are available for
free
to all the derived modes. Extensions are done, not by doing a completely new
design, but *in terms of* the original system -- it may not be perfect, but
it's good enough to allow people to move on and do other things.
The second time was the design of the Scheme Unix API found in scsh. Most
Schemes have a couple of functions for changing directory, some minimal
socket
hacking, and perhaps forking off a shell command with the system() C
function.
But no one has done a complete job, and the functions are never compatible.
It was a classic 80%-solution disaster. So I sat down to do a careful, 100%
job -- I wanted to cover everything in section 2 of the Unix man pages, in a
manner that was harmonious with the deep structures of the Scheme language.
As
a design task, it was a tremendous amount of work, taking several years, and
multiple revisions. But now it's done. Scsh's socket code, for instance,
*completely* implements the socket API. My hope in doing all this was that
other people could profit from my investment. If you are building your own
Scheme system, *you* don't have to put in the time. You can just steal the
design. Or the code.
The regexp notation in this document represents a third attempt at this kind
of design. Looking back, I'm amazed at how much time I poured into the
design,
not to mention the complete reference implementation. I sold myself on
doing a
serious job with the philosophy of the 100% design -- the point is to save
other people the trouble. If the design is good enough, then instead of
having
to do your own, you can steal mine and use the time saved... to do your own
100% design of something *else*, and fill in another gap.
I am not saying that these three designs of mine represent the last word on
the issues -- "100%" is really a bit of a misnomer, since no design is ever
truly 100%. I would prefer to think of them as sufficiently good that they
at
least present low-water marks -- future systems, I'd hope, can at least
build
upon these designs, hopefully *in terms of* these designs. You don't ever
have
to do *worse* -- you can just steal the design. If you don't have a
significantly better idea, I'd encourage you to adopt the design for the
benefits of compatibility. If you *do* have an improvement, email me about
it,
so we can fold it in to the core design and *everyone* can win -- and we can
also make your improvement part of the standard, so that people can use your
good idea and *still* be portable.
But here's what I'd really like: instead of tweaking regexps, you go do your
own 100% design or two. Because I'd like to use them. If everyone does just
one, then that's all anyone has to do.
-Olin
Finally, I'm not adverse to a .conf file escape hatch. It's especially
convincing in a context where other services do the same -- we should
have a greater degree of uniformity across services. However if other
services implemented a 100%-solution Scheme configuration interface, I
wonder if we would still want the .conf file interface. Dunno!
>> +To add IMAP support to a GuixSD system, add a @code{dovecot-service} to
>
> s|IMAP support|an IMAP/POP3 email server|
ACK
>> +(define-configuration unix-listener-configuration
>> + (path
>> + (file-name (error "unix listener path required"))
>> + "The file name on which to listen.")
>
> s/path/file-name/ maybe
Can I push back on this? Currently there each configuration parameter
maps in a direct way to the property in the dovecot.conf, which has the
nice property that it corresponds with the upstream Dovecot
documentation. Dunno.
> We should probably use a ‘dovecot-error’ procedure instead of ‘error’,
ACK
Will fix nits. Let me know if "path" is OK as a configuration
parameter. We call it a file name in the documentation at least :)
Cheers,
A
Re: [PATCH 2/2] gnu: Add dovecot service, Andy Wingo, 2015/12/18
Re: [PATCH 1/2] gnu: dovecot: Add linux-pam to inputs., Ludovic Courtès, 2015/12/15