t/all: fixup test for missing IPC::Run
[ssoma-mda.git] / Documentation / ssoma_repository.txt
1 % ssoma_repository(5) ssoma user manual
2
3 # NAME
4
5 ssoma_repository - repository and tree description for ssoma
6
7 # DESCRIPTION
8
9 ssoma uses a git repository to store each email as a git blob.  The tree
10 filename of the blob is based on the SHA1 hexdigest of the Message-ID
11 header.  A commit is made for each message delivered.  The commit SHA-1
12 identifier is used by ssoma clients to track synchronization state.
13
14 # PATHNAMES IN TREES
15
16 A Message-ID may be extremely long and also contain slashes, so using
17 them as a path name is challenging.  Instead we use the SHA-1 hexdigest
18 of the Message-ID (excluding the leading "<" and trailing ">") to
19 generate a path name.  Leading and trailing white space in the
20 Message-ID header is ignored for hashing.
21
22 A message with Message-ID of: <20131106023245.GA20224@dcvr.yhbt.net>
23
24 Would be stored as: f2/8c6cfd2b0a65f994c3e1be266105413b3d3f63
25
26 Thus it is easy to look up the contents of a message matching a given
27 a Message-ID.
28
29 # CONFLICTS
30
31 Message-ID is a unique-enough identifier for practical purposes, but
32 they may still conflict (especially in case of malicious clients and
33 timing issues).  In the case of identical Message-ID and different
34 messages, the blob shall become a tree with multiple messages.
35 Likewise, if there is a (rare) SHA-1 conflict on different Message-ID
36 headers, the tree will contain each message (with different Message-ID
37 headers).
38
39 Thus the blobs for conflicting Message-IDs will be the SHA-1 hexdigest
40 of the Subject header and raw body (no extra whitespace delimiting the
41 two).
42
43   PFX=21/4527ce3741f50bb9afa65e7c5003c8a8ddc4b1
44
45   $PFX/287d8b67bf8ebdb30e34cb4ca9995dbd465f37aa # first copy
46   $PFX/287d8b67bf8ebdb30e34cb4ca9995dbd465f37ab # second copy
47   $PFX/287d8b67bf8ebdb30e34cb4ca9995dbd465f37ac # third copy
48
49 # LOCKING
50
51 fcntl(2) locking exclusively locks the empty $GIT_DIR/ssoma.lock file
52 for all non-atomic operations.
53
54 # EXAMPLE INPUT FLOW (SERVER-SIDE MDA)
55
56 1. Message is delivered to a mail transport agent (MTA)
57 1a. (optional) reject/discard spam, this should run before ssoma-lda
58 1b. (optional) reject/strip unwanted attachments
59
60 ssoma-mda handles all steps once invoked.
61
62 2. Mail transport agent invokes ssoma-mda
63 3. reads message via stdin, extracting Message-ID
64 4. acquires fcntl lock on $GIT_DIR/ssoma.lock
65 5. creates or updates the blob of associated 2/38 SHA-1 path
66 6. updates the index and commits
67 7. releases $GIT_DIR/ssoma.lock
68
69 ssoma-mda can also be used as an inotify(7) trigger to monitor maildirs,
70 and the ability to monitor IMAP mailboxes using IDLE will be available
71 in the future.
72
73 # GIT REPOSITORIES (SERVERS)
74
75 ssoma uses bare git repositories on both servers and clients.
76
77 Using the git-init(1) command with --bare is the recommend method
78 of creating a git repository on a server:
79
80         git init --bare /path/to/wherever/you/want.git
81
82 There are no standardized paths for servers, administrators make
83 all the choices regarding git repository locations.
84
85 Special files in $GIT_DIR on the server:
86
87 * $GIT_DIR/ssoma.index - a git index file used for MDA updates,
88 :  The normal git index (in $GIT_DIR/index) is not used at all as
89    there is typically no working tree.
90
91 * $GIT_DIR/ssoma.lock - empty file for fcntl(2) locking
92 :  This is necessary to ensure the index and commits are updated
93    consistently and multiple processes running MDA do not step on
94    each other.
95
96 # GIT REPOSITORIES (CLIENTS)
97
98 ssoma uses bare git repositories for clients (as well as servers).
99
100 The default is to use GIT_DIR=~/.ssoma/$LISTNAME.git in the user's home
101 directory.  This is a bare git repository with two additional files:
102
103 * $GIT_DIR/ssoma.lock - empty lock file, same as used by ssoma-mda(1)
104 * $GIT_DIR/ssoma.state - a git-config(1) format file used by ssoma(1)
105
106 Each client $GIT_DIR may have multiple mbox/maildir/command targets.
107 It is possible for a client to extract the mail stored in the git
108 repository to multiple mboxes for compatibility with a variety of
109 different tools.
110
111 # $GIT_DIR/ssoma.state format.
112
113         ; "local" is the default name (analogous to "origin" with remotes)
114         [target "local"]
115                 path = /path/to/mbox
116
117                 ; this tells ssoma where to start the next import from
118                 ; this means ssoma will not redundantly import old
119                 ; messages and the user is free to move/delete old
120                 ; messages from the mbox.
121                 last-imported = 33eaf25f43fd73d8f4f7b0a066b689809d733191
122
123         ; "alt" is a user-defined name, in case a user wants to output
124         ; the repo in several formats
125         [target "alt"]
126                 ; note the trailing '/' to denote the maildir path,
127                 ; the Email::LocalDelivery Perl module depends on this
128                 ; trailing slash to identify it as a maildir
129                 path = /path/to/maildir/
130                 last-imported = 950815b313a4e616c6fe39f46b2e894b51d7d62f
131
132         ; users may also choose to pipe to an arbitrary command of their
133         ; choice, this filter may behave like an MDA (and implement
134         ; filtering).  Tools like procmail(1)/maildrop(1) may be
135         ; invoked here.
136         [target "script"]
137                 command = /path/to/executable/which/reads-mail-from-stdin
138                 last-imported = 950815b313a4e616c6fe39f46b2e894b51d7d62f
139
140 # EXAMPLE OUTPUT FLOW (CLIENT)
141
142 1. clone or fetches to bare git repo (GIT_DIR=~/.ssoma/$LISTNAME.git)
143 2. checks for last-imported commit in ~/.ssoma/$LISTNAME.git/ssoma.state
144 3. diffs last-imported commit with current HEAD
145 4. imports new emails to mbox/maildir since last-imported up to current HEAD
146 5. updates last-imported commit
147
148 # CAVEATS
149
150 It is NOT recommended to check out the working directory of a git.
151 there may be many files.
152
153 It is impossible to completely expunge messages, even spam, as git
154 retains full history.  Projects may (with adequate notice) cycle to new
155 repositories/branches with history cleaned up via git-filter-branch(1).
156 This is up to the administrators.
157
158 # COPYRIGHT
159
160 Copyright 2013, Eric Wong <normalperson@yhbt.net> and all contributors.\
161 License: AGPLv3 or later <http://www.gnu.org/licenses/agpl-3.0.txt>