| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- // Copyright (c) Tailscale Inc & AUTHORS
- // SPDX-License-Identifier: BSD-3-Clause
- package paths
- import (
- "os"
- "path/filepath"
- "tailscale.com/types/logger"
- )
- // TryConfigFileMigration carefully copies the contents of oldFile to
- // newFile, returning the path which should be used to read the config.
- // - if newFile already exists, don't modify it just return its path
- // - if neither oldFile nor newFile exist, return newFile for a fresh
- // default config to be written to.
- // - if oldFile exists but copying to newFile fails, return oldFile so
- // there will at least be some config to work with.
- func TryConfigFileMigration(logf logger.Logf, oldFile, newFile string) string {
- _, err := os.Stat(newFile)
- if err == nil {
- // Common case for a system which has already been migrated.
- return newFile
- }
- if !os.IsNotExist(err) {
- logf("TryConfigFileMigration failed; new file: %v", err)
- return newFile
- }
- contents, err := os.ReadFile(oldFile)
- if err != nil {
- // Common case for a new user.
- return newFile
- }
- if err = MkStateDir(filepath.Dir(newFile)); err != nil {
- logf("TryConfigFileMigration failed; MkStateDir: %v", err)
- return oldFile
- }
- err = os.WriteFile(newFile, contents, 0600)
- if err != nil {
- removeErr := os.Remove(newFile)
- if removeErr != nil {
- logf("TryConfigFileMigration failed; write newFile no cleanup: %v, remove err: %v",
- err, removeErr)
- return oldFile
- }
- logf("TryConfigFileMigration failed; write newFile: %v", err)
- return oldFile
- }
- logf("TryConfigFileMigration: successfully migrated: from %v to %v",
- oldFile, newFile)
- return newFile
- }
|