github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/payload/context/register.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package context 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "gopkg.in/juju/charm.v6" 10 11 jujucmd "github.com/juju/juju/cmd" 12 "github.com/juju/juju/payload" 13 ) 14 15 // RegisterCmdName is the name of the payload register command. 16 const RegisterCmdName = "payload-register" 17 18 // NewRegisterCmd returns a new RegisterCmd that wraps the given context. 19 func NewRegisterCmd(ctx HookContext) (*RegisterCmd, error) { 20 return &RegisterCmd{hookContextFunc: componentHookContext(ctx)}, nil 21 } 22 23 // RegisterCmd is a command that registers a payload with juju. 24 type RegisterCmd struct { 25 cmd.CommandBase 26 27 hookContextFunc func() (Component, error) 28 typ string 29 class string 30 id string 31 labels []string 32 } 33 34 // TODO(ericsnow) Change "tags" to "labels" in the help text? 35 36 // Info implements cmd.Command. 37 func (c RegisterCmd) Info() *cmd.Info { 38 return jujucmd.Info(&cmd.Info{ 39 Name: RegisterCmdName, 40 Args: "<type> <class> <id> [tags...]", 41 Purpose: "register a charm payload with juju", 42 Doc: ` 43 "payload-register" is used while a hook is running to let Juju know that a 44 payload has been started. The information used to start the payload must be 45 provided when "register" is run. 46 47 The payload class must correspond to one of the payloads defined in 48 the charm's metadata.yaml. 49 50 `, 51 }) 52 } 53 54 // Init implements cmd.Command. 55 func (c *RegisterCmd) Init(args []string) error { 56 if len(args) < 3 { 57 return errors.Errorf("missing required arguments") 58 } 59 c.typ = args[0] 60 c.class = args[1] 61 c.id = args[2] 62 c.labels = args[3:] 63 return nil 64 } 65 66 // Run implements cmd.Command. 67 func (c *RegisterCmd) Run(ctx *cmd.Context) error { 68 if err := c.validate(ctx); err != nil { 69 return errors.Trace(err) 70 } 71 pl := payload.Payload{ 72 PayloadClass: charm.PayloadClass{ 73 Name: c.class, 74 Type: c.typ, 75 }, 76 ID: c.id, 77 Status: payload.StateRunning, 78 Labels: c.labels, 79 Unit: "a-application/0", // TODO(ericsnow) eliminate this! 80 } 81 hctx, err := c.hookContextFunc() 82 if err != nil { 83 return errors.Trace(err) 84 } 85 if err := hctx.Track(pl); err != nil { 86 return errors.Trace(err) 87 } 88 89 // We flush to state immediately so that status reflects the 90 // payload correctly. 91 if err := hctx.Flush(); err != nil { 92 return errors.Trace(err) 93 } 94 95 // TODO(ericsnow) Print out the full ID. 96 97 return nil 98 } 99 100 func (c *RegisterCmd) validate(ctx *cmd.Context) error { 101 meta, err := readMetadata(ctx) 102 if err != nil { 103 return errors.Trace(err) 104 } 105 106 found := false 107 for _, class := range meta.PayloadClasses { 108 if c.class == class.Name { 109 if c.typ != class.Type { 110 return errors.Errorf("incorrect type %q for payload %q, expected %q", c.typ, class.Name, class.Type) 111 } 112 found = true 113 } 114 } 115 if !found { 116 return errors.Errorf("payload %q not found in metadata.yaml", c.class) 117 } 118 return nil 119 }