Skip to content

Commit

Permalink
logs commands: validate item exists & is finished processing
Browse files Browse the repository at this point in the history
Signed-off-by: Steve Kriss <krisss@vmware.com>
  • Loading branch information
skriss committed Mar 31, 2019
1 parent a696cd0 commit 265fdb6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 45 deletions.
18 changes: 17 additions & 1 deletion pkg/cmd/cli/backup/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
},
}
Expand Down
61 changes: 17 additions & 44 deletions pkg/cmd/cli/restore/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
},
}
Expand All @@ -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
}
6 changes: 6 additions & 0 deletions pkg/cmd/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

0 comments on commit 265fdb6

Please sign in to comment.