mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-13 15:29:12 +01:00
credential: keep a per-entry file deleted after the IAM load deleted
An entry the load read from its own file is already migrated. When that file is removed before the migration runs, the legacy copy must not recreate it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7bbefe6a78
commit
768f40299e
1 file changed
+40
-7
@@ -39,6 +39,17 @@ func (store *FilerEtcStore) LoadConfiguration(ctx context.Context) (*iam_pb.S3Ap
|
||||
}
|
||||
}
|
||||
|
||||
fromLegacy := map[any]bool{}
|
||||
for _, identity := range s3cfg.Identities {
|
||||
fromLegacy[identity] = true
|
||||
}
|
||||
for _, sa := range s3cfg.ServiceAccounts {
|
||||
fromLegacy[sa] = true
|
||||
}
|
||||
for _, g := range s3cfg.Groups {
|
||||
fromLegacy[g] = true
|
||||
}
|
||||
|
||||
// 2. Load from multi-file structure (high priority, overrides legacy details)
|
||||
if _, err := store.loadFromMultiFile(ctx, s3cfg); err != nil {
|
||||
return s3cfg, err
|
||||
@@ -58,7 +69,23 @@ func (store *FilerEtcStore) LoadConfiguration(ctx context.Context) (*iam_pb.S3Ap
|
||||
// This ensures that all identities (including legacy ones) are written to individual files
|
||||
// and the legacy file is renamed.
|
||||
if foundLegacy {
|
||||
if err := store.migrateToMultiFile(ctx, content); err != nil {
|
||||
loaded := map[string]bool{}
|
||||
for _, identity := range s3cfg.Identities {
|
||||
if !fromLegacy[identity] {
|
||||
loaded[IamIdentitiesDirectory+"/"+identity.Name] = true
|
||||
}
|
||||
}
|
||||
for _, sa := range s3cfg.ServiceAccounts {
|
||||
if !fromLegacy[sa] {
|
||||
loaded[IamServiceAccountsDirectory+"/"+sa.Id] = true
|
||||
}
|
||||
}
|
||||
for _, g := range s3cfg.Groups {
|
||||
if !fromLegacy[g] {
|
||||
loaded[IamGroupsDirectory+"/"+g.Name] = true
|
||||
}
|
||||
}
|
||||
if err := store.migrateToMultiFile(ctx, content, loaded); err != nil {
|
||||
glog.Errorf("Failed to migrate IAM configuration to multi-file layout: %v", err)
|
||||
return s3cfg, nil
|
||||
}
|
||||
@@ -141,7 +168,7 @@ func (store *FilerEtcStore) loadFromMultiFile(ctx context.Context, s3cfg *iam_pb
|
||||
return hasIdentities, nil
|
||||
}
|
||||
|
||||
func (store *FilerEtcStore) migrateToMultiFile(ctx context.Context, legacyContent []byte) error {
|
||||
func (store *FilerEtcStore) migrateToMultiFile(ctx context.Context, legacyContent []byte, loaded map[string]bool) error {
|
||||
current, found, err := store.readInsideFiler(ctx, filer.IamConfigDirectory, IamLegacyIdentityFile)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -157,10 +184,16 @@ func (store *FilerEtcStore) migrateToMultiFile(ctx context.Context, legacyConten
|
||||
|
||||
glog.Infof("Migrating IAM configuration to multi-file layout...")
|
||||
|
||||
// An existing per-entry file is newer than the legacy copy, and may have
|
||||
// been rewritten or removed after this load read it: never overwrite it.
|
||||
// A per-entry file is newer than the legacy copy, and may have been
|
||||
// rewritten or removed after this load read it: never write it back.
|
||||
createIfAbsent := func(subDir, name string, v any) error {
|
||||
if loaded[subDir+"/"+name] {
|
||||
return nil
|
||||
}
|
||||
return store.createIfAbsent(ctx, subDir, name, v)
|
||||
}
|
||||
for _, identity := range legacy.Identities {
|
||||
if err := store.createIfAbsent(ctx, IamIdentitiesDirectory, identity.Name, identity); err != nil {
|
||||
if err := createIfAbsent(IamIdentitiesDirectory, identity.Name, identity); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -168,7 +201,7 @@ func (store *FilerEtcStore) migrateToMultiFile(ctx context.Context, legacyConten
|
||||
if err := validateServiceAccountId(sa.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := store.createIfAbsent(ctx, IamServiceAccountsDirectory, sa.Id, sa); err != nil {
|
||||
if err := createIfAbsent(IamServiceAccountsDirectory, sa.Id, sa); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -177,7 +210,7 @@ func (store *FilerEtcStore) migrateToMultiFile(ctx context.Context, legacyConten
|
||||
if g.Name == "" {
|
||||
return fmt.Errorf("group name is required")
|
||||
}
|
||||
if err := store.createIfAbsent(ctx, IamGroupsDirectory, g.Name, g); err != nil {
|
||||
if err := createIfAbsent(IamGroupsDirectory, g.Name, g); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user