Compare commits

...

2 Commits

2 changed files with 122 additions and 3 deletions

View File

@ -0,0 +1,119 @@
(define-module (tiedote-md-service)
#:use-module (gnu services configuration)
#:use-module (gnu services shepherd)
#:use-module (gnu services base)
#:use-module (gnu system shadow)
#:use-module (gnu services)
#:use-module (guix records)
#:use-module (guix gexp)
#:use-module (tiedote-md-package)
#:use-module (gnu packages bash)
#:export (tiedote.md-configuration
tiedote.md-service-type))
(define-maybe string)
(define-configuration/no-serialization tiedote.md-configuration
(email-address
(string)
"Email address to send messages as. Mail to this address must be routed to
the tiedote.md user on this system.")
(sender-name
(string)
"Name to send messages as.")
(remote-url
(string)
"URL of the Git repository to mirror.")
(remote-branch
maybe-string
"Git branch to read messages from.")
(sendmail-path
(string "/run/privileged/bin/sendmail")
"Path to a sendmail compatible mailing executable.")
(port
(integer 3000)
"Port to listen on for webhook notifications.")
(socket-path
(string "/run/tiedote.md/acid.sock")
"Socket on which tiedote.md should listen on.")
(state-directory
(string "/var/lib/tiedote.md")
"Directory for persistent storage."))
(define (tiedote.md-accounts config)
(match-record config <tiedote.md-configuration>
(state-directory)
(list (user-group
(name "tiedote.md")
(system? #t))
(user-account
(name "tiedote.md")
(system? #t)
(group "tiedote.md")
(comment "Tiedote.md service user")
(home-directory state-directory)
(shell (file-append bash-minimal "/bin/bash"))))))
(define (tiedote.md-shepherd-service config)
(match-record config <tiedote.md-configuration>
(state-directory socket-path email-address sender-name port sendmail-path
remote-branch remote-url)
(list (shepherd-service
(documentation "A simple mass email system")
(requirement '(networking user-processes))
(provision '(tiedote.md))
(start #~(let* ((user (getpw "tiedote.md"))
(uid (passwd:uid user))
(gid (passwd:gid user))
(socket-directory (dirname #$socket-path))
(repo-path (string-append #$state-directory "/git-repo")))
(begin
(mkdir-p socket-directory)
(chown socket-directory uid gid)
(make-forkexec-constructor
`(#$(file-append tiedote-md "/bin/tiedote.md")
"--address" #$email-address
"--sender-name" #$sender-name
"--sendmail" #$sendmail-path
"--socket" #$socket-path
"server"
"--repository" repo-path
"--port" #$(number->string port)
"--remote-url" #$remote-url
,@(if #$(maybe-value-set? remote-branch)
(list "--remote-branch" #$remote-branch)
'()))
#:user "tiedote.md"
#:group "tiedote.md"
#:environment-variables
(cons* "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt"
"LC_ALL=C.utf8"
(default-environment-variables))
#:directory #$state-directory))))
(stop #~(make-kill-destructor))))))
(define (tiedote.md-activation config)
(match-record config <tiedote.md-configuration>
(state-directory email-address sender-name sendmail-path socket-path)
(let* ((receive-exec (list (file-append tiedote-md "/bin/tiedote.md") ; file to exec
(file-append tiedote-md "/bin/tiedote.md") ; arg $0
"--address" email-address
"--sender-name" sender-name
"--sendmail" sendmail-path
"--socket" socket-path))
(receive-script (program-file "tiedote.md-receive"
#~(apply execl #$receive-exec)))
(forward-file (mixed-text-file "dot-forward" "|" receive-script)))
#~(let ((.forward (string-append #$state-directory "/.forward")))
(if (file-exists? .forward)
(delete-file .forward))
(symlink #$forward-file .forward)))))
(define tiedote.md-service-type
(service-type
(name 'tiedote.md)
(extensions
(list (service-extension account-service-type tiedote.md-accounts)
(service-extension activation-service-type tiedote.md-activation)
(service-extension shepherd-root-service-type tiedote.md-shepherd-service)))
(description "A simple mass email system")))

View File

@ -6,12 +6,12 @@ module Main where
import Control.Applicative (optional)
import Control.Concurrent (forkIO, threadDelay)
import Control.Exception (onException)
import Control.Exception (onException, catch)
import Control.Exception (throwIO)
import Control.Monad (void, forever)
import Data.Acid (AcidState(..), openLocalState, createCheckpoint, createArchive)
import Data.Acid.Remote (skipAuthenticationCheck, acidServerSockAddr, openRemoteStateSockAddr, skipAuthenticationPerform)
import Data.FileStore (gitFileStore, initialize)
import Data.FileStore (gitFileStore, initialize, FileStoreError(RepositoryExists))
import Data.IMF (Mailbox(..), parse, mailbox)
import Data.MIME.Charset (defaultCharsets)
import Data.Text.Encoding (encodeUtf8)
@ -36,7 +36,7 @@ import TiedoteMD.Debug
serverMain :: SockAddr -> Mailbox -> FilePath -> GitOrigin -> FilePath -> Int -> Int -> IO ()
serverMain socket mail repoPath origin sendmailPath checkpointDelay port = do
initialize $ gitFileStore repoPath
initialize (gitFileStore repoPath) `catch` \RepositoryExists -> pure ()
acid <- openLocalState $ emptyState
_ <- forkIO $ acidServerSockAddr skipAuthenticationCheck socket acid
queueMessages acid