From fcd867706a23c536538eb5d384715e13c7acf50e Mon Sep 17 00:00:00 2001 From: Maor Date: Sun, 30 Dec 2018 09:19:59 +0200 Subject: [PATCH] [cain/restore] add user-group to specify files ownership --- README.md | 1 + cmd/cain.go | 3 +++ pkg/cain/cain.go | 6 ++++++ pkg/utils/path.go | 16 ++++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/README.md b/README.md index 9f2e212..19b3ee3 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ Flags: -l, --selector string selector to filter on --src string source to restore from. Example: s3://bucket/cassandra/namespace/cluster-name -t, --tag string tag to restore + --user-group string user and group who should own restored files (default "cassandra:cassandra") ``` #### Examples diff --git a/cmd/cain.go b/cmd/cain.go index b8026ef..9fd3815 100644 --- a/cmd/cain.go +++ b/cmd/cain.go @@ -108,6 +108,7 @@ type restoreCmd struct { container string parallel int bufferSize float64 + userGroup string out io.Writer } @@ -146,6 +147,7 @@ func NewRestoreCmd(out io.Writer) *cobra.Command { Container: r.container, Parallel: r.parallel, BufferSize: r.bufferSize, + UserGroup: r.userGroup, } if err := cain.Restore(options); err != nil { log.Fatal(err) @@ -163,6 +165,7 @@ func NewRestoreCmd(out io.Writer) *cobra.Command { f.StringVarP(&r.container, "container", "c", "cassandra", "container name to act on") f.IntVarP(&r.parallel, "parallel", "p", 1, "number of files to copy in parallel. set this flag to 0 for full parallelism") f.Float64VarP(&r.bufferSize, "buffer-size", "b", 6.75, "in memory buffer size (MB) to use for files copy (buffer per file)") + f.StringVar(&r.userGroup, "user-group", "cassandra:cassandra", "user and group who should own restored files") return cmd } diff --git a/pkg/cain/cain.go b/pkg/cain/cain.go index 238e143..a9f321c 100644 --- a/pkg/cain/cain.go +++ b/pkg/cain/cain.go @@ -79,6 +79,7 @@ type RestoreOptions struct { Container string Parallel int BufferSize float64 + UserGroup string } // Restore performs restore @@ -144,6 +145,11 @@ func Restore(o RestoreOptions) error { return err } + log.Println("Changing files ownership") + if err := utils.ChangeFilesOwnership(k8sClient, existingPods, o.Namespace, o.Container, o.UserGroup); err != nil { + return err + } + log.Println("Refreshing tables") RefreshTables(k8sClient, o.Namespace, o.Container, o.Keyspace, podsToBeRestored, tablesToRefresh) diff --git a/pkg/utils/path.go b/pkg/utils/path.go index 142da7e..243c67c 100644 --- a/pkg/utils/path.go +++ b/pkg/utils/path.go @@ -144,3 +144,19 @@ func PathFromSrcToK8s(k8sClient interface{}, fromPath, cassandraDataDir, srcBase return toPath, nil } + +// ChangeFilesOwnership changes the ownership of files after restoring them +func ChangeFilesOwnership(iK8sClient interface{}, pods []string, namespace, container, userGroup string) error { + k8sClient := iK8sClient.(*skbn.K8sClient) + command := []string{"chown", "-R", userGroup, cassandraDataDir} + for _, pod := range pods { + stderr, err := skbn.Exec(*k8sClient, namespace, pod, container, command, nil, nil) + if len(stderr) != 0 { + return fmt.Errorf("STDERR: " + (string)(stderr)) + } + if err != nil { + return err + } + } + return nil +}