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