fix: synchronize migration flag access and propagate zip close error

Make nodeMigrationFileCreated an atomic.Bool since it is written by
CreateBackup and read by GetInfo on concurrent HTTP handler goroutines,
and finalize the migration archive explicitly so a failed zip close
returns an error instead of reporting a corrupt backup as success.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Roland Bewick 2026-08-10 15:11:14 +07:00
parent 8b8fc45ee2
commit 9fc22bc76f
2 changed files with 12 additions and 3 deletions

View file

@ -15,6 +15,7 @@ import (
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/sirupsen/logrus"
@ -52,7 +53,7 @@ type api struct {
eventPublisher events.EventPublisher
// set after a migration file is created; the hub is halted at that point
// and the frontend should keep showing the migration success page
nodeMigrationFileCreated bool
nodeMigrationFileCreated atomic.Bool
}
func NewAPI(svc service.Service, gormDB *gorm.DB, config config.Config, keys keys.Keys, albySvc alby.AlbyService, albyOAuthSvc alby.AlbyOAuthService, eventPublisher events.EventPublisher) *api {
@ -1513,7 +1514,7 @@ func (api *api) GetInfo(ctx context.Context) (*InfoResponse, error) {
}
lnClient := api.svc.GetLNClient()
info.Running = lnClient != nil
info.NodeMigrationFileCreated = api.nodeMigrationFileCreated
info.NodeMigrationFileCreated = api.nodeMigrationFileCreated.Load()
info.BackendType = backendType
info.AlbyAuthUrl = api.albyOAuthSvc.GetAuthUrl()
info.OAuthRedirect = !api.cfg.GetEnv().IsDefaultClientId()

View file

@ -195,9 +195,17 @@ func (api *api) CreateBackup(unlockPassword string, w io.Writer) error {
}
}
// Finalize the archive before reporting success; the deferred close
// only covers early returns.
err = zw.Close()
if err != nil {
logger.Logger.WithError(err).Error("Failed to finalize migration archive")
return fmt.Errorf("failed to finalize migration archive: %w", err)
}
logger.Logger.Info("Successfully created backup to migrate Alby Hub to another device")
api.nodeMigrationFileCreated = true
api.nodeMigrationFileCreated.Store(true)
return nil
}