修复部署验收回归问题

This commit is contained in:
smail 2026-09-22 06:33:03 +08:00
parent 6c35fcffc2
commit 5ad2b9d63b
3 changed files with 61 additions and 27 deletions

View File

@ -126,6 +126,22 @@ func retainPreviousSSL(root string, next *SSLConfig, previous SSLConfig) {
}
}
func removeFlatSSLFile(directory, path string) error {
info, err := os.Lstat(path)
if err != nil {
return err
}
if info.Mode()&os.ModeSymlink != 0 || !info.Mode().IsRegular() || hasMultipleFileLinks(path) {
return ErrUnsafeSSLFile
}
storage, err := os.OpenRoot(directory)
if err != nil {
return err
}
defer storage.Close()
return storage.Remove(filepath.Base(path))
}
func pruneFlatSSLLocked(root string, protected []SSLConfig) error {
// 当前材料不可用时暂停回收,避免丢失仍可恢复的历史证书。
if len(protected) == 0 {
@ -165,11 +181,6 @@ func pruneFlatSSLLocked(root string, protected []SSLConfig) error {
keep[publicPath] = true
}
}
storage, err := os.OpenRoot(directory)
if err != nil {
return err
}
defer storage.Close()
for _, entry := range entries {
publicPath := filepath.Join(directory, entry.Name())
privatePath := strings.TrimSuffix(publicPath, ".crt") + ".key"
@ -189,7 +200,7 @@ func pruneFlatSSLLocked(root string, protected []SSLConfig) error {
if err != nil {
// 先删私钥、后删证书;中断留下的孤立证书可在下轮安全重试。
if _, statErr := os.Lstat(privatePath); os.IsNotExist(statErr) {
if err := storage.Remove(filepath.Base(publicPath)); err != nil {
if err := removeFlatSSLFile(directory, publicPath); err != nil {
return err
}
}
@ -209,9 +220,9 @@ func pruneFlatSSLLocked(root string, protected []SSLConfig) error {
}
continue
}
err = storage.Remove(filepath.Base(privatePath))
err = removeFlatSSLFile(directory, privatePath)
if err == nil {
err = storage.Remove(filepath.Base(publicPath))
err = removeFlatSSLFile(directory, publicPath)
}
unlock()
if err := errors.Join(err, lease.Close()); err != nil {

View File

@ -149,28 +149,26 @@ func pruneManagedSSLLocked(root string, protected []SSLConfig) error {
}
// 磁盘引用也必须保留,避免其他管理器实例或已提交未发布的候选被删除。
configRoot, err := os.OpenRoot(filepath.Join(root, "config"))
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
data, err := configRoot.ReadFile("ssl.json")
_ = configRoot.Close()
if err == nil {
var section SSLSectionConfig
if err := ParseStrict(data, &section); err != nil {
return err
}
if section.TLS.CertificateRef != "" {
protected = append(protected, section.TLS)
reference, err := resolveManagedSSLPathsAtRoot(root, section.TLS)
if err != nil {
data, readErr := configRoot.ReadFile("ssl.json")
_ = configRoot.Close()
if readErr == nil {
var section SSLSectionConfig
if err := ParseStrict(data, &section); err != nil {
return err
}
if legacyManagedSSLReference(section.TLS.CertificateRef) {
keep[filepath.Dir(reference.CertificatePath)] = true
if section.TLS.CertificateRef != "" {
protected = append(protected, section.TLS)
reference, err := resolveManagedSSLPathsAtRoot(root, section.TLS)
if err != nil {
return err
}
if legacyManagedSSLReference(section.TLS.CertificateRef) {
keep[filepath.Dir(reference.CertificatePath)] = true
}
}
} else if !os.IsNotExist(readErr) {
return readErr
}
} else if !os.IsNotExist(err) {
return err

View File

@ -338,7 +338,7 @@ func (s *TransactionStore) Recover() error {
return ErrTransactionPhase
}
}
return nil
return cleanupEmptyTransactionStaging(transactions)
}
func (s *TransactionStore) beforePhase(phase TransactionPhase) error {
@ -619,6 +619,31 @@ func secureTransactionStagingDirectory(transactions string) (string, error) {
return directory, nil
}
func cleanupEmptyTransactionStaging(transactions string) error {
directory := filepath.Join(filepath.Dir(transactions), "transaction-staging")
info, err := os.Lstat(directory)
if os.IsNotExist(err) {
return nil
}
if err != nil {
return err
}
if info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {
return ErrTransactionInvalid
}
entries, err := os.ReadDir(directory)
if err != nil {
return err
}
if len(entries) != 0 {
return nil
}
if err := os.Remove(directory); err != nil {
return err
}
return atomicfile.SyncDirectory(filepath.Dir(transactions))
}
func validateTransactionDirectory(directory string) error {
if err := ensureDirectory(directory); err != nil {
return err