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
					
				| @ -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 New Issue
	
	Block a user