Skip to content

Commit

Permalink
[K10-1255] Restic deleteData by ID (#5296)
Browse files Browse the repository at this point in the history
* Add snapshotsByTag command

* Add parsing snapID from snapshots

* Add parsing snapID test

* Address review comments

* Address review comments

* Combine result length checks

* Export getSnapshotIDFromTag

* Add BackupDelete integration_test

* Renaming func and variables

* Fix imports
  • Loading branch information
DeepikaDixit authored and Ilya Kislenko committed Mar 29, 2019
1 parent 2fbc631 commit e220ac8
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 15 deletions.
54 changes: 39 additions & 15 deletions pkg/function/delete_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package function

import (
"context"
"encoding/json"

"github.com/pkg/errors"

Expand Down Expand Up @@ -84,27 +85,36 @@ func (*deleteDataFunc) Exec(ctx context.Context, tp param.TemplateParams, args m
if (deleteIdentifier != "") == (deleteTag != "") {
return nil, errors.Errorf("Require one argument: %s or %s", DeleteDataBackupIdentifierArg, DeleteDataBackupTagArg)
}
var cmd []string
if deleteIdentifier != "" {
cmd = restic.ForgetCommandByID(tp.Profile, deleteArtifactPrefix, deleteIdentifier, encryptionKey)
}
if deleteTag != "" {
cmd = restic.ForgetCommandByTag(tp.Profile, deleteArtifactPrefix, deleteTag, encryptionKey)
cmd := restic.SnapshotsCommandByTag(tp.Profile, deleteArtifactPrefix, deleteTag, encryptionKey)
stdout, stderr, err := kube.Exec(cli, namespace, pod.Name, pod.Spec.Containers[0].Name, cmd)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stdout)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stderr)
if err != nil {
return nil, errors.Wrapf(err, "Failed to forget data, could not get snapshotID from tag, Tag: %s", deleteTag)
}
deleteIdentifier, err = GetSnapshotIDFromLog(stdout)
if err != nil {
return nil, errors.Wrapf(err, "Failed to forget data, could not get snapshotID from tag, Tag: %s", deleteTag)
}
}
stdout, stderr, err := kube.Exec(cli, namespace, pod.Name, pod.Spec.Containers[0].Name, cmd)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stdout)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stderr)
if err != nil {
return nil, errors.Wrapf(err, "Failed to forget data")
if deleteIdentifier != "" {
cmd := restic.ForgetCommandByID(tp.Profile, deleteArtifactPrefix, deleteIdentifier, encryptionKey)
stdout, stderr, err := kube.Exec(cli, namespace, pod.Name, pod.Spec.Containers[0].Name, cmd)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stdout)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stderr)
if err != nil {
return nil, errors.Wrapf(err, "Failed to forget data")
}
}

if reclaimSpace {
cmdP := restic.PruneCommand(tp.Profile, deleteArtifactPrefix, encryptionKey)
stdoutP, stderrP, errP := kube.Exec(cli, namespace, pod.Name, pod.Spec.Containers[0].Name, cmdP)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stdoutP)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stderrP)
cmd := restic.PruneCommand(tp.Profile, deleteArtifactPrefix, encryptionKey)
stdout, stderr, err := kube.Exec(cli, namespace, pod.Name, pod.Spec.Containers[0].Name, cmd)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stdout)
format.Log(pod.Name, pod.Spec.Containers[0].Name, stderr)
if err != nil {
return nil, errors.Wrapf(errP, "Failed to prune data after forget")
return nil, errors.Wrapf(err, "Failed to prune data after forget")
}
}
return nil, nil
Expand All @@ -113,3 +123,17 @@ func (*deleteDataFunc) Exec(ctx context.Context, tp param.TemplateParams, args m
func (*deleteDataFunc) RequiredArgs() []string {
return []string{DeleteDataNamespaceArg, DeleteDataBackupArtifactPrefixArg}
}

// GetSnapshotIDFromLog gets the SnapshotID from log
func GetSnapshotIDFromLog(output string) (string, error) {
var result []map[string]interface{}
err := json.Unmarshal([]byte(output), &result)
if err != nil {
return "", errors.WithMessage(err, "Failed to unmarshall output from snapshotCommand")
}
if len(result) != 1 {
return "", errors.New("Snapshot not found")
}
snapId := result[0]["short_id"]
return snapId.(string), nil
}
27 changes: 27 additions & 0 deletions pkg/function/delete_data_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package function

import (
. "gopkg.in/check.v1"
)

type DeleteDataSuite struct {
}

var _ = Suite(&DeleteDataSuite{})

func (s *DeleteDataSuite) TestGetSnapshotIDFromTag(c *C) {
for _, tc := range []struct {
log string
expected string
checker Checker
}{
{log: `[{"time":"2019-03-28T17:35:15.146526-07:00","hostname":"MacBook-Pro.local","username":"abc","uid":501,"gid":20,"tags":["backup123"],"id":"7c0bfeb93dd5b390a6eaf8a386ec8cb86e4631f2d96400407b529b53d979536a","short_id":"7c0bfeb9"}]`, expected: "7c0bfeb9", checker: IsNil},
{log: `[{"time":"2019-03-28T17:35:15.146526-07:00","hostname":"MacBook-Pro.local","username":"abc","uid":501,"gid":20,"tags":["backup123"],"id":"7c0bfeb93dd5b390a6eaf8a386ec8cb86e4631f2d96400407b529b53d979536a","short_id":"7c0bfeb9"},{"time":"2019-03-28T17:35:15.146526-07:00","hostname":"MacBook-Pro.local","username":"abc","uid":501,"gid":20,"tags":["backup123"],"id":"7c0bfeb93dd5b390a6eaf8a386ec8cb86e4631f2d96400407b529b53d979536a","short_id":"7c0bfeb9"}]`, expected: "", checker: NotNil},
{log: `null`, expected: "", checker: NotNil},
} {
id, err := GetSnapshotIDFromLog(tc.log)
c.Assert(err, tc.checker)
c.Assert(id, Equals, tc.expected)

}
}
8 changes: 8 additions & 0 deletions pkg/restic/restic.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ func SnapshotsCommand(profile *param.Profile, repository, encryptionKey string)
return shCommand(command)
}

// SnapshotsCommandByTag returns restic snapshots command
func SnapshotsCommandByTag(profile *param.Profile, repository, tag, encryptionKey string) []string {
cmd := resticArgs(profile, repository, encryptionKey)
cmd = append(cmd, "snapshots", "--tag", tag, "--json")
command := strings.Join(cmd, " ")
return shCommand(command)
}

// InitCommand returns restic init command
func InitCommand(profile *param.Profile, repository, encryptionKey string) []string {
cmd := resticArgs(profile, repository, encryptionKey)
Expand Down

0 comments on commit e220ac8

Please sign in to comment.