logs commands: validate backup/restore exists & is finished processing
Signed-off-by: Steve Kriss <krisss@vmware.com>pull/1337/head
parent
a696cd09f2
commit
1d3d66aa77
|
@ -0,0 +1 @@
|
|||
velero backup logs & velero restore logs: show helpful error message if backup/restore does not exist or is not finished processing
|
|
@ -21,6 +21,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
v1 "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
"github.com/heptio/velero/pkg/client"
|
||||
|
@ -36,10 +38,24 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
|
|||
Short: "Get backup logs",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
backupName := args[0]
|
||||
|
||||
veleroClient, err := f.Client()
|
||||
cmd.CheckError(err)
|
||||
|
||||
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), args[0], v1.DownloadTargetKindBackupLog, os.Stdout, timeout)
|
||||
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(backupName, metav1.GetOptions{})
|
||||
if apierrors.IsNotFound(err) {
|
||||
cmd.Exit("Backup %q does not exist.", backupName)
|
||||
} else if err != nil {
|
||||
cmd.Exit("Error checking for backup %q: %v", backupName, err)
|
||||
}
|
||||
|
||||
if backup.Status.Phase != v1.BackupPhaseCompleted && backup.Status.Phase != v1.BackupPhaseFailed {
|
||||
cmd.Exit("Logs for backup %q are not available until it's finished processing. Please wait "+
|
||||
"until the backup has a phase of Completed or Failed and try again.", backupName)
|
||||
}
|
||||
|
||||
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), backupName, v1.DownloadTargetKindBackupLog, os.Stdout, timeout)
|
||||
cmd.CheckError(err)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -20,15 +20,14 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
v1 "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
"github.com/heptio/velero/pkg/client"
|
||||
"github.com/heptio/velero/pkg/cmd"
|
||||
"github.com/heptio/velero/pkg/cmd/util/downloadrequest"
|
||||
veleroclient "github.com/heptio/velero/pkg/generated/clientset/versioned"
|
||||
)
|
||||
|
||||
func NewLogsCommand(f client.Factory) *cobra.Command {
|
||||
|
@ -39,12 +38,24 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
|
|||
Short: "Get restore logs",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
l := NewLogsOptions()
|
||||
cmd.CheckError(l.Complete(args))
|
||||
cmd.CheckError(l.Validate(f))
|
||||
restoreName := args[0]
|
||||
|
||||
veleroClient, err := f.Client()
|
||||
cmd.CheckError(err)
|
||||
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), args[0], v1.DownloadTargetKindRestoreLog, os.Stdout, timeout)
|
||||
|
||||
restore, err := veleroClient.VeleroV1().Restores(f.Namespace()).Get(restoreName, metav1.GetOptions{})
|
||||
if apierrors.IsNotFound(err) {
|
||||
cmd.Exit("Restore %q does not exist.", restoreName)
|
||||
} else if err != nil {
|
||||
cmd.Exit("Error checking for restore %q: %v", restoreName, err)
|
||||
}
|
||||
|
||||
if restore.Status.Phase != v1.RestorePhaseCompleted && restore.Status.Phase != v1.RestorePhaseFailed {
|
||||
cmd.Exit("Logs for restore %q are not available until it's finished processing. Please wait "+
|
||||
"until the restore has a phase of Completed or Failed and try again.", restoreName)
|
||||
}
|
||||
|
||||
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), restoreName, v1.DownloadTargetKindRestoreLog, os.Stdout, timeout)
|
||||
cmd.CheckError(err)
|
||||
},
|
||||
}
|
||||
|
@ -53,41 +64,3 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
|
|||
|
||||
return c
|
||||
}
|
||||
|
||||
// LogsOptions contains the fields required to retrieve logs of a restore
|
||||
type LogsOptions struct {
|
||||
RestoreName string
|
||||
|
||||
client veleroclient.Interface
|
||||
}
|
||||
|
||||
// NewLogsOptions returns a new instance of LogsOptions
|
||||
func NewLogsOptions() *LogsOptions {
|
||||
return &LogsOptions{}
|
||||
}
|
||||
|
||||
// Complete fills in LogsOptions with the given parameters, like populating the
|
||||
// restore name from the input args
|
||||
func (l *LogsOptions) Complete(args []string) error {
|
||||
l.RestoreName = args[0]
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates the LogsOptions against the cluster, like validating if
|
||||
// the given restore exists in the cluster or not
|
||||
func (l *LogsOptions) Validate(f client.Factory) error {
|
||||
c, err := f.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.client = c
|
||||
|
||||
r, err := l.client.VeleroV1().Restores(f.Namespace()).Get(l.RestoreName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if r.Status.Phase != v1.RestorePhaseCompleted {
|
||||
return errors.Errorf("unable to retrieve logs because restore is not complete")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -32,3 +32,9 @@ func CheckError(err error) {
|
|||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Exit prints msg (with optional args), plus a newline, to stderr and exits with code 1.
|
||||
func Exit(msg string, args ...interface{}) {
|
||||
fmt.Fprintf(os.Stderr, msg+"\n", args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue