mirror of
https://github.com/kopia/kopia.git
synced 2026-03-06 23:38:24 -05:00
fixups from PR comments
This commit is contained in:
@@ -157,6 +157,7 @@ func (c *commandRepositorySetParameters) run(ctx context.Context, rep repo.Direc
|
||||
|
||||
c.setSizeMBParameter(ctx, c.maxPackSizeMB, "maximum pack size", &mp.MaxPackSize, &anyChange)
|
||||
|
||||
// prevent downgrade of index format
|
||||
if c.indexFormatVersion > mp.IndexVersion {
|
||||
c.setIntParameter(ctx, c.indexFormatVersion, "index format version", &mp.IndexVersion, &anyChange)
|
||||
} else if c.indexFormatVersion != mp.IndexVersion {
|
||||
|
||||
@@ -182,6 +182,71 @@ func (s *formatSpecificTestSuite) TestRepositorySetParametersUpgrade(t *testing.
|
||||
env.RunAndExpectSuccess(t, "index", "epoch", "list")
|
||||
}
|
||||
|
||||
func (s *formatSpecificTestSuite) TestRepositorySetParametersDowngrade(t *testing.T) {
|
||||
env := s.setupInMemoryRepo(t)
|
||||
out := env.RunAndExpectSuccess(t, "repository", "status")
|
||||
|
||||
// default values
|
||||
require.Contains(t, out, "Max pack length: 21 MB")
|
||||
|
||||
switch s.formatVersion {
|
||||
case format.FormatVersion1:
|
||||
require.Contains(t, out, "Format version: 1")
|
||||
require.Contains(t, out, "Epoch Manager: disabled")
|
||||
env.RunAndExpectFailure(t, "index", "epoch", "list")
|
||||
case format.FormatVersion2:
|
||||
require.Contains(t, out, "Format version: 2")
|
||||
require.Contains(t, out, "Epoch Manager: enabled")
|
||||
env.RunAndExpectSuccess(t, "index", "epoch", "list")
|
||||
default:
|
||||
require.Contains(t, out, "Format version: 3")
|
||||
require.Contains(t, out, "Epoch Manager: enabled")
|
||||
env.RunAndExpectSuccess(t, "index", "epoch", "list")
|
||||
}
|
||||
|
||||
env.Environment["KOPIA_UPGRADE_LOCK_ENABLED"] = "1"
|
||||
|
||||
{
|
||||
cmd := []string{
|
||||
"repository", "upgrade",
|
||||
"--upgrade-owner-id", "owner",
|
||||
"--io-drain-timeout", "1s", "--allow-unsafe-upgrade",
|
||||
"--status-poll-interval", "1s",
|
||||
"--max-permitted-clock-drift", "1s",
|
||||
}
|
||||
|
||||
// You can only upgrade when you are not already upgraded
|
||||
if s.formatVersion < format.MaxFormatVersion {
|
||||
env.RunAndExpectSuccess(t, cmd...)
|
||||
} else {
|
||||
env.RunAndExpectFailure(t, cmd...)
|
||||
}
|
||||
}
|
||||
|
||||
env.RunAndExpectSuccess(t, "repository", "set-parameters", "--upgrade")
|
||||
env.RunAndExpectSuccess(t, "repository", "set-parameters", "--epoch-min-duration", "3h")
|
||||
env.RunAndExpectSuccess(t, "repository", "set-parameters", "--epoch-cleanup-safety-margin", "23h")
|
||||
env.RunAndExpectSuccess(t, "repository", "set-parameters", "--epoch-advance-on-size-mb", "77")
|
||||
env.RunAndExpectSuccess(t, "repository", "set-parameters", "--epoch-advance-on-count", "22")
|
||||
env.RunAndExpectSuccess(t, "repository", "set-parameters", "--epoch-checkpoint-frequency", "9")
|
||||
|
||||
env.RunAndExpectFailure(t, "repository", "set-parameters", "--epoch-min-duration", "1s")
|
||||
env.RunAndExpectFailure(t, "repository", "set-parameters", "--epoch-refresh-frequency", "10h")
|
||||
env.RunAndExpectFailure(t, "repository", "set-parameters", "--epoch-checkpoint-frequency", "-10")
|
||||
env.RunAndExpectFailure(t, "repository", "set-parameters", "--epoch-cleanup-safety-margin", "10s")
|
||||
env.RunAndExpectFailure(t, "repository", "set-parameters", "--epoch-advance-on-count", "1")
|
||||
|
||||
out = env.RunAndExpectSuccess(t, "repository", "status")
|
||||
require.Contains(t, out, "Epoch Manager: enabled")
|
||||
require.Contains(t, out, "Index Format: v2")
|
||||
require.Contains(t, out, "Format version: 3")
|
||||
require.Contains(t, out, "Epoch cleanup margin: 23h0m0s")
|
||||
require.Contains(t, out, "Epoch advance on: 22 blobs or 80.7 MB, minimum 3h0m0s")
|
||||
require.Contains(t, out, "Epoch checkpoint every: 9 epochs")
|
||||
|
||||
env.RunAndExpectSuccess(t, "index", "epoch", "list")
|
||||
}
|
||||
|
||||
func (s *formatSpecificTestSuite) TestRepositorySetParametersRequiredFeatures(t *testing.T) {
|
||||
env := s.setupInMemoryRepo(t)
|
||||
|
||||
|
||||
@@ -116,9 +116,8 @@ func loadIndexBlobs(ctx context.Context, indexEntries map[content.ID][2]index.In
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateAction returns an array of strings (report) that describes differences between
|
||||
// the V0 index blob and V1 index blob content. This is used to check that the upgraded index
|
||||
// (V1 index) reflects the content of the old V0 index.
|
||||
// validateAction returns an error of the new V1 index blob content does not match the source V0 index blob content.
|
||||
// This is used to check that the upgraded index (V1 index) reflects the content of the old V0 index.
|
||||
func (c *commandRepositoryUpgrade) validateAction(ctx context.Context, rep repo.DirectRepositoryWriter) error {
|
||||
|
||||
indexEntries := map[content.ID][2]index.Info{}
|
||||
@@ -171,28 +170,22 @@ func (c *commandRepositoryUpgrade) validateAction(ctx context.Context, rep repo.
|
||||
// checkIndexInfo compare two index infos. If a mismatch exists, return an error with diagnostic information.
|
||||
func checkIndexInfo(i0, i1 index.Info) error {
|
||||
var err error
|
||||
if i0.GetFormatVersion() != i1.GetFormatVersion() {
|
||||
switch {
|
||||
case i0.GetFormatVersion() != i1.GetFormatVersion():
|
||||
err = errors.Errorf("mismatched FormatVersions: %v %v", i0.GetFormatVersion(), i1.GetFormatVersion())
|
||||
}
|
||||
if i0.GetOriginalLength() != i1.GetOriginalLength() {
|
||||
case i0.GetOriginalLength() != i1.GetOriginalLength():
|
||||
err = errors.Errorf("mismatched OriginalLengths: %v %v", i0.GetOriginalLength(), i1.GetOriginalLength())
|
||||
}
|
||||
if i0.GetPackBlobID() != i1.GetPackBlobID() {
|
||||
case i0.GetPackBlobID() != i1.GetPackBlobID():
|
||||
err = errors.Errorf("mismatched PackBlobIDs: %v %v", i0.GetPackBlobID(), i1.GetPackBlobID())
|
||||
}
|
||||
if i0.GetPackedLength() != i1.GetPackedLength() {
|
||||
case i0.GetPackedLength() != i1.GetPackedLength():
|
||||
err = errors.Errorf("mismatched PackedLengths: %v %v", i0.GetPackedLength(), i1.GetPackedLength())
|
||||
}
|
||||
if i0.GetPackOffset() != i1.GetPackOffset() {
|
||||
case i0.GetPackOffset() != i1.GetPackOffset():
|
||||
err = errors.Errorf("mismatched PackOffsets: %v %v", i0.GetPackOffset(), i1.GetPackOffset())
|
||||
}
|
||||
if i0.GetEncryptionKeyID() != i1.GetEncryptionKeyID() {
|
||||
case i0.GetEncryptionKeyID() != i1.GetEncryptionKeyID():
|
||||
err = errors.Errorf("mismatched EncryptionKeyIDs: %v %v", i0.GetEncryptionKeyID(), i1.GetEncryptionKeyID())
|
||||
}
|
||||
if i0.GetDeleted() != i1.GetDeleted() {
|
||||
case i0.GetDeleted() != i1.GetDeleted():
|
||||
err = errors.Errorf("mismatched Deleted flags: %v %v", i0.GetDeleted(), i1.GetDeleted())
|
||||
}
|
||||
if i0.GetTimestampSeconds() != i1.GetTimestampSeconds() {
|
||||
case i0.GetTimestampSeconds() != i1.GetTimestampSeconds():
|
||||
err = errors.Errorf("mismatched TimestampSeconds: %v %v", i0.GetTimestampSeconds(), i1.GetTimestampSeconds())
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
"github.com/kopia/kopia/repo/blob"
|
||||
)
|
||||
|
||||
// BackupBlobIDPrefix is the prefix for all identifiers of the BLOBs that
|
||||
// keep a backup copy of the FormatBlobID BLOB for the purposes of rollback
|
||||
// during upgrade.
|
||||
const (
|
||||
// BackupBlobIDPrefix is the prefix for all identifiers of the BLOBs that
|
||||
// keep a backup copy of the FormatBlobID BLOB for the purposes of rollback
|
||||
// during upgrade.
|
||||
BackupBlobIDPrefix = "kopia.repository.backup."
|
||||
|
||||
// LegacyIndexPoisonBlobID used to pollute V0 indexes after upgrade to prevent legacy clients from corrupting V1 indexes
|
||||
LegacyIndexPoisonBlobID = "n00000000000000000000000000000000-repository_unreadable_by_this_kopia_version_upgrade_required"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user