github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/backups/upload.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 9 "github.com/juju/cmd" 10 "github.com/juju/errors" 11 12 "github.com/juju/juju/apiserver/params" 13 "github.com/juju/juju/cmd/modelcmd" 14 ) 15 16 const uploadDoc = ` 17 upload-backup sends a backup archive file to remote storage. 18 ` 19 20 // NewUploadCommand returns a command used to send a backup 21 // achive file to remote storage. 22 func NewUploadCommand() cmd.Command { 23 return modelcmd.Wrap(&uploadCommand{}) 24 } 25 26 // uploadCommand is the sub-command for uploading a backup archive. 27 type uploadCommand struct { 28 CommandBase 29 // Filename is where to find the archive to upload. 30 Filename string 31 } 32 33 // Info implements Command.Info. 34 func (c *uploadCommand) Info() *cmd.Info { 35 return &cmd.Info{ 36 Name: "upload-backup", 37 Args: "<filename>", 38 Purpose: "Store a backup archive file remotely in Juju.", 39 Doc: uploadDoc, 40 } 41 } 42 43 // Init implements Command.Init. 44 func (c *uploadCommand) Init(args []string) error { 45 if len(args) == 0 { 46 return errors.New("backup filename not specified") 47 } 48 filename, args := args[0], args[1:] 49 if err := cmd.CheckEmpty(args); err != nil { 50 return errors.Trace(err) 51 } 52 c.Filename = filename 53 return nil 54 } 55 56 // Run implements Command.Run. 57 func (c *uploadCommand) Run(ctx *cmd.Context) error { 58 if c.Log != nil { 59 if err := c.Log.Start(ctx); err != nil { 60 return err 61 } 62 } 63 client, err := c.NewAPIClient() 64 if err != nil { 65 return errors.Trace(err) 66 } 67 defer client.Close() 68 69 archive, meta, err := getArchive(c.Filename) 70 if err != nil { 71 return errors.Trace(err) 72 } 73 defer archive.Close() 74 75 if c.Log != nil && c.Log.Verbose { 76 fmt.Fprintln(ctx.Stdout, "Uploaded metadata:") 77 c.dumpMetadata(ctx, meta) 78 fmt.Fprintln(ctx.Stdout) 79 } 80 81 // Upload the archive. 82 id, err := client.Upload(archive, *meta) 83 if err != nil { 84 return errors.Trace(err) 85 } 86 87 if c.Log != nil && c.Log.Quiet { 88 fmt.Fprintln(ctx.Stdout, id) 89 return nil 90 } 91 92 // Pull the stored metadata. 93 stored, err := c.getStoredMetadata(id) 94 if err != nil { 95 return errors.Trace(err) 96 } 97 98 c.dumpMetadata(ctx, stored) 99 return nil 100 } 101 102 func (c *uploadCommand) getStoredMetadata(id string) (*params.BackupsMetadataResult, error) { 103 // TODO(ericsnow) lp-1399722 This should be addressed. 104 // There is at least anecdotal evidence that we cannot use an API 105 // client for more than a single request. So we use a new client 106 // for download. 107 client, err := c.NewAPIClient() 108 if err != nil { 109 return nil, errors.Trace(err) 110 } 111 defer client.Close() 112 113 stored, err := client.Info(id) 114 return stored, errors.Trace(err) 115 }