cmd/cli: cleanup more ctrld generated files

While at it, implement function to open log file on Windows for sharing
delete. So the log file could be backup correctly.

This may fix #303
This commit is contained in:
Cuong Manh Le
2024-08-07 15:51:11 +07:00
committed by Cuong Manh Le
parent 905f2d08c5
commit 18a19a3aa2
4 changed files with 87 additions and 9 deletions
+18 -4
View File
@@ -48,7 +48,11 @@ import (
// selfCheckInternalTestDomain is used for testing ctrld self response to clients. // selfCheckInternalTestDomain is used for testing ctrld self response to clients.
const selfCheckInternalTestDomain = "ctrld" + loopTestDomain const selfCheckInternalTestDomain = "ctrld" + loopTestDomain
const windowsForwardersFilename = ".forwarders.txt" const (
windowsForwardersFilename = ".forwarders.txt"
oldBinSuffix = "_previous"
oldLogSuffix = ".1"
)
var ( var (
version = "dev" version = "dev"
@@ -605,7 +609,13 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`,
// Config file. // Config file.
files = append(files, v.ConfigFileUsed()) files = append(files, v.ConfigFileUsed())
// Log file. // Log file.
files = append(files, cfg.Service.LogPath) logFile := normalizeLogFilePath(cfg.Service.LogPath)
files = append(files, logFile)
// Backup log file.
oldLogFile := logFile + oldLogSuffix
if _, err := os.Stat(oldLogFile); err == nil {
files = append(files, oldLogFile)
}
// Socket files. // Socket files.
if dir, _ := socketDir(); dir != "" { if dir, _ := socketDir(); dir != "" {
files = append(files, filepath.Join(dir, ctrldControlUnixSock)) files = append(files, filepath.Join(dir, ctrldControlUnixSock))
@@ -624,11 +634,15 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`,
files = append(files, absHomeDir(windowsForwardersFilename)) files = append(files, absHomeDir(windowsForwardersFilename))
} }
// Binary itself. // Binary itself.
bin, _ := os.Executable() bin, _ := os.Executable()
if bin != "" && supportedSelfDelete { if bin != "" && supportedSelfDelete {
files = append(files, bin) files = append(files, bin)
} }
// Backup file after upgrading.
oldBin := bin + oldBinSuffix
if _, err := os.Stat(oldBin); err == nil {
files = append(files, oldBin)
}
for _, file := range files { for _, file := range files {
if file == "" { if file == "" {
continue continue
@@ -922,7 +936,7 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`,
if _, err := s.Status(); errors.Is(err, service.ErrNotInstalled) { if _, err := s.Status(); errors.Is(err, service.ErrNotInstalled) {
svcInstalled = false svcInstalled = false
} }
oldBin := bin + "_previous" oldBin := bin + oldBinSuffix
baseUrl := upgradeChannel[upgradeChannelDefault] baseUrl := upgradeChannel[upgradeChannelDefault]
if len(args) > 0 { if len(args) > 0 {
channel := args[0] channel := args[0]
+7 -4
View File
@@ -64,8 +64,11 @@ func Main() {
} }
func normalizeLogFilePath(logFilePath string) string { func normalizeLogFilePath(logFilePath string) string {
if logFilePath == "" || filepath.IsAbs(logFilePath) || service.Interactive() { // In cleanup mode, we always want the full log file path.
return logFilePath if !cleanup {
if logFilePath == "" || filepath.IsAbs(logFilePath) || service.Interactive() {
return logFilePath
}
} }
if homedir != "" { if homedir != "" {
return filepath.Join(homedir, logFilePath) return filepath.Join(homedir, logFilePath)
@@ -122,14 +125,14 @@ func initLoggingWithBackup(doBackup bool) {
flags := os.O_CREATE | os.O_RDWR | os.O_APPEND flags := os.O_CREATE | os.O_RDWR | os.O_APPEND
if doBackup { if doBackup {
// Backup old log file with .1 suffix. // Backup old log file with .1 suffix.
if err := os.Rename(logFilePath, logFilePath+".1"); err != nil && !os.IsNotExist(err) { if err := os.Rename(logFilePath, logFilePath+oldLogSuffix); err != nil && !os.IsNotExist(err) {
mainLog.Load().Error().Msgf("could not backup old log file: %v", err) mainLog.Load().Error().Msgf("could not backup old log file: %v", err)
} else { } else {
// Backup was created, set flags for truncating old log file. // Backup was created, set flags for truncating old log file.
flags = os.O_CREATE | os.O_RDWR flags = os.O_CREATE | os.O_RDWR
} }
} }
logFile, err := os.OpenFile(logFilePath, flags, os.FileMode(0o600)) logFile, err := openLogFile(logFilePath, flags)
if err != nil { if err != nil {
mainLog.Load().Error().Msgf("failed to create log file: %v", err) mainLog.Load().Error().Msgf("failed to create log file: %v", err)
os.Exit(1) os.Exit(1)
+4
View File
@@ -9,3 +9,7 @@ import (
func hasElevatedPrivilege() (bool, error) { func hasElevatedPrivilege() (bool, error) {
return os.Geteuid() == 0, nil return os.Geteuid() == 0, nil
} }
func openLogFile(path string, flags int) (*os.File, error) {
return os.OpenFile(path, flags, os.FileMode(0o600))
}
+58 -1
View File
@@ -1,6 +1,11 @@
package cli package cli
import "golang.org/x/sys/windows" import (
"os"
"syscall"
"golang.org/x/sys/windows"
)
func hasElevatedPrivilege() (bool, error) { func hasElevatedPrivilege() (bool, error) {
var sid *windows.SID var sid *windows.SID
@@ -22,3 +27,55 @@ func hasElevatedPrivilege() (bool, error) {
token := windows.Token(0) token := windows.Token(0)
return token.IsMember(sid) return token.IsMember(sid)
} }
func openLogFile(path string, mode int) (*os.File, error) {
if len(path) == 0 {
return nil, &os.PathError{Path: path, Op: "open", Err: syscall.ERROR_FILE_NOT_FOUND}
}
pathP, err := syscall.UTF16PtrFromString(path)
if err != nil {
return nil, err
}
var access uint32
switch mode & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) {
case os.O_RDONLY:
access = windows.GENERIC_READ
case os.O_WRONLY:
access = windows.GENERIC_WRITE
case os.O_RDWR:
access = windows.GENERIC_READ | windows.GENERIC_WRITE
}
if mode&os.O_CREATE != 0 {
access |= windows.GENERIC_WRITE
}
if mode&os.O_APPEND != 0 {
access &^= windows.GENERIC_WRITE
access |= windows.FILE_APPEND_DATA
}
shareMode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_DELETE)
var sa *syscall.SecurityAttributes
var createMode uint32
switch {
case mode&(os.O_CREATE|os.O_EXCL) == (os.O_CREATE | os.O_EXCL):
createMode = windows.CREATE_NEW
case mode&(os.O_CREATE|os.O_TRUNC) == (os.O_CREATE | os.O_TRUNC):
createMode = windows.CREATE_ALWAYS
case mode&os.O_CREATE == os.O_CREATE:
createMode = windows.OPEN_ALWAYS
case mode&os.O_TRUNC == os.O_TRUNC:
createMode = windows.TRUNCATE_EXISTING
default:
createMode = windows.OPEN_EXISTING
}
handle, err := syscall.CreateFile(pathP, access, shareMode, sa, createMode, syscall.FILE_ATTRIBUTE_NORMAL, 0)
if err != nil {
return nil, &os.PathError{Path: path, Op: "open", Err: err}
}
return os.NewFile(uintptr(handle), path), nil
}