github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/backups/download.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package backups
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"os"
    10  
    11  	"github.com/juju/cmd"
    12  	"github.com/juju/errors"
    13  	"github.com/juju/gnuflag"
    14  
    15  	jujucmd "github.com/juju/juju/cmd"
    16  	"github.com/juju/juju/cmd/modelcmd"
    17  	"github.com/juju/juju/state/backups"
    18  )
    19  
    20  const downloadDoc = `
    21  download-backup retrieves a backup archive file.
    22  
    23  If --filename is not used, the archive is downloaded to a temporary
    24  location and the filename is printed to stdout.
    25  `
    26  
    27  // NewDownloadCommand returns a commant used to download backups.
    28  func NewDownloadCommand() cmd.Command {
    29  	return modelcmd.Wrap(&downloadCommand{})
    30  }
    31  
    32  // downloadCommand is the sub-command for downloading a backup archive.
    33  type downloadCommand struct {
    34  	CommandBase
    35  	// Filename is where to save the downloaded archive.
    36  	Filename string
    37  	// ID is the backup ID to download.
    38  	ID string
    39  }
    40  
    41  // Info implements Command.Info.
    42  func (c *downloadCommand) Info() *cmd.Info {
    43  	return jujucmd.Info(&cmd.Info{
    44  		Name:    "download-backup",
    45  		Args:    "<ID>",
    46  		Purpose: "Get an archive file.",
    47  		Doc:     downloadDoc,
    48  	})
    49  }
    50  
    51  // SetFlags implements Command.SetFlags.
    52  func (c *downloadCommand) SetFlags(f *gnuflag.FlagSet) {
    53  	c.CommandBase.SetFlags(f)
    54  	f.StringVar(&c.Filename, "filename", "", "Download target")
    55  }
    56  
    57  // Init implements Command.Init.
    58  func (c *downloadCommand) Init(args []string) error {
    59  	if len(args) == 0 {
    60  		return errors.New("missing ID")
    61  	}
    62  	id, args := args[0], args[1:]
    63  	if err := cmd.CheckEmpty(args); err != nil {
    64  		return errors.Trace(err)
    65  	}
    66  	c.ID = id
    67  	return nil
    68  }
    69  
    70  // Run implements Command.Run.
    71  func (c *downloadCommand) Run(ctx *cmd.Context) error {
    72  	if c.Log != nil {
    73  		if err := c.Log.Start(ctx); err != nil {
    74  			return err
    75  		}
    76  	}
    77  	client, err := c.NewAPIClient()
    78  	if err != nil {
    79  		return errors.Trace(err)
    80  	}
    81  	defer client.Close()
    82  
    83  	// Download the archive.
    84  	resultArchive, err := client.Download(c.ID)
    85  	if err != nil {
    86  		return errors.Trace(err)
    87  	}
    88  	defer resultArchive.Close()
    89  
    90  	// Prepare the local archive.
    91  	filename := c.ResolveFilename()
    92  	archive, err := os.Create(filename)
    93  	if err != nil {
    94  		return errors.Annotate(err, "while creating local archive file")
    95  	}
    96  	defer archive.Close()
    97  
    98  	// Write out the archive.
    99  	_, err = io.Copy(archive, resultArchive)
   100  	if err != nil {
   101  		return errors.Annotate(err, "while copying local archive file")
   102  	}
   103  
   104  	// Print the local filename.
   105  	fmt.Fprintln(ctx.Stdout, filename)
   106  	return nil
   107  }
   108  
   109  // ResolveFilename returns the filename used by the command.
   110  func (c *downloadCommand) ResolveFilename() string {
   111  	filename := c.Filename
   112  	if filename == "" {
   113  		filename = backups.FilenamePrefix + c.ID + ".tar.gz"
   114  	}
   115  	return filename
   116  }