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  }