mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-08-15 19:56:06 +00:00
move runCommand to pkg/util/exec and use in restic repo mgr
Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
@@ -17,12 +17,9 @@ limitations under the License.
|
||||
package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
@@ -40,6 +37,7 @@ import (
|
||||
informers "github.com/heptio/ark/pkg/generated/informers/externalversions/ark/v1"
|
||||
listers "github.com/heptio/ark/pkg/generated/listers/ark/v1"
|
||||
"github.com/heptio/ark/pkg/restic"
|
||||
arkexec "github.com/heptio/ark/pkg/util/exec"
|
||||
"github.com/heptio/ark/pkg/util/kube"
|
||||
)
|
||||
|
||||
@@ -184,7 +182,7 @@ func (c *podVolumeBackupController) processBackup(req *arkv1api.PodVolumeBackup)
|
||||
|
||||
var stdout, stderr string
|
||||
|
||||
if stdout, stderr, err = runCommand(resticCmd.Cmd()); err != nil {
|
||||
if stdout, stderr, err = arkexec.RunCommand(resticCmd.Cmd()); err != nil {
|
||||
log.WithError(errors.WithStack(err)).Errorf("Error running command=%s, stdout=%s, stderr=%s", resticCmd.String(), stdout, stderr)
|
||||
return c.fail(req, fmt.Sprintf("error running restic backup, stderr=%s: %s", stderr, err.Error()), log)
|
||||
}
|
||||
@@ -210,35 +208,6 @@ func (c *podVolumeBackupController) processBackup(req *arkv1api.PodVolumeBackup)
|
||||
return nil
|
||||
}
|
||||
|
||||
// runCommand runs a command and returns its stdout, stderr, and its returned
|
||||
// error (if any). If there are errors reading stdout or stderr, their return
|
||||
// value(s) will contain the error as a string.
|
||||
func runCommand(cmd *exec.Cmd) (string, string, error) {
|
||||
stdoutBuf := new(bytes.Buffer)
|
||||
stderrBuf := new(bytes.Buffer)
|
||||
|
||||
cmd.Stdout = stdoutBuf
|
||||
cmd.Stderr = stderrBuf
|
||||
|
||||
runErr := cmd.Run()
|
||||
|
||||
var stdout, stderr string
|
||||
|
||||
if res, readErr := ioutil.ReadAll(stdoutBuf); readErr != nil {
|
||||
stdout = errors.Wrap(readErr, "error reading command's stdout").Error()
|
||||
} else {
|
||||
stdout = string(res)
|
||||
}
|
||||
|
||||
if res, readErr := ioutil.ReadAll(stderrBuf); readErr != nil {
|
||||
stderr = errors.Wrap(readErr, "error reading command's stderr").Error()
|
||||
} else {
|
||||
stderr = string(res)
|
||||
}
|
||||
|
||||
return stdout, stderr, runErr
|
||||
}
|
||||
|
||||
func (c *podVolumeBackupController) patchPodVolumeBackup(req *arkv1api.PodVolumeBackup, mutate func(*arkv1api.PodVolumeBackup)) (*arkv1api.PodVolumeBackup, error) {
|
||||
// Record original json
|
||||
oldData, err := json.Marshal(req)
|
||||
|
||||
@@ -41,6 +41,7 @@ import (
|
||||
listers "github.com/heptio/ark/pkg/generated/listers/ark/v1"
|
||||
"github.com/heptio/ark/pkg/restic"
|
||||
"github.com/heptio/ark/pkg/util/boolptr"
|
||||
arkexec "github.com/heptio/ark/pkg/util/exec"
|
||||
"github.com/heptio/ark/pkg/util/kube"
|
||||
)
|
||||
|
||||
@@ -308,7 +309,7 @@ func restorePodVolume(req *arkv1api.PodVolumeRestore, credsFile, volumeDir strin
|
||||
|
||||
var stdout, stderr string
|
||||
|
||||
if stdout, stderr, err = runCommand(resticCmd.Cmd()); err != nil {
|
||||
if stdout, stderr, err = arkexec.RunCommand(resticCmd.Cmd()); err != nil {
|
||||
return errors.Wrapf(err, "error running restic restore, cmd=%s, stdout=%s, stderr=%s", resticCmd.String(), stdout, stderr)
|
||||
}
|
||||
log.Debugf("Ran command=%s, stdout=%s, stderr=%s", resticCmd.String(), stdout, stderr)
|
||||
|
||||
@@ -191,3 +191,7 @@ func newPodVolumeBackup(backup *arkv1api.Backup, pod *corev1api.Pod, volumeName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func errorOnly(_ interface{}, err error) error {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -34,6 +33,7 @@ import (
|
||||
clientset "github.com/heptio/ark/pkg/generated/clientset/versioned"
|
||||
arkv1informers "github.com/heptio/ark/pkg/generated/informers/externalversions/ark/v1"
|
||||
arkv1listers "github.com/heptio/ark/pkg/generated/listers/ark/v1"
|
||||
arkexec "github.com/heptio/ark/pkg/util/exec"
|
||||
)
|
||||
|
||||
// RepositoryManager executes commands against restic repositories.
|
||||
@@ -163,7 +163,7 @@ func (rm *repositoryManager) InitRepo(name string) error {
|
||||
rm.repoLocker.LockExclusive(name)
|
||||
defer rm.repoLocker.UnlockExclusive(name)
|
||||
|
||||
return errorOnly(rm.exec(InitCommand(rm.repoPrefix, name)))
|
||||
return rm.exec(InitCommand(rm.repoPrefix, name))
|
||||
}
|
||||
|
||||
func (rm *repositoryManager) CheckRepo(name string) error {
|
||||
@@ -172,7 +172,7 @@ func (rm *repositoryManager) CheckRepo(name string) error {
|
||||
|
||||
cmd := CheckCommand(rm.repoPrefix, name)
|
||||
|
||||
return errorOnly(rm.exec(cmd))
|
||||
return rm.exec(cmd)
|
||||
}
|
||||
|
||||
func (rm *repositoryManager) PruneRepo(name string) error {
|
||||
@@ -181,7 +181,7 @@ func (rm *repositoryManager) PruneRepo(name string) error {
|
||||
|
||||
cmd := PruneCommand(rm.repoPrefix, name)
|
||||
|
||||
return errorOnly(rm.exec(cmd))
|
||||
return rm.exec(cmd)
|
||||
}
|
||||
|
||||
func (rm *repositoryManager) Forget(snapshot SnapshotIdentifier) error {
|
||||
@@ -190,31 +190,29 @@ func (rm *repositoryManager) Forget(snapshot SnapshotIdentifier) error {
|
||||
|
||||
cmd := ForgetCommand(rm.repoPrefix, snapshot.Repo, snapshot.SnapshotID)
|
||||
|
||||
return errorOnly(rm.exec(cmd))
|
||||
return rm.exec(cmd)
|
||||
}
|
||||
|
||||
func (rm *repositoryManager) exec(cmd *Command) ([]byte, error) {
|
||||
func (rm *repositoryManager) exec(cmd *Command) error {
|
||||
file, err := TempCredentialsFile(rm.secretsLister, cmd.Repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
// ignore error since there's nothing we can do and it's a temp file.
|
||||
defer os.Remove(file)
|
||||
|
||||
cmd.PasswordFile = file
|
||||
|
||||
output, err := cmd.Cmd().Output()
|
||||
rm.log.WithField("repository", cmd.Repo).Debugf("Ran restic command=%q, output=%s", cmd.String(), output)
|
||||
stdout, stderr, err := arkexec.RunCommand(cmd.Cmd())
|
||||
rm.log.WithFields(logrus.Fields{
|
||||
"repository": cmd.Repo,
|
||||
"command": cmd.String(),
|
||||
"stdout": stdout,
|
||||
"stderr": stderr,
|
||||
}).Debugf("Ran restic command")
|
||||
if err != nil {
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
return nil, errors.Wrapf(err, "error running command, stderr=%s", exitErr.Stderr)
|
||||
}
|
||||
return nil, errors.Wrap(err, "error running command")
|
||||
return errors.Wrapf(err, "error running command=%s, stdout=%s, stderr=%s", cmd.String(), stdout, stderr)
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func errorOnly(_ interface{}, err error) error {
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2018 the Heptio Ark contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package exec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// RunCommand runs a command and returns its stdout, stderr, and its returned
|
||||
// error (if any). If there are errors reading stdout or stderr, their return
|
||||
// value(s) will contain the error as a string.
|
||||
func RunCommand(cmd *exec.Cmd) (string, string, error) {
|
||||
stdoutBuf := new(bytes.Buffer)
|
||||
stderrBuf := new(bytes.Buffer)
|
||||
|
||||
cmd.Stdout = stdoutBuf
|
||||
cmd.Stderr = stderrBuf
|
||||
|
||||
runErr := cmd.Run()
|
||||
|
||||
var stdout, stderr string
|
||||
|
||||
if res, readErr := ioutil.ReadAll(stdoutBuf); readErr != nil {
|
||||
stdout = errors.Wrap(readErr, "error reading command's stdout").Error()
|
||||
} else {
|
||||
stdout = string(res)
|
||||
}
|
||||
|
||||
if res, readErr := ioutil.ReadAll(stderrBuf); readErr != nil {
|
||||
stderr = errors.Wrap(readErr, "error reading command's stderr").Error()
|
||||
} else {
|
||||
stderr = string(res)
|
||||
}
|
||||
|
||||
return stdout, stderr, runErr
|
||||
}
|
||||
Reference in New Issue
Block a user