Sample env carries a version marker; install appends settings missing since the writing version
This commit is contained in:
@@ -140,7 +140,7 @@ func copyFile(src, dst string, mode os.FileMode) error {
|
||||
// *directory*, and granting the sandboxed service user write access to a
|
||||
// shared system directory would let a compromised service overwrite other
|
||||
// binaries. /var/lib/gpu-turnstile is exclusively ours.
|
||||
func Install(configPath string, copyBin bool) error {
|
||||
func Install(configPath string, copyBin bool, version string) error {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -172,14 +172,23 @@ func Install(configPath string, copyBin bool) error {
|
||||
}
|
||||
}
|
||||
exe = installedExe
|
||||
if _, err := os.Stat(etcConfig); os.IsNotExist(err) {
|
||||
data, readErr := os.ReadFile(etcConfig)
|
||||
switch {
|
||||
case os.IsNotExist(readErr):
|
||||
if configPath != "" {
|
||||
copyFile(configPath, etcConfig, 0o644) //nolint:errcheck // best effort
|
||||
} else {
|
||||
// No config at all: install a fully commented sample
|
||||
// covering every setting. LOG_FILE stays commented —
|
||||
// stderr goes to the journal on Linux.
|
||||
if err := os.WriteFile(etcConfig, []byte(config.SampleEnv("")), 0o644); err != nil {
|
||||
} else if err := os.WriteFile(etcConfig, []byte(config.SampleEnv(version, "")), 0o644); err != nil {
|
||||
// Fully commented sample covering every setting; LOG_FILE
|
||||
// stays commented — stderr goes to the journal on Linux.
|
||||
return fmt.Errorf("write %s: %w", etcConfig, err)
|
||||
}
|
||||
case readErr != nil:
|
||||
return fmt.Errorf("read %s: %w", etcConfig, readErr)
|
||||
default:
|
||||
// An installer-written config from an older version gets any
|
||||
// new settings appended; hand-written files stay untouched.
|
||||
if synced, changed := config.SyncSample(string(data), version, ""); changed {
|
||||
if err := os.WriteFile(etcConfig, []byte(synced), 0o644); err != nil {
|
||||
return fmt.Errorf("write %s: %w", etcConfig, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func Run(run func(ctx context.Context) error) error {
|
||||
}
|
||||
|
||||
// Install is unsupported on non-Windows, non-Linux platforms.
|
||||
func Install(string, bool) error { return errUnsupported }
|
||||
func Install(string, bool, string) error { return errUnsupported }
|
||||
|
||||
// Remove is unsupported on non-Windows, non-Linux platforms.
|
||||
func Remove() error { return errUnsupported }
|
||||
|
||||
@@ -116,7 +116,7 @@ func (h *handler) Execute(_ []string, requests <-chan svc.ChangeRequest, status
|
||||
// the installed binary is refreshed only when the content differs, the
|
||||
// registration is updated only where it drifted, and the service is
|
||||
// started again only if it was running before.
|
||||
func Install(configPath string, copyBin bool) error {
|
||||
func Install(configPath string, copyBin bool, version string) error {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -174,15 +174,26 @@ func Install(configPath string, copyBin bool) error {
|
||||
}
|
||||
// A service has no console: without LOG_FILE the output vanishes.
|
||||
// With no config at all, install a fully commented sample covering
|
||||
// every setting (only LOG_FILE active); an existing config just gets
|
||||
// a LOG_FILE line appended if it has none.
|
||||
// every setting (only LOG_FILE active). An existing installer-written
|
||||
// config from an older version gets any new settings appended; any
|
||||
// other existing config just gets a LOG_FILE line if it has none.
|
||||
logPath := filepath.Join(dataDir, "gpu-turnstile.log")
|
||||
if _, statErr := os.Stat(targetCfg); os.IsNotExist(statErr) {
|
||||
if err := os.WriteFile(targetCfg, []byte(config.SampleEnv(logPath)), 0o644); err != nil {
|
||||
data, readErr := os.ReadFile(targetCfg)
|
||||
switch {
|
||||
case os.IsNotExist(readErr):
|
||||
if err := os.WriteFile(targetCfg, []byte(config.SampleEnv(version, logPath)), 0o644); err != nil {
|
||||
return fmt.Errorf("write %s: %w", targetCfg, err)
|
||||
}
|
||||
} else if err := ensureLogFile(targetCfg, logPath); err != nil {
|
||||
return err
|
||||
case readErr != nil:
|
||||
return fmt.Errorf("read %s: %w", targetCfg, readErr)
|
||||
default:
|
||||
if synced, changed := config.SyncSample(string(data), version, logPath); changed {
|
||||
if err := os.WriteFile(targetCfg, []byte(synced), 0o644); err != nil {
|
||||
return fmt.Errorf("write %s: %w", targetCfg, err)
|
||||
}
|
||||
} else if err := ensureLogFile(targetCfg, logPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
configPath = targetCfg
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user