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