fix: apply managed Nginx public entry without service restart
This commit is contained in:
1 parent
36d653b32b
commit
e4f1059880
11 files changed
+338
-33
No files matched your search
@@ -282,6 +282,25 @@ func ConfigureMode(dataDir, mode string) error {
|
||||
return writePersisted(dataDir, "tls-mode", mode)
|
||||
}
|
||||
|
||||
// AdoptNginxConfiguration updates the in-process public address after the
|
||||
// managed Nginx site has passed validation and reloaded successfully.
|
||||
func AdoptNginxConfiguration(dataDir string) error {
|
||||
config, err := configFromEnvironment(dataDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if config.mode != "nginx" {
|
||||
return fmt.Errorf("当前入口不是 Nginx 模式")
|
||||
}
|
||||
state.Lock()
|
||||
defer state.Unlock()
|
||||
if state.config.mode != "nginx" || state.config.dataDir != dataDir {
|
||||
return fmt.Errorf("运行模式不支持热更新 Nginx 入口")
|
||||
}
|
||||
state.config = config
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start keeps certificates in the persistent data directory. Issuance occurs
|
||||
// on the first TLS handshake, and autocert handles renewal.
|
||||
func Start(handler http.Handler, dataDir string) error {
|
||||
@@ -377,8 +396,8 @@ func Status() CertificateStatus {
|
||||
status.ConfiguredScheme = normalizeScheme(desired.scheme)
|
||||
status.ConfiguredPort = desired.port
|
||||
status.ConfiguredPublicBase = PublicBaseURL(status.ConfiguredScheme, desired.domain, desired.port)
|
||||
status.RestartRequired = desired.domain != config.domain || desired.mode != config.mode ||
|
||||
normalizeScheme(desired.scheme) != scheme || desired.port != config.port
|
||||
status.RestartRequired = desired.mode != config.mode || (config.mode != "nginx" &&
|
||||
(desired.domain != config.domain || normalizeScheme(desired.scheme) != scheme || desired.port != config.port))
|
||||
}
|
||||
if config.mode == "nginx" {
|
||||
// Certbot or uploaded PEMs own HTTPS certificates. HTTP needs no leaf.
|
||||
|
||||
@@ -89,6 +89,35 @@ func TestNginxModeDoesNotBindGoListeners(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNginxEntryCanAdoptWithoutRestart(t *testing.T) {
|
||||
t.Setenv("VPN_TLS_MODE", "")
|
||||
t.Setenv("VPN_TLS_DOMAIN", "")
|
||||
t.Setenv("VPN_TLS_SCHEME", "")
|
||||
t.Setenv("VPN_TLS_PORT", "")
|
||||
dir := t.TempDir()
|
||||
if err := ConfigureMode(dir, "nginx"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ConfigurePublicEntry(dir, "https", "first.example.com", 443); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := Start(http.NotFoundHandler(), dir); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ConfigurePublicEntry(dir, "http", "second.example.com", 8080); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if s := Status(); s.PublicBase == "http://second.example.com:8080" || s.RestartRequired {
|
||||
t.Fatalf("unapplied nginx config must not claim the new entry or require process restart: %+v", s)
|
||||
}
|
||||
if err := AdoptNginxConfiguration(dir); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if s := Status(); s.RestartRequired || s.ConfiguredPublicBase != "http://second.example.com:8080" || s.PublicBase != s.ConfiguredPublicBase {
|
||||
t.Fatalf("nginx config was not adopted: %+v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicBaseURL(t *testing.T) {
|
||||
cases := []struct {
|
||||
scheme, host string
|
||||
|
||||
Reference in new issue
Block a user