Add the BlockCAS driver, and stop GenerateSnapshotName panicking - #258
Open
anisurrahman75 wants to merge 11 commits into
Open
anisurrahman75 wants to merge 11 commits into
anisurrahman75 wants to merge 11 commits into
Conversation
Picks up the local-backend repository path normalization (filepath.Join), which removes the redundant double slash in RESTIC_REPOSITORY for local (PVC/NFS) backends. Signed-off-by: Anisur Rahman <anisur@appscode.com>
A component stored in a content-addressed block store records the key of its manifest rather than a restic snapshot id: a disk is cut on a fixed grid, each block is kept once under the hash of its contents, and one manifest lists the block for every slot. That is what lets an incremental backup be restored on its own instead of by replaying a chain. Follows the existing per-driver stats pattern (WalG, Medusa, Solr, ClickHouseBackup, Neo4jAdmin). Signed-off-by: Anisur Rahman <anisur@appscode.com>
apis.Driver and the Addon task field each carry their own enum marker, and controller-gen emits both under allOf, so a value must satisfy both. Adding it in one place only left BlockCAS rejected. Signed-off-by: Anisur Rahman <anisur@appscode.com>
GenerateSnapshotName indexed the regex match without checking it, so any BackupSession whose name does not end in -<digits> panicked the caller. A hand-created session rarely does. Splitting is now a named helper that returns the whole name and an empty suffix when there is no match. Signed-off-by: Anisur Rahman <anisur@appscode.com>
Upstream fixed the GenerateSnapshotName panic independently while this branch was open. Kept that behaviour but expressed through SplitBackupSessionName, which kubestash/kubestash#388 needs to fix the same bug in three more callers. Signed-off-by: Anisur Rahman <anisur@appscode.com>
A scheduled backup captures one point in time and records a single ManifestKey. An archiver captures a series, so it records a checkpoint index key, a bounded recent window, the first and last checkpoint times that bound the restorable range, and counters. The index itself stays in the backend. It cannot be trimmed — a point-in-time restore may need any entry — so at a ten-minute interval the object would outgrow the API server long before retention expires. FailedCheckpoints and LastFailure matter more than they look: a resident loop keeps running through failures, so counters are the only signal it is sick. Signed-off-by: Anisur Rahman <anisur@appscode.com>
archiver.kubestash.com/v1alpha1 is addon-agnostic, so future addons add their
own archiver kinds beside KubeVirtArchiver instead of inventing a group each.
The spec follows KubeDB's archivers: virtualMachines, backupStorage,
encryptionSecret, retentionPolicy, fullBackup, manifestBackup, cbtBackup, pause
and deletionPolicy. Three things differ, and each is forced:
* opt-in is selector-only. We do not own the VirtualMachine CRD, so there is
no field on the VM to set the way KubeDB sets one on a database.
* fullBackup defaults to the BlockCAS driver, not VolumeSnapshotter. Fulls and
checkpoints share one block store, which is what makes a daily full a hash
comparison rather than a whole-disk upload.
* cbtBackup carries no scheduler. Its absence is what marks the resident half,
the same convention KubeDB uses for logBackup; a test asserts no such field
creeps in.
Status reports per matched VM whether changed-block tracking is Enabled, the
raw state and a reason. Enabling CBT needs a VM restart, so the controller will
validate and report rather than restart production VMs on a label change — the
per-VM list is where the user reads what to do about it.
Signed-off-by: Anisur Rahman <anisur@appscode.com>
It reconciles into BackupConfiguration, Job and Snapshot, so it belongs in the group that already owns backup configuration rather than in an archiver group of its own. KubeDB splits archivers by group because it has one kind per database engine; there is only ever one of these. Drops apis/archiver entirely: its doc.go, groupversion_info.go, install and fuzzer packages existed only to stand up the second group. Signed-off-by: Anisur Rahman <anisur@appscode.com>
A KubeVirt CBT archiver writes a checkpoint every ten minutes, and none of them gets a Snapshot object of its own: the resident loop keeps ONE Snapshot Running and records the checkpoints in an index in the backend. So the restorable points are far finer-grained than the Snapshot list a `pitr` targetTime can select from, and the addon has to do the resolving. pointInTime is that surface: the newest restorable point at or before the given time, resolved by the addon against its own history. Signed-off-by: Anisur Rahman <anisur@appscode.com>
A resident archiver's snapshot never completes by design: its component stays Running until archiving stops, so its metadata cannot have been uploaded yet. CalculatePhase read that as Failed, and because the upload is only attempted once every component has finished, nothing ever retried it — a healthy archiver writing checkpoints every two minutes read as permanently broken. Seen live: one transient DNS failure to S3 latched the snapshot to Failed while the loop went on to write 507 checkpoints. Signed-off-by: Anisur Rahman <anisur@appscode.com>
A cleaner only creates prune_errors_by_repo.json when it has an error to record, and the BlockCAS cleaner never writes one at all. Reading it unconditionally failed every BlockCAS retention job at the final update-retention-policy-status step, even though the prune itself had succeeded. Absence means no errors; a cleaner that died before it could report is caught by the job's own exit code. Signed-off-by: Anisur Rahman <anisur@appscode.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two changes — say the word and I will split them.
1. The BlockCAS driver and its stats
Adds a
BlockCASdriver alongside the existing per-addon drivers, with a matchingBlockCASStatsonComponent.Incremental backups of a KubeVirt VM disk cannot be represented by a restic snapshot id: a restic snapshot of an incremental export holds only the changed bytes with no offset information, so it is not restorable. The block-CAS model cuts a disk on a fixed grid, stores each block once under the hash of its contents, and writes one complete manifest per snapshot. An incremental merges its changed slots over its parent, so a restore reads exactly one manifest rather than replaying a chain.
BlockCASStatsrecords the manifest key, grid size, parent snapshot and checkpoint, and what the run moved (slots considered, blocks uploaded vs deduped, zero slots skipped, bytes uploaded).Note that
apis.Driverand the Addon task field each carry their own enum marker, and controller-gen emits both underallOf— a value must satisfy both, so both are updated.2. GenerateSnapshotName panics on names without a numeric suffix
FindStringSubmatchreturns nil when the name does not end in-<digits>, and a hand-created BackupSession rarely does. Splitting is now the named helperSplitBackupSessionName, which returns the whole name and an empty suffix instead. kubestash/kubestash#388 uses it to fix three more copies of the same bug, one of which sits on a delete path and wedged sessions permanently.Both changes are purely additive; the split helper is covered by a table test.
Consumed by kubestash/kubevirt#4.
Related
The CBT work spans three repositories and reviews best in this order:
BlockCASdriver,BlockCASStats, theKubeVirtArchiverCRD, andSplitBackupSessionNameKubeVirtArchiverreconciler, and the regex-panic fixesdocs/cbt/, including the design and an agent-facing testing runbookcbt-volume-backupcatalog task