Sendmail should create a process on the gitea system and have a default timeout (#11256)
* Make sure that sendmail processes register with the process manager * Provide a timeout for these (initially of 5 minutes) * Add configurable value and tie in to documentation * Tie in to the admin config page. Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
319eb83112
commit
4f9d59be17
6 changed files with 25 additions and 4 deletions
|
@ -649,6 +649,8 @@ MAILER_TYPE = smtp
|
||||||
SENDMAIL_PATH = sendmail
|
SENDMAIL_PATH = sendmail
|
||||||
; Specify any extra sendmail arguments
|
; Specify any extra sendmail arguments
|
||||||
SENDMAIL_ARGS =
|
SENDMAIL_ARGS =
|
||||||
|
; Timeout for Sendmail
|
||||||
|
SENDMAIL_TIMEOUT = 5m
|
||||||
|
|
||||||
[cache]
|
[cache]
|
||||||
; if the cache enabled
|
; if the cache enabled
|
||||||
|
|
|
@ -410,6 +410,7 @@ set name for unique queues. Individual queues will default to
|
||||||
- Enabling dummy will ignore all settings except `ENABLED`, `SUBJECT_PREFIX` and `FROM`.
|
- Enabling dummy will ignore all settings except `ENABLED`, `SUBJECT_PREFIX` and `FROM`.
|
||||||
- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be
|
- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be
|
||||||
command or full path).
|
command or full path).
|
||||||
|
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
|
||||||
- ``IS_TLS_ENABLED`` : **false** : Decide if SMTP connections should use TLS.
|
- ``IS_TLS_ENABLED`` : **false** : Decide if SMTP connections should use TLS.
|
||||||
|
|
||||||
## Cache (`cache`)
|
## Cache (`cache`)
|
||||||
|
|
|
@ -6,6 +6,7 @@ package setting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/mail"
|
"net/mail"
|
||||||
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
|
@ -35,8 +36,9 @@ type Mailer struct {
|
||||||
IsTLSEnabled bool
|
IsTLSEnabled bool
|
||||||
|
|
||||||
// Sendmail sender
|
// Sendmail sender
|
||||||
SendmailPath string
|
SendmailPath string
|
||||||
SendmailArgs []string
|
SendmailArgs []string
|
||||||
|
SendmailTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -69,7 +71,8 @@ func newMailService() {
|
||||||
IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(),
|
IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(),
|
||||||
SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString(""),
|
SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString(""),
|
||||||
|
|
||||||
SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"),
|
SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"),
|
||||||
|
SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute),
|
||||||
}
|
}
|
||||||
MailService.From = sec.Key("FROM").MustString(MailService.User)
|
MailService.From = sec.Key("FROM").MustString(MailService.User)
|
||||||
|
|
||||||
|
|
|
@ -2119,6 +2119,7 @@ config.mailer_user = User
|
||||||
config.mailer_use_sendmail = Use Sendmail
|
config.mailer_use_sendmail = Use Sendmail
|
||||||
config.mailer_sendmail_path = Sendmail Path
|
config.mailer_sendmail_path = Sendmail Path
|
||||||
config.mailer_sendmail_args = Extra Arguments to Sendmail
|
config.mailer_sendmail_args = Extra Arguments to Sendmail
|
||||||
|
config.mailer_sendmail_timeout = Sendmail Timeout
|
||||||
config.send_test_mail = Send Testing Email
|
config.send_test_mail = Send Testing Email
|
||||||
config.test_mail_failed = Failed to send a testing email to '%s': %v
|
config.test_mail_failed = Failed to send a testing email to '%s': %v
|
||||||
config.test_mail_sent = A testing email has been sent to '%s'.
|
config.test_mail_sent = A testing email has been sent to '%s'.
|
||||||
|
|
|
@ -7,6 +7,7 @@ package mailer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -20,6 +21,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/process"
|
||||||
"code.gitea.io/gitea/modules/queue"
|
"code.gitea.io/gitea/modules/queue"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
|
@ -244,7 +246,14 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
|
||||||
args = append(args, setting.MailService.SendmailArgs...)
|
args = append(args, setting.MailService.SendmailArgs...)
|
||||||
args = append(args, to...)
|
args = append(args, to...)
|
||||||
log.Trace("Sending with: %s %v", setting.MailService.SendmailPath, args)
|
log.Trace("Sending with: %s %v", setting.MailService.SendmailPath, args)
|
||||||
cmd := exec.Command(setting.MailService.SendmailPath, args...)
|
|
||||||
|
pm := process.GetManager()
|
||||||
|
desc := fmt.Sprintf("SendMail: %s %v", setting.MailService.SendmailPath, args)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(graceful.GetManager().HammerContext(), setting.MailService.SendmailTimeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(ctx, setting.MailService.SendmailPath, args...)
|
||||||
pipe, err := cmd.StdinPipe()
|
pipe, err := cmd.StdinPipe()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -255,12 +264,15 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid := pm.Add(desc, cancel)
|
||||||
|
|
||||||
_, err = msg.WriteTo(pipe)
|
_, err = msg.WriteTo(pipe)
|
||||||
|
|
||||||
// we MUST close the pipe or sendmail will hang waiting for more of the message
|
// we MUST close the pipe or sendmail will hang waiting for more of the message
|
||||||
// Also we should wait on our sendmail command even if something fails
|
// Also we should wait on our sendmail command even if something fails
|
||||||
closeError = pipe.Close()
|
closeError = pipe.Close()
|
||||||
waitError = cmd.Wait()
|
waitError = cmd.Wait()
|
||||||
|
pm.Remove(pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if closeError != nil {
|
} else if closeError != nil {
|
||||||
|
|
|
@ -228,6 +228,8 @@
|
||||||
<dd>{{.Mailer.SendmailPath}}</dd>
|
<dd>{{.Mailer.SendmailPath}}</dd>
|
||||||
<dt>{{.i18n.Tr "admin.config.mailer_sendmail_args"}}</dt>
|
<dt>{{.i18n.Tr "admin.config.mailer_sendmail_args"}}</dt>
|
||||||
<dd>{{.Mailer.SendmailArgs}}</dd>
|
<dd>{{.Mailer.SendmailArgs}}</dd>
|
||||||
|
<dt>{{.i18n.Tr "admin.config.mailer_sendmail_timeout"}}</dt>
|
||||||
|
<dd>{{.Mailer.SendmailTimeout}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||||
{{end}}
|
{{end}}
|
||||||
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
|
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
|
||||||
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd><br>
|
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd><br>
|
||||||
|
|
Loading…
Reference in a new issue