Skip to content

Commit

Permalink
Add migration to new profile IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
dhaavi committed Sep 14, 2023
1 parent 2d9e07a commit 070a322
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
3 changes: 2 additions & 1 deletion profile/fingerprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
71 changes: 71 additions & 0 deletions profile/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package profile

import (
"context"
"regexp"

"github.com/hashicorp/go-version"

Expand Down Expand Up @@ -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,
},
)
}

Expand Down Expand Up @@ -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
}

0 comments on commit 070a322

Please sign in to comment.