package main import ( "errors" "io/fs" "log" "os" "os/exec" "path/filepath" "time" ) func (web *Web) spawnCertbot() { web.mux.Lock() defer web.mux.Unlock() if web.CertbotRenewalGap == 0 { web.CertbotRenewalGap = DefaultCertbotRenewalGap } web.certbotDone = make(chan struct{}, 0) oneshot := make(chan struct{}, 0) _, err := os.Lstat(filepath.Join("/etc/letsencrypt/live", web.GitHost)) if errors.Is(err, fs.ErrNotExist) { close(oneshot) } ticker := time.NewTicker(web.CertbotRenewalGap) go func() { for { select { case <-oneshot: web.RunCertbot() case <-ticker.C: web.RunCertbot() case <-web.certbotDone: ticker.Stop() return } } }() } func (web *Web) killCertbot() { close(web.certbotDone) } func (web *Web) RunCertbot() { web.killHTTP80() defer web.spawnHTTP80() var args []string if GruauCertbotAgreeTOS { args = append(args, "--agree-tos") } if GruauCertbotEmail != "" { args = append(args, "-m", GruauCertbotEmail) } args = append(args, "--non-interactive", "certonly", "--standalone") args = append(args, "--preferred-challenges", "http", "-d", web.GitHost) cmd := exec.Command("/usr/bin/certbot", args...) cmd.Env = make([]string, 0) cmd.Dir = "/etc/letsencrypt" out, err := cmd.CombinedOutput() if err != nil { log.Printf("gruau: certbot failed: %v, %q", err, string(out)) return } log.Printf("gruau: certbot succeeded: %q", string(out)) }