Add migration to new profile IDs

This commit is contained in:
Daniel
2023-09-14 11:30:05 +02:00
parent 2d9e07aa79
commit 070a3229f5
2 changed files with 73 additions and 1 deletions

View File

@@ -5,9 +5,10 @@ import (
"regexp"
"strings"
"golang.org/x/exp/slices"
"github.com/safing/jess/lhash"
"github.com/safing/portbase/container"
"golang.org/x/exp/slices"
)
// # Matching and Scores

View File

@@ -2,6 +2,7 @@ package profile
import (
"context"
"regexp"
"github.com/hashicorp/go-version"
@@ -30,6 +31,11 @@ func registerMigrations() error {
Version: "v1.5.0", // FIXME
MigrateFunc: migrateIcons,
},
migration.Migration{
Description: "Migrate from random profile IDs to fingerprint-derived IDs",
Version: "v1.5.1", // FIXME
MigrateFunc: migrateToDerivedIDs,
},
)
}
@@ -147,3 +153,68 @@ func migrateIcons(ctx context.Context, _, to *version.Version, db *database.Inte
return nil
}
var randomUUIDRegex = regexp.MustCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`)
func migrateToDerivedIDs(ctx context.Context, _, to *version.Version, db *database.Interface) error {
var profilesToDelete []string //nolint:prealloc // We don't know how many profiles there are.
// Get iterator over all profiles.
it, err := db.Query(query.New(profilesDBPath))
if err != nil {
log.Tracer(ctx).Errorf("profile: failed to migrate to derived profile IDs: failed to start query: %s", err)
return nil
}
// Migrate all profiles.
for r := range it.Next {
// Parse profile.
profile, err := EnsureProfile(r)
if err != nil {
log.Tracer(ctx).Debugf("profiles: failed to parse profile %s for migration: %s", r.Key(), err)
continue
}
// Skip if the ID does not look like a random UUID.
if !randomUUIDRegex.MatchString(profile.ID) {
continue
}
// Generate new ID.
newID := deriveProfileID(profile.Fingerprints)
// If they match, skip migration for this profile.
if profile.ID == newID {
continue
}
// Add old ID to profiles that we need to delete.
profilesToDelete = append(profilesToDelete, profile.ScopedID())
// Set new ID and rebuild the key.
profile.ID = newID
profile.makeKey()
// Save back to DB.
err = db.Put(profile)
if err != nil {
log.Tracer(ctx).Debugf("profiles: failed to save profile %s after migration: %s", r.Key(), err)
} else {
log.Tracer(ctx).Tracef("profiles: migrated profile %s to %s", r.Key(), to)
}
}
// Check if there was an error while iterating.
if err := it.Err(); err != nil {
log.Tracer(ctx).Errorf("profile: failed to migrate to derived profile IDs: failed to iterate over profiles for migration: %s", err)
}
// Delete old migrated profiles.
for _, scopedID := range profilesToDelete {
if err := db.Delete(profilesDBPath + scopedID); err != nil {
log.Tracer(ctx).Errorf("profile: failed to delete old profile %s during migration: %s", scopedID, err)
}
}
return nil
}