github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/model/cancelgeneration.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package model 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "github.com/juju/gnuflag" 10 11 "github.com/juju/juju/api/modelgeneration" 12 jujucmd "github.com/juju/juju/cmd" 13 "github.com/juju/juju/cmd/modelcmd" 14 "github.com/juju/juju/core/model" 15 ) 16 17 const ( 18 cancelGenerationSummary = "Cancels the new generation to the model." 19 cancelGenerationDoc = ` 20 Cancel the next generation. This will abort anything in the next 21 generation and return the active target to the current generation. 22 23 Examples: 24 juju cancel-generation 25 26 See also: 27 add-generation 28 advance-generation 29 switch-generation 30 ` 31 ) 32 33 // NewCancelGenerationCommand wraps cancelGenerationCommand with sane model settings. 34 func NewCancelGenerationCommand() cmd.Command { 35 return modelcmd.Wrap(&cancelGenerationCommand{}) 36 } 37 38 // cancelGenerationCommand is the simplified command for accessing and setting 39 // attributes related to canceling model generations. 40 type cancelGenerationCommand struct { 41 modelcmd.ModelCommandBase 42 43 api CancelGenerationCommandAPI 44 } 45 46 // CancelGenerationCommandAPI defines an API interface to be used during testing. 47 //go:generate mockgen -package mocks -destination ./mocks/cancelgeneration_mock.go github.com/juju/juju/cmd/juju/model CancelGenerationCommandAPI 48 type CancelGenerationCommandAPI interface { 49 Close() error 50 CancelGeneration(string) error 51 } 52 53 // Info implements part of the cmd.Command interface. 54 func (c *cancelGenerationCommand) Info() *cmd.Info { 55 info := &cmd.Info{ 56 Name: "cancel-generation", 57 Purpose: cancelGenerationSummary, 58 Doc: cancelGenerationDoc, 59 } 60 return jujucmd.Info(info) 61 } 62 63 // SetFlags implements part of the cmd.Command interface. 64 func (c *cancelGenerationCommand) SetFlags(f *gnuflag.FlagSet) { 65 c.ModelCommandBase.SetFlags(f) 66 } 67 68 // Init implements part of the cmd.Command interface. 69 func (c *cancelGenerationCommand) Init(args []string) error { 70 if len(args) != 0 { 71 return errors.Errorf("No arguments allowed") 72 } 73 return nil 74 } 75 76 // getAPI returns the API. This allows passing in a test CancelGenerationCommandAPI 77 // implementation. 78 func (c *cancelGenerationCommand) getAPI() (CancelGenerationCommandAPI, error) { 79 if c.api != nil { 80 return c.api, nil 81 } 82 api, err := c.NewAPIRoot() 83 if err != nil { 84 return nil, errors.Annotate(err, "opening API connection") 85 } 86 client := modelgeneration.NewClient(api) 87 return client, nil 88 } 89 90 // Run implements the meaty part of the cmd.Command interface. 91 func (c *cancelGenerationCommand) Run(ctx *cmd.Context) error { 92 client, err := c.getAPI() 93 if err != nil { 94 return err 95 } 96 defer client.Close() 97 98 _, modelDetails, err := c.ModelCommandBase.ModelDetails() 99 if err != nil { 100 return errors.Annotate(err, "getting model details") 101 } 102 103 if err = client.CancelGeneration(modelDetails.ModelUUID); err != nil { 104 return err 105 } 106 107 // Now update the model store with the 'current' generation for this 108 // model. 109 if err = c.SetModelGeneration(model.GenerationCurrent); err != nil { 110 return err 111 } 112 113 ctx.Stdout.Write([]byte("remaining incomplete changes dropped and target generation set to current\n")) 114 return nil 115 }