From cab5ff2c780b41fdaee7941faea03df1ca0351f6 Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Sat, 6 May 2023 23:24:25 +0800 Subject: [PATCH] feat: get lego's logs and send them to frontend --- .../domain/cert/components/ObtainCert.vue | 5 ++- server/internal/cert/cert.go | 41 +++++++++++++++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/frontend/src/views/domain/cert/components/ObtainCert.vue b/frontend/src/views/domain/cert/components/ObtainCert.vue index c9804976..61bc2b15 100644 --- a/frontend/src/views/domain/cert/components/ObtainCert.vue +++ b/frontend/src/views/domain/cert/components/ObtainCert.vue @@ -154,7 +154,10 @@ const issue_cert = async (config_name: string, server_name: string, callback: Fu switch (r.status) { case 'info': - progressPercent.value += 5 + // If it's a lego log, do not increase the percent. + if (r.message.indexOf('[INFO]') == -1) { + progressPercent.value += 5 + } break default: modalClosable.value = true diff --git a/server/internal/cert/cert.go b/server/internal/cert/cert.go index 33334188..05013307 100644 --- a/server/internal/cert/cert.go +++ b/server/internal/cert/cert.go @@ -7,7 +7,7 @@ import ( "crypto/rand" "crypto/tls" "github.com/0xJacky/Nginx-UI/logger" - dns2 "github.com/0xJacky/Nginx-UI/server/internal/cert/dns" + "github.com/0xJacky/Nginx-UI/server/internal/cert/dns" "github.com/0xJacky/Nginx-UI/server/internal/nginx" "github.com/0xJacky/Nginx-UI/server/query" "github.com/0xJacky/Nginx-UI/server/settings" @@ -15,9 +15,12 @@ import ( "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/challenge/http01" "github.com/go-acme/lego/v4/lego" - "github.com/go-acme/lego/v4/providers/dns" + lego_log "github.com/go-acme/lego/v4/log" + dns_providers "github.com/go-acme/lego/v4/providers/dns" "github.com/go-acme/lego/v4/registration" "github.com/pkg/errors" + "io" + "log" "net/http" "os" "path/filepath" @@ -52,6 +55,18 @@ type ConfigPayload struct { DNSCredentialID int `json:"dns_credential_id"` } +type channelWriter struct { + ch chan []byte +} + +func (cw *channelWriter) Write(p []byte) (n int, err error) { + n = len(p) + temp := make([]byte, n) + copy(temp, p) + cw.ch <- temp + return n, nil +} + func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error) { defer func() { if err := recover(); err != nil { @@ -59,6 +74,10 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error) } }() + // Use a channel to receive lego log + logChannel := make(chan []byte, 1024) + defer close(logChannel) + domain := payload.ServerName // Create a user. New accounts need an email and private key to start. @@ -75,6 +94,20 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error) Key: privateKey, } + // Hijack lego's log + cw := &channelWriter{ch: logChannel} + multiWriter := io.MultiWriter(os.Stderr, cw) + l := log.New(os.Stderr, "", log.LstdFlags) + l.SetOutput(multiWriter) + lego_log.Logger = l + + // Start a goroutine to fetch and process logs from channel + go func() { + for msg := range logChannel { + logChan <- string(msg) + } + }() + config := lego.NewConfig(&myUser) if settings.ServerSettings.Demo { @@ -120,7 +153,7 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error) logChan <- "Using DNS01 challenge provider" code := dnsCredential.Config.Code - pConfig, ok := dns2.GetProvider(code) + pConfig, ok := dns.GetProvider(code) if !ok { errChan <- errors.Wrap(err, "provider not found") @@ -135,7 +168,7 @@ func IssueCert(payload *ConfigPayload, logChan chan string, errChan chan error) logChan <- "Cleaning environment variables" pConfig.CleanEnv() }() - provider, err := dns.NewDNSChallengeProviderByName(code) + provider, err := dns_providers.NewDNSChallengeProviderByName(code) if err != nil { break }