Compare commits

...

2 Commits

Author SHA1 Message Date
Andrew Dunham d7557110c5 WIP: more logging during profile migration
Change-Id: I3a3ca8f25bfefca139115b25ec4161c069da7e4a
2023-06-01 18:41:03 -04:00
Will Norris ab797f0abd VERSION.txt: this is v1.42.0
Signed-off-by: Will Norris <will@tailscale.com>
2023-05-24 08:59:04 -07:00
3 changed files with 20 additions and 1 deletions

View File

@ -1 +1 @@
1.41.0 1.42.0

View File

@ -24,6 +24,9 @@ import (
var errAlreadyMigrated = errors.New("profile migration already completed") var errAlreadyMigrated = errors.New("profile migration already completed")
// var debug = envknob.RegisterBool("TS_DEBUG_PROFILES")
var debug = func() bool { return true }
// profileManager is a wrapper around a StateStore that manages // profileManager is a wrapper around a StateStore that manages
// multiple profiles and the current profile. // multiple profiles and the current profile.
type profileManager struct { type profileManager struct {
@ -42,6 +45,13 @@ type profileManager struct {
isNewProfile bool isNewProfile bool
} }
func (pm *profileManager) dlogf(format string, args ...any) {
if !debug() {
return
}
pm.logf(format, args...)
}
// CurrentUserID returns the current user ID. It is only non-empty on // CurrentUserID returns the current user ID. It is only non-empty on
// Windows where we have a multi-user system. // Windows where we have a multi-user system.
func (pm *profileManager) CurrentUserID() ipn.WindowsUserID { func (pm *profileManager) CurrentUserID() ipn.WindowsUserID {
@ -66,8 +76,10 @@ func (pm *profileManager) SetCurrentUserID(uid ipn.WindowsUserID) error {
// Read the CurrentProfileKey from the store which stores // Read the CurrentProfileKey from the store which stores
// the selected profile for the current user. // the selected profile for the current user.
b, err := pm.store.ReadState(ipn.CurrentProfileKey(string(uid))) b, err := pm.store.ReadState(ipn.CurrentProfileKey(string(uid)))
pm.dlogf("profileManager.store.ReadState(%q) = %v, %v", string(uid), len(b), err)
if err == ipn.ErrStateNotExist || len(b) == 0 { if err == ipn.ErrStateNotExist || len(b) == 0 {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
pm.dlogf("windows: migrating from legacy preferences")
if err := pm.migrateFromLegacyPrefs(); err != nil && !errors.Is(err, errAlreadyMigrated) { if err := pm.migrateFromLegacyPrefs(); err != nil && !errors.Is(err, errAlreadyMigrated) {
return err return err
} }
@ -555,6 +567,7 @@ func newProfileManagerWithGOOS(store ipn.StateStore, logf logger.Logf, goos stri
// and runtime must be valid Windows security identifier structures. // and runtime must be valid Windows security identifier structures.
} else if len(knownProfiles) == 0 && goos != "windows" && runtime.GOOS != "windows" { } else if len(knownProfiles) == 0 && goos != "windows" && runtime.GOOS != "windows" {
// No known profiles, try a migration. // No known profiles, try a migration.
pm.dlogf("no known profiles; trying to migrate from legacy prefs")
if err := pm.migrateFromLegacyPrefs(); err != nil { if err := pm.migrateFromLegacyPrefs(); err != nil {
return nil, err return nil, err
} }
@ -573,11 +586,13 @@ func (pm *profileManager) migrateFromLegacyPrefs() error {
metricMigrationError.Add(1) metricMigrationError.Add(1)
return fmt.Errorf("load legacy prefs: %w", err) return fmt.Errorf("load legacy prefs: %w", err)
} }
pm.dlogf("loaded legacy preferences; sentinel=%q", sentinel)
if err := pm.SetPrefs(prefs); err != nil { if err := pm.SetPrefs(prefs); err != nil {
metricMigrationError.Add(1) metricMigrationError.Add(1)
return fmt.Errorf("migrating _daemon profile: %w", err) return fmt.Errorf("migrating _daemon profile: %w", err)
} }
pm.completeMigration(sentinel) pm.completeMigration(sentinel)
pm.dlogf("completed legacy preferences migration with sentinel=%q", sentinel)
metricMigrationSuccess.Add(1) metricMigrationSuccess.Add(1)
return nil return nil
} }

View File

@ -40,6 +40,7 @@ func legacyPrefsDir(uid ipn.WindowsUserID) (string, error) {
func (pm *profileManager) loadLegacyPrefs() (string, ipn.PrefsView, error) { func (pm *profileManager) loadLegacyPrefs() (string, ipn.PrefsView, error) {
userLegacyPrefsDir, err := legacyPrefsDir(pm.currentUserID) userLegacyPrefsDir, err := legacyPrefsDir(pm.currentUserID)
if err != nil { if err != nil {
pm.dlogf("no legacy preferences directory for %q: %v", pm.currentUserID, err)
return "", ipn.PrefsView{}, err return "", ipn.PrefsView{}, err
} }
@ -47,14 +48,17 @@ func (pm *profileManager) loadLegacyPrefs() (string, ipn.PrefsView, error) {
// verify that migration sentinel is not present // verify that migration sentinel is not present
_, err = os.Stat(migrationSentinel) _, err = os.Stat(migrationSentinel)
if err == nil { if err == nil {
pm.dlogf("migration sentinel %q already exists", migrationSentinel)
return "", ipn.PrefsView{}, errAlreadyMigrated return "", ipn.PrefsView{}, errAlreadyMigrated
} }
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
pm.dlogf("os.Stat(%q) = %v", migrationSentinel, err)
return "", ipn.PrefsView{}, err return "", ipn.PrefsView{}, err
} }
prefsPath := filepath.Join(userLegacyPrefsDir, legacyPrefsFile+legacyPrefsExt) prefsPath := filepath.Join(userLegacyPrefsDir, legacyPrefsFile+legacyPrefsExt)
prefs, err := ipn.LoadPrefs(prefsPath) prefs, err := ipn.LoadPrefs(prefsPath)
pm.dlogf("ipn.LoadPrefs(%q) = %v, %v", prefsPath, prefs, err)
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
return "", ipn.PrefsView{}, errAlreadyMigrated return "", ipn.PrefsView{}, errAlreadyMigrated
} }