github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/api/agent/machineactions/machineactions.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Copyright 2016 Cloudbase Solutions 3 // Licensed under the AGPLv3, see LICENCE file for details. 4 5 package machineactions 6 7 import ( 8 "github.com/juju/errors" 9 "github.com/juju/names/v5" 10 11 "github.com/juju/juju/api/base" 12 apiwatcher "github.com/juju/juju/api/watcher" 13 "github.com/juju/juju/core/watcher" 14 "github.com/juju/juju/rpc/params" 15 ) 16 17 type Client struct { 18 facade base.FacadeCaller 19 } 20 21 func NewClient(caller base.APICaller) *Client { 22 return &Client{base.NewFacadeCaller(caller, "MachineActions")} 23 } 24 25 // WatchActionNotifications returns a StringsWatcher for observing the 26 // IDs of Actions added to the Machine. The initial event will contain the 27 // IDs of any Actions pending at the time the Watcher is made. 28 func (c *Client) WatchActionNotifications(agent names.MachineTag) (watcher.StringsWatcher, error) { 29 var results params.StringsWatchResults 30 args := params.Entities{ 31 Entities: []params.Entity{{Tag: agent.String()}}, 32 } 33 34 err := c.facade.FacadeCall("WatchActionNotifications", args, &results) 35 if err != nil { 36 return nil, errors.Trace(err) 37 } 38 39 if len(results.Results) != 1 { 40 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 41 } 42 43 result := results.Results[0] 44 if result.Error != nil { 45 return nil, errors.Trace(result.Error) 46 } 47 w := apiwatcher.NewStringsWatcher(c.facade.RawAPICaller(), result) 48 return w, nil 49 } 50 51 func (c *Client) getOneAction(tag names.ActionTag) (params.ActionResult, error) { 52 nothing := params.ActionResult{} 53 54 args := params.Entities{ 55 Entities: []params.Entity{{Tag: tag.String()}}, 56 } 57 58 var results params.ActionResults 59 err := c.facade.FacadeCall("Actions", args, &results) 60 if err != nil { 61 return nothing, errors.Trace(err) 62 } 63 64 if len(results.Results) > 1 { 65 return nothing, errors.Errorf("expected only 1 action query result, got %d", len(results.Results)) 66 } 67 68 result := results.Results[0] 69 if result.Error != nil { 70 return nothing, errors.Trace(result.Error) 71 } 72 73 return result, nil 74 } 75 76 // Action returns the Action with the given tag. 77 func (c *Client) Action(tag names.ActionTag) (*Action, error) { 78 result, err := c.getOneAction(tag) 79 if err != nil { 80 return nil, errors.Trace(err) 81 } 82 a := &Action{ 83 id: tag.Id(), 84 name: result.Action.Name, 85 params: result.Action.Parameters, 86 } 87 if result.Action.Parallel != nil { 88 a.parallel = *result.Action.Parallel 89 } 90 if result.Action.ExecutionGroup != nil { 91 a.executionGroup = *result.Action.ExecutionGroup 92 } 93 return a, nil 94 } 95 96 // ActionBegin marks an action as running. 97 func (c *Client) ActionBegin(tag names.ActionTag) error { 98 var results params.ErrorResults 99 100 args := params.Entities{ 101 Entities: []params.Entity{{Tag: tag.String()}}, 102 } 103 104 err := c.facade.FacadeCall("BeginActions", args, &results) 105 if err != nil { 106 return errors.Trace(err) 107 } 108 109 return results.OneError() 110 } 111 112 // ActionFinish captures the structured output of an action. 113 func (c *Client) ActionFinish(tag names.ActionTag, status string, actionResults map[string]interface{}, message string) error { 114 var results params.ErrorResults 115 116 args := params.ActionExecutionResults{ 117 Results: []params.ActionExecutionResult{{ 118 ActionTag: tag.String(), 119 Status: status, 120 Results: actionResults, 121 Message: message, 122 }}, 123 } 124 125 err := c.facade.FacadeCall("FinishActions", args, &results) 126 if err != nil { 127 return errors.Trace(err) 128 } 129 130 return results.OneError() 131 } 132 133 // RunningActions returns a list of actions running for the given machine tag. 134 func (c *Client) RunningActions(agent names.MachineTag) ([]params.ActionResult, error) { 135 var results params.ActionsByReceivers 136 137 args := params.Entities{ 138 Entities: []params.Entity{{Tag: agent.String()}}, 139 } 140 141 err := c.facade.FacadeCall("RunningActions", args, &results) 142 if err != nil { 143 return nil, errors.Trace(err) 144 } 145 146 if len(results.Actions) != 1 { 147 return nil, errors.Errorf("expected 1 result, got %d", len(results.Actions)) 148 } 149 150 result := results.Actions[0] 151 if result.Error != nil { 152 return nil, result.Error 153 } 154 155 return result.Actions, nil 156 }