* 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.21.12.1
| @@ -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 | |||||
| SendmailArgs []string | |||||
| SendmailPath 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> | ||||