* 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>tags/v1.13.0-dev
@@ -649,6 +649,8 @@ MAILER_TYPE = smtp | |||
SENDMAIL_PATH = sendmail | |||
; Specify any extra sendmail arguments | |||
SENDMAIL_ARGS = | |||
; Timeout for Sendmail | |||
SENDMAIL_TIMEOUT = 5m | |||
[cache] | |||
; 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`. | |||
- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be | |||
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. | |||
## Cache (`cache`) |
@@ -6,6 +6,7 @@ package setting | |||
import ( | |||
"net/mail" | |||
"time" | |||
"code.gitea.io/gitea/modules/log" | |||
@@ -35,8 +36,9 @@ type Mailer struct { | |||
IsTLSEnabled bool | |||
// Sendmail sender | |||
SendmailPath string | |||
SendmailArgs []string | |||
SendmailPath string | |||
SendmailArgs []string | |||
SendmailTimeout time.Duration | |||
} | |||
var ( | |||
@@ -69,7 +71,8 @@ func newMailService() { | |||
IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(), | |||
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) | |||
@@ -2119,6 +2119,7 @@ config.mailer_user = User | |||
config.mailer_use_sendmail = Use Sendmail | |||
config.mailer_sendmail_path = Sendmail Path | |||
config.mailer_sendmail_args = Extra Arguments to Sendmail | |||
config.mailer_sendmail_timeout = Sendmail Timeout | |||
config.send_test_mail = Send Testing Email | |||
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'. |
@@ -7,6 +7,7 @@ package mailer | |||
import ( | |||
"bytes" | |||
"context" | |||
"crypto/tls" | |||
"fmt" | |||
"io" | |||
@@ -20,6 +21,7 @@ import ( | |||
"code.gitea.io/gitea/modules/base" | |||
"code.gitea.io/gitea/modules/graceful" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/process" | |||
"code.gitea.io/gitea/modules/queue" | |||
"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, to...) | |||
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() | |||
if err != nil { | |||
@@ -255,12 +264,15 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error { | |||
return err | |||
} | |||
pid := pm.Add(desc, cancel) | |||
_, err = msg.WriteTo(pipe) | |||
// 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 | |||
closeError = pipe.Close() | |||
waitError = cmd.Wait() | |||
pm.Remove(pid) | |||
if err != nil { | |||
return err | |||
} else if closeError != nil { |
@@ -228,6 +228,8 @@ | |||
<dd>{{.Mailer.SendmailPath}}</dd> | |||
<dt>{{.i18n.Tr "admin.config.mailer_sendmail_args"}}</dt> | |||
<dd>{{.Mailer.SendmailArgs}}</dd> | |||
<dt>{{.i18n.Tr "admin.config.mailer_sendmail_timeout"}}</dt> | |||
<dd>{{.Mailer.SendmailTimeout}} {{.i18n.Tr "tool.raw_seconds"}}</dd> | |||
{{end}} | |||
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt> | |||
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd><br> |