Compare commits

..

8 Commits

5 changed files with 48 additions and 75 deletions

View File

@ -11,7 +11,6 @@
#:use-module (gnu packages haskell-check) #:use-module (gnu packages haskell-check)
#:use-module (gnu packages haskell-web) #:use-module (gnu packages haskell-web)
#:use-module (gnu packages golang-web) #:use-module (gnu packages golang-web)
#:use-module (gnu packages ssh)
#:use-module (gnu packages version-control)) #:use-module (gnu packages version-control))
(define vcs-file? (define vcs-file?
@ -42,19 +41,17 @@
ghc-scotty ghc-scotty
ghc-exit-codes ghc-exit-codes
git git
openssh-sans-x
go-github-com-aymerick-douceur)) go-github-com-aymerick-douceur))
(arguments (arguments
(list (list
#:phases #:phases
#~(modify-phases %standard-phases #~(modify-phases %standard-phases
(add-after 'install 'wrap-binaries (add-after 'install 'wrap-binaries
(lambda* (#:key inputs #:allow-other-keys) (lambda _
(wrap-program (wrap-program
(string-append #$output "/bin/tiedote.md") (string-append #$output "/bin/tiedote.md")
`("PATH" prefix (,(string-append (assoc-ref inputs "git") "/bin") `("PATH" prefix (,(string-append #$(this-package-input "git") "/bin")
,(string-append (assoc-ref inputs "openssh-sans-x") "/bin") ,(string-append #$(this-package-input "go-github-com-aymerick-douceur")
,(string-append (assoc-ref inputs "go-github-com-aymerick-douceur")
"/bin"))))))))) "/bin")))))))))
(home-page "https://git.olarinmaensamoojat.fi/OMS/tiedote.md") (home-page "https://git.olarinmaensamoojat.fi/OMS/tiedote.md")
(synopsis "Git- ja markdown-pohjainen masssasähköpostijärjestelmä OMS:lle") (synopsis "Git- ja markdown-pohjainen masssasähköpostijärjestelmä OMS:lle")
@ -471,17 +468,20 @@ representations used for @@Generic1@@ are modified slightly.")
(define ghc-filestore (define ghc-filestore
(package (package
(name "ghc-filestore") (name "ghc-filestore")
(version "0.6.5.1") (version "0.6.5")
(source (origin (source (origin
(method url-fetch) (method url-fetch)
(uri (hackage-uri "filestore" version)) (uri (hackage-uri "filestore" version))
(sha256 (sha256
(base32 (base32
"1m6rav1rcigckakw8ky27lbwh5a9q8xl7nvv358ljykmvyl1j2lc")))) "0z29273vdqjsrj4vby0gp7d12wg9nkzq9zgqg18db0p5948jw1dh"))))
(build-system haskell-build-system) (build-system haskell-build-system)
(properties '((upstream-name . "filestore"))) (properties '((upstream-name . "filestore")))
(inputs (list ghc-utf8-string ghc-xml ghc-split ghc-diff ghc-old-locale git mercurial)) (inputs (list ghc-utf8-string ghc-xml ghc-split ghc-diff ghc-old-locale git mercurial))
(native-inputs (list ghc-hunit)) (native-inputs (list ghc-hunit))
(arguments
`(#:cabal-revision ("1"
"1v9xqm0112knv6za05qf310ldndrc0h3xhajgwjaycbzkrknz4n7")))
(home-page "http://hackage.haskell.org/package/filestore") (home-page "http://hackage.haskell.org/package/filestore")
(synopsis "Interface for versioning file stores.") (synopsis "Interface for versioning file stores.")
(description (description

View File

@ -30,7 +30,7 @@ the tiedote.md user on this system.")
(sendmail-path (sendmail-path
(string "/run/privileged/bin/sendmail") (string "/run/privileged/bin/sendmail")
"Path to a sendmail compatible mailing executable.") "Path to a sendmail compatible mailing executable.")
(webhook-port (port
(integer 3000) (integer 3000)
"Port to listen on for webhook notifications.") "Port to listen on for webhook notifications.")
(socket-path (socket-path
@ -54,36 +54,10 @@ the tiedote.md user on this system.")
(home-directory state-directory) (home-directory state-directory)
(shell (file-append bash-minimal "/bin/bash")))))) (shell (file-append bash-minimal "/bin/bash"))))))
(define (make-tiedote.md-server-script config)
(match-record config <tiedote.md-configuration>
(socket-path email-address sender-name webhook-port sendmail-path
remote-branch remote-url state-directory)
(program-file "tiedote.md-server"
#~(begin
; use utf8 before starting tiedote.md to be able to pass utf characters as arguments
(setlocale LC_ALL "C.UTF-8")
; use utf8 after exec so that ghc text library doesn't crash from IO
(setenv "LANG" "C.UTF-8")
(let ((tiedote.md #$(file-append tiedote-md "/bin/tiedote.md"))
(repo-path (string-append #$state-directory "/git-repo")))
(apply execl
`(,tiedote.md
,tiedote.md
"--address" #$email-address
"--sender-name" #$sender-name
"--sendmail" #$sendmail-path
"--socket" #$socket-path
"server"
"--repository" ,repo-path
"--port" #$(number->string webhook-port)
"--remote-url" #$remote-url
,@(if #$(maybe-value-set? remote-branch)
(list "--remote-branch" #$remote-branch)
'()))))))))
(define (tiedote.md-shepherd-service config) (define (tiedote.md-shepherd-service config)
(match-record config <tiedote.md-configuration> (match-record config <tiedote.md-configuration>
(state-directory socket-path) (state-directory socket-path email-address sender-name port sendmail-path
remote-branch remote-url)
(list (shepherd-service (list (shepherd-service
(documentation "A simple mass email system") (documentation "A simple mass email system")
(requirement '(networking user-processes)) (requirement '(networking user-processes))
@ -91,46 +65,48 @@ the tiedote.md user on this system.")
(start #~(let* ((user (getpw "tiedote.md")) (start #~(let* ((user (getpw "tiedote.md"))
(uid (passwd:uid user)) (uid (passwd:uid user))
(gid (passwd:gid user)) (gid (passwd:gid user))
(socket-directory (dirname #$socket-path))) (socket-directory (dirname #$socket-path))
(repo-path (string-append #$state-directory "/git-repo")))
(begin (begin
(mkdir-p socket-directory) (mkdir-p socket-directory)
(chown socket-directory uid gid) (chown socket-directory uid gid)
(make-forkexec-constructor (list #$(make-tiedote.md-server-script config)) (make-forkexec-constructor
#:user "tiedote.md" (list #$(file-append tiedote-md "/bin/tiedote.md")
#:group "tiedote.md" "--address" #$email-address
#:environment-variables "--sender-name" #$sender-name
(cons* "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt" "--sendmail" #$sendmail-path
(default-environment-variables)) "--socket" #$socket-path
#:directory #$state-directory)))) "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 (cons "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt"
(default-environment-variable))
#:directory #$state-directory))))
(stop #~(make-kill-destructor)))))) (stop #~(make-kill-destructor))))))
(define (tiedote.md-activation config) (define (tiedote.md-activation config)
(match-record config <tiedote.md-configuration> (match-record config <tiedote.md-configuration>
(state-directory email-address sender-name sendmail-path socket-path) (state-directory email-address sender-name sendmail-path socket-path)
(let* ((tiedote.md (file-append tiedote-md "/bin/tiedote.md")) (let* ((receive-exec (list (file-append tiedote-md "/bin/tiedote.md") ; file to exec
(receive-exec (list tiedote.md ; file to exec (file-append tiedote-md "/bin/tiedote.md") ; arg $0
tiedote.md ; arg $0
"--address" email-address "--address" email-address
"--sender-name" sender-name "--sender-name" sender-name
"--sendmail" sendmail-path "--sendmail" sendmail-path
"--socket" socket-path "--socket" socket-path))
"receive"))
(receive-script (program-file "tiedote.md-receive" (receive-script (program-file "tiedote.md-receive"
#~(begin #~(apply execl #$receive-exec)))
(setlocale LC_ALL "C.UTF-8")
(setenv "LANG" "C.UTF-8")
(apply execl '#$receive-exec))))
(forward-file (mixed-text-file "dot-forward" "|" receive-script))) (forward-file (mixed-text-file "dot-forward" "|" receive-script)))
#~(let* ((.forward (string-append #$state-directory "/.forward")) #~(let ((.forward (string-append #$state-directory "/.forward")))
(user (getpw "tiedote.md"))
(uid (passwd:uid user))
(gid (passwd:gid user)))
(if (file-exists? .forward) (if (file-exists? .forward)
(delete-file .forward)) (delete-file .forward))
; smtpd does not follow symbolic links and requires .forward files to (symlink #$forward-file .forward)))))
; be owned by the recipient
(copy-file #$forward-file .forward)
(chown .forward uid gid)))))
(define tiedote.md-service-type (define tiedote.md-service-type
(service-type (service-type

View File

@ -41,7 +41,9 @@ lähettämisestä ja Git-tietovaraston päivittämisestä, kun se saa muutoksist
ilmoituksen HTTP POST -pyyntönä (esim. Git-palvelun webhookista). ilmoituksen HTTP POST -pyyntönä (esim. Git-palvelun webhookista).
Palvelimen voi käynnistää komennolla `tiedote.md server`. Mahdolliset asetukset Palvelimen voi käynnistää komennolla `tiedote.md server`. Mahdolliset asetukset
saa listattua lisäämällä komentoon `--help` valitsimen. saa listattua lisäämällä komentoon `--help` valitsimen. `--address`
valitsimesta tulee huomata, että osoitteessa voi käyttää vain ASCII-merkkejä
(ks. [#15](https://git.olarinmaensamoojat.fi/OMS/tiedote.md/issues/15)).
Sähköpostin lähettämiseen tarvitaan `sendmail`-yhteensopiva MTA (mail transfer Sähköpostin lähettämiseen tarvitaan `sendmail`-yhteensopiva MTA (mail transfer
agent, sähköpostin välitysohjelma), jollaisen useimmat sähköpostipalvelimet agent, sähköpostin välitysohjelma), jollaisen useimmat sähköpostipalvelimet

View File

@ -3,7 +3,7 @@
(url "https://git.savannah.gnu.org/git/guix.git") (url "https://git.savannah.gnu.org/git/guix.git")
(branch "master") (branch "master")
(commit (commit
"b2943f6791d02feda7901c3dc2c777193e664455") "a6fc564bcc32ba599fc701f340c2d59c47bb225b")
(introduction (introduction
(make-channel-introduction (make-channel-introduction
"9edb3f66fd807b096b48283debdcddccfea34bad" "9edb3f66fd807b096b48283debdcddccfea34bad"

View File

@ -4,6 +4,7 @@
module TiedoteMD.Send where module TiedoteMD.Send where
import Control.Concurrent (threadDelay) import Control.Concurrent (threadDelay)
import Control.Exception (throwIO)
import Control.Lens (set, _Just) import Control.Lens (set, _Just)
import Control.Monad (forever, unless) import Control.Monad (forever, unless)
import Data.Acid (AcidState, query, update) import Data.Acid (AcidState, query, update)
@ -14,7 +15,8 @@ import Data.MIME.Charset (defaultCharsets)
import Data.Set (Set) import Data.Set (Set)
import Data.Time (getCurrentTime) import Data.Time (getCurrentTime)
import System.Exit (ExitCode(..)) import System.Exit (ExitCode(..))
import System.IO (hClose, stdout, stderr) import System.Exit.Codes (codeTempFail)
import System.IO (hClose, stdout)
import System.Process (CreateProcess(..), StdStream(..), waitForProcess, createProcess, proc) import System.Process (CreateProcess(..), StdStream(..), waitForProcess, createProcess, proc)
import System.Random (getStdRandom, uniform) import System.Random (getStdRandom, uniform)
@ -23,25 +25,18 @@ import qualified Data.IMF as IMF
import qualified Data.List.NonEmpty as NE import qualified Data.List.NonEmpty as NE
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.IO as T
import TiedoteMD.State import TiedoteMD.State
import TiedoteMD.Types import TiedoteMD.Types
sendmail :: FilePath -> LBS.ByteString -> IO () sendmail :: FilePath -> LBS.ByteString -> IO ()
sendmail path bs = do sendmail path bs = do
(Just stdin, _, Just stderr, processHandle) <- createProcess (Just stdin, _, _, processHandle) <- createProcess (proc path ["-t"]) {std_in = CreatePipe}
(proc path ["-t"]) {std_in = CreatePipe, std_err = CreatePipe}
LBS.hPut stdin bs LBS.hPut stdin bs
hClose stdin hClose stdin
errors <- T.hGetContents stderr
exitCode <- waitForProcess processHandle exitCode <- waitForProcess processHandle
-- TODO: handle System.Exit.Codes.codeTempFail differently from other failures unless (exitCode `elem` [ExitSuccess, codeTempFail]) $
unless (exitCode == ExitSuccess) $ do throwIO $ ProcessError (T.pack path) exitCode
T.hPutStr System.IO.stderr $
"Sending mail with " <> (T.pack path) <> " failed with " <> (T.pack $ show exitCode)
unless (T.null errors) $ T.hPutStrLn System.IO.stderr $ ":\n" <> errors
T.hPutStrLn System.IO.stderr ""
manageQueue :: AcidState State -> Mailbox -> FilePath -> IO () manageQueue :: AcidState State -> Mailbox -> FilePath -> IO ()
manageQueue acid sender sendmailPath = forever $ do manageQueue acid sender sendmailPath = forever $ do