fix(deploy): 在线更新 - 在停服前校验更新器写入权限并修正 systemd 可写目录
This commit is contained in:
@@ -123,6 +123,14 @@ func (m *Manager) preflight(composePath, targetVersion string) error {
|
||||
if _, err := os.Stat(m.envPath()); err != nil {
|
||||
return fmt.Errorf("读取部署环境:%w", err)
|
||||
}
|
||||
if m.config.SelfUpdate {
|
||||
if strings.TrimSpace(m.config.BinaryPath) == "" {
|
||||
return errors.New("检查 Host Updater 安装目录:二进制路径为空")
|
||||
}
|
||||
if err := checkWritableDirectory(filepath.Dir(m.config.BinaryPath)); err != nil {
|
||||
return fmt.Errorf("检查 Host Updater 安装目录:%w", err)
|
||||
}
|
||||
}
|
||||
var disk syscall.Statfs_t
|
||||
if err := syscall.Statfs(m.config.BackupDir, &disk); err != nil {
|
||||
return fmt.Errorf("检查备份磁盘空间:%w", err)
|
||||
@@ -144,6 +152,26 @@ func (m *Manager) preflight(composePath, targetVersion string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkWritableDirectory(directory string) error {
|
||||
directory = strings.TrimSpace(directory)
|
||||
if directory == "" {
|
||||
return errors.New("Host Updater 二进制路径为空")
|
||||
}
|
||||
temporary, err := os.CreateTemp(directory, ".updater-write-test-*")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := temporary.Name()
|
||||
if closeErr := temporary.Close(); closeErr != nil {
|
||||
_ = os.Remove(name)
|
||||
return closeErr
|
||||
}
|
||||
if removeErr := os.Remove(name); removeErr != nil {
|
||||
return removeErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) prepareUpdaterBinary(targetVersion string) (string, error) {
|
||||
if !m.config.SelfUpdate {
|
||||
return "", nil
|
||||
|
||||
@@ -129,3 +129,20 @@ func TestCreateBackupReadsBackendDataAsRoot(t *testing.T) {
|
||||
}
|
||||
t.Fatalf("backend data backup did not use root: %#v", runner.calls)
|
||||
}
|
||||
|
||||
func TestCheckWritableDirectory(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
if err := checkWritableDirectory(directory); err != nil {
|
||||
t.Fatalf("writable directory rejected: %v", err)
|
||||
}
|
||||
entries, err := os.ReadDir(directory)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(entries) != 0 {
|
||||
t.Fatalf("write probe was not cleaned up: %v", entries)
|
||||
}
|
||||
if err := checkWritableDirectory(filepath.Join(directory, "missing")); err == nil {
|
||||
t.Fatal("missing directory was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user