diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/development.md | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/doc/development.md b/doc/development.md new file mode 100644 index 0000000..75d549f --- /dev/null +++ b/doc/development.md @@ -0,0 +1,208 @@ +% Test environment setup for [`interimap`(1)] and [`pullimap`(1)] +% Guilhem Moulin <guilhem@fripost.org> + +Introduction +============ + +This document describes how to create dummy mail storage for +[`interimap`(1)] and/or [`pullimap`(1)] development, using +[Dovecot](https://dovecot.org) as [IMAP4rev1] server. Start by creating +a new temporary directory: + + $ BASEDIR="$(mktemp --tmpdir --directory)" + +(The leading `$ ` in this document are command-line prompt strings, and +are not part of the command themselves.) + + +Dovecot configuration +===================== + +Create a file `$BASEDIR/dovecot.conf`, which will be used as +configuration for the various Dovecot commands (the system configuration +will be skipped). + + $ cat >"$BASEDIR/dovecot.conf" <<-EOF + log_path = "$BASEDIR/dovecot.log" + ssl = no + mail_home = "$BASEDIR/%u" + mail_location = maildir:~/mail + EOF + +Here are some details on the above: + +`log_path` + + : Dovecot [logs to syslog](https://wiki.dovecot.org/Logging) by default. + It's annoying to clutter syslog with test entries, so instead we make it + log to a file under `$BASEDIR`. + +`ssl` + + : Not required, but turned off here so dumping the configuration with + `` `doveconf -c "$BASEDIR/dovecot.conf" -n` `` doesn't spew a warning. + +`mail_home` + + : Dovecot needs the name of the user to (pre-)authenticate. It is shown + in the greeting line, and also used in [`%`-variable] expansion. + Several [`doveadm`(1)] sub-commands have a `-u` (or `-d`) option which + can be used to determine the username. When this option is not set, + the username is taken from the `USER` environment variable. If that + environment variable is unset as well, then the return string of + [`getlogin`(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getlogin.html) + is used. + + Similarly, the user's home directory is used in (`~`- and) + [`%`-variable] expansion. It's taken from the `HOME` environment + variable when the `mail_home` setting is left unset in the Dovecot + configuration (and not overridden by the [user database](https://wiki.dovecot.org/UserDatabase)). + + `mail_home` can therefore be left unset if the `HOME` environment + variable is consistently set to `$BASEDIR/$USER`. However it's + safer to explicitly set it in the configuration file: otherwise a + command run in a non-curated environment might mess up with your own + mail storage… + +`mail_location` + + : The user's mail storage resides — in [Maildir](https://wiki.dovecot.org/MailLocation/Maildir) + format — in a directory `mail` under their home directory. This is + enough if you're fine with the default IMAP hierarchy delimiter + (which depends on the mail format) is used, and if you need a single + [IMAP namespace](https://tools.ietf.org/html/rfc2342). For more + complex setups you'll need one or more + [`namespace {…}` block](https://wiki.dovecot.org/Namespaces). + + +Mail storage access +=================== + +Feel free to point a mail client at the dummy mail storage. To start a +pre-authenticated [IMAP4rev1] in the test environment for username +`testuser`, list mailboxes, and exit, run: + + $ env -i PATH="/usr/bin:/bin" USER="testuser" \ + doveadm -c "$BASEDIR/dovecot.conf" exec imap + * PREAUTH [CAPABILITY IMAP4rev1 …] Logged in as testuser + a LIST "" "*" + * LIST (\HasNoChildren) "." INBOX + a OK List completed (0.002 + 0.000 + 0.001 secs). + q LOGOUT + q OK Logout completed (0.001 + 0.000 secs). + +For mailbox (create, delete, rename) and message (add, flag update) +manipulation you can use your mail client, the relevant [IMAP4rev1] +commands, or simply the [`doveadm`(1)] tools. Here is an example using +the latter to create a mailbox `foo`, add a sample message to it, and +finally mark it as `\Seen`. + + $ env -i PATH="/usr/bin:/bin" USER="testuser" \ + doveadm -c "$BASEDIR/dovecot.conf" mailbox create "foo" +<!-- --> + $ env -i PATH="/usr/bin:/bin" USER="testuser" HOME="$BASEDIR/testuser" \ + doveadm -c "$BASEDIR/dovecot.conf" exec dovecot-lda -e -m "foo" <<-EOF + From: <sender@example.net> + To: <recipient@example.net> + Subject: Hello world! + Date: $(date -R) + Message-ID: <$(</proc/sys/kernel/random/uuid)@example.net> + + Hello world! + EOF +<!-- --> + $ env -i PATH="/usr/bin:/bin" USER="testuser" \ + doveadm -c "$BASEDIR/dovecot.conf" flags add "\\Seen" mailbox "foo" "*" + +Normally [`dovecot-lda`(1)](https://wiki.dovecot.org/LDA) tries to do a +userdb lookup in order to determine the user's home directory. Since we +didn't configure a user database we need to explicitly set the `HOME` +environment variable. + + +InterIMAP configuration and test +================================ + +In this example the peers to synchronize are sharing the same Dovecot +configuration file `$BASEDIR/dovecot.conf`. Of course, it's also +possible to use a different configuration on each “server”, for instance +in order to specify different hierarchy delimiters, namespaces, or mail +storage format. + +Create an [`interimap`(1)] configuration file to synchronize the `local` +and `remote` accounts. + + $ cat >"$BASEDIR/interimap.conf" <<-EOF + database = $BASEDIR/interimap.db + + [local] + type = tunnel + command = env -i PATH="$PATH" USER="local" doveadm -c "$BASEDIR/dovecot.conf" exec imap + + [remote] + type = tunnel + command = env -i PATH="$PATH" USER="remote" doveadm -c "$BASEDIR/dovecot.conf" exec imap + EOF + +Run [`interimap`(1)] without `--watch` in order to create the database. + + $ env -i PATH="$PATH" perl -I./lib -T ./interimap --config="$BASEDIR/interimap.conf" + Creating new schema in database file …/interimap.db + database: Created mailbox INBOX + […] + +You can now run [`interimap`(1)] with `--watch` set, here to one second +to observe synchronisation steps early. + + $ env -i PATH="$PATH" perl -I./lib -T ./interimap --config="$BASEDIR/interimap.conf" \ + --watch=1 --debug + +Use instructions from the [previous section][Mail storage access] +(substituting `testuser` with `local` or `remote`) in order to simulate +activity on either end to synchronize. If you run these commands in +another shell, then make sure to re-set the `BASEDIR` environment +variable! + + +PullIMAP configuration and test +=============================== + +Create a [`pullimap`(1)] configuration file with as section `[foo]`. + + $ cat >"$BASEDIR/pullimap.conf" <<-EOF + [foo] + type = tunnel + command = env -i PATH="$PATH" USER="testuser" doveadm -c "$BASEDIR/dovecot.conf" exec imap + statefile = $BASEDIR/pullimap.foo + EOF + +Run [`pullimap`(1)] without `--idle` in order to create the state file. + + $ env -i PATH="$PATH" perl -I./lib -T ./pullimap --config="$BASEDIR/pullimap.conf" \ + --no-delivery foo + +You can now run [`pullimap`(1)] with `--idle` set. + + $ env -i PATH="$PATH" perl -I./lib -T ./pullimap --config="$BASEDIR/pullimap.conf" \ + --no-delivery --idle --debug foo + +Use instructions from the [previous section][Mail storage access] +in order to simulate activity on the “remote” server (in the relevant +mailbox — `INBOX` by default). If you run these commands in another +shell, then make sure to re-set the `BASEDIR` environment variable! + + +Cleanup +======= + +To remove temporary directories and the message they contain, simply +recursively remove the directory `$BASEDIR`. + + $ rm -rf -- "$BASEDIR" + + +[IMAP4rev1]: https://tools.ietf.org/html/rfc3501 +[`interimap`(1)]: https://guilhem.org/man/interimap.1.html +[`pullimap`(1)]: https://guilhem.org/man/pullimap.1.html +[`doveadm`(1)]: https://wiki.dovecot.org/Tools/Doveadm +[`%`-variable]: https://wiki.dovecot.org/Variables |