mirror of
https://github.com/kopia/kopia.git
synced 2026-01-29 00:33:24 -05:00
Implemented snapshot delete command. Behaves similarly to manifest rm, but with extra verification steps. - Checks that the referenced manifest is of type "snapshot" - Checks that the ID points to a snapshot, checks that the host name, user name, and path provided by flag or defaults match the source of the snapshot ID. Command will fail if they do not match, except if given --unsafe-ignore-source, which will bypass the associated safety requirement and delete anyway. Added end to end tests for input combinations, restore in conjunction with delete, and trying to snapshot delete a manifest by ID of a non-snapshot manifest.
51 lines
1.7 KiB
Go
51 lines
1.7 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/kopia/kopia/repo"
|
|
"github.com/kopia/kopia/repo/manifest"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
var (
|
|
snapshotDeleteCommand = snapshotCommands.Command("delete", "Explicitly delete a snapshot by providing a snapshot ID.")
|
|
snapshotDeleteID = snapshotDeleteCommand.Arg("id", "Snapshot ID to be deleted").Required().String()
|
|
snapshotDeletePath = snapshotDeleteCommand.Flag("path", "Specify the path of the snapshot to be deleted").String()
|
|
snapshotDeleteIgnoreSource = snapshotDeleteCommand.Flag("unsafe-ignore-source", "Override the requirement to specify source info for the delete to succeed").Bool()
|
|
)
|
|
|
|
func runDeleteCommand(ctx context.Context, rep *repo.Repository) error {
|
|
if !*snapshotDeleteIgnoreSource && *snapshotDeletePath == "" {
|
|
return errors.New("path is required")
|
|
}
|
|
|
|
manifestID := manifest.ID(*snapshotDeleteID)
|
|
manifestMeta, err := rep.Manifests.GetMetadata(ctx, manifestID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
labels := manifestMeta.Labels
|
|
if labels["type"] != "snapshot" {
|
|
return errors.Errorf("snapshot ID provided (%v) did not reference a snapshot", manifestID)
|
|
}
|
|
if !*snapshotDeleteIgnoreSource {
|
|
if labels["hostname"] != getHostName() {
|
|
return errors.New("host name does not match for deleting requested snapshot ID")
|
|
}
|
|
if labels["username"] != getUserName() {
|
|
return errors.New("user name does not match for deleting requested snapshot ID")
|
|
}
|
|
if labels["path"] != *snapshotDeletePath {
|
|
return errors.New("path does not match for deleting requested snapshot ID")
|
|
}
|
|
}
|
|
|
|
return rep.Manifests.Delete(ctx, manifestID)
|
|
}
|
|
|
|
func init() {
|
|
addUserAndHostFlags(snapshotDeleteCommand)
|
|
snapshotDeleteCommand.Action(repositoryAction(runDeleteCommand))
|
|
}
|