Download this file
| 1 | package rootparticipation |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "errors" |
| 6 | "os" |
| 7 | ) |
| 8 | |
| 9 | // MigrationCensus owns the same exclusion as Acquire. Completion never resets |
| 10 | // revisions or overwrites another transaction's pending marker. |
| 11 | func (l Ledger) MigrationCensus(ctx context.Context, want Census, verifyOnly bool) error { |
| 12 | unlock, err := l.State.Lock(ctx, "transaction.lock") |
| 13 | if err != nil { |
| 14 | return err |
| 15 | } |
| 16 | defer unlock() |
| 17 | raw, err := l.State.Read("census.json") |
| 18 | if err == nil { |
| 19 | var c Census |
| 20 | if Decode(raw, &c) != nil || c.Schema != 1 || c.Box != want.Box || c.Enrollment != want.Enrollment || c.Migration != want.Migration || c.NeverEnrolled || c.Revision == 0 || c.LaunchRevision == 0 { |
| 21 | return ErrUnavailable |
| 22 | } |
| 23 | if c.Complete && c.Pending == "" { |
| 24 | return nil |
| 25 | } |
| 26 | if verifyOnly || c.Pending != "migration" { |
| 27 | return ErrUnavailable |
| 28 | } |
| 29 | want.Revision = c.Revision |
| 30 | want.LaunchRevision = c.LaunchRevision |
| 31 | } else if !errors.Is(err, os.ErrNotExist) { |
| 32 | return err |
| 33 | } else if verifyOnly { |
| 34 | return ErrUnavailable |
| 35 | } |
| 36 | if err := l.writeCensus(want); err != nil { |
| 37 | if want.Complete { |
| 38 | want.Complete = false |
| 39 | want.Pending = "migration" |
| 40 | return errors.Join(err, l.writeCensus(want)) |
| 41 | } |
| 42 | return err |
| 43 | } |
| 44 | return nil |
| 45 | } |
| 46 | |