github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/common/upgradeseries.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names/v5" 9 10 "github.com/juju/juju/api/base" 11 apiwatcher "github.com/juju/juju/api/watcher" 12 apiservererrors "github.com/juju/juju/apiserver/errors" 13 "github.com/juju/juju/core/model" 14 "github.com/juju/juju/core/watcher" 15 "github.com/juju/juju/rpc/params" 16 ) 17 18 // UpgradeSeriesAPI provides common agent-side API functions to 19 // call into apiserver.common/UpgradeSeries 20 type UpgradeSeriesAPI struct { 21 facade base.FacadeCaller 22 tag names.Tag 23 } 24 25 // NewUpgradeSeriesAPI creates a UpgradeSeriesAPI on the specified facade, 26 // and uses this name when calling through the caller. 27 func NewUpgradeSeriesAPI(facade base.FacadeCaller, tag names.Tag) *UpgradeSeriesAPI { 28 return &UpgradeSeriesAPI{facade: facade, tag: tag} 29 } 30 31 // WatchUpgradeSeriesNotifications returns a NotifyWatcher for observing the state of 32 // a series upgrade. 33 func (u *UpgradeSeriesAPI) WatchUpgradeSeriesNotifications() (watcher.NotifyWatcher, error) { 34 var results params.NotifyWatchResults 35 args := params.Entities{ 36 Entities: []params.Entity{{Tag: u.tag.String()}}, 37 } 38 err := u.facade.FacadeCall("WatchUpgradeSeriesNotifications", args, &results) 39 if err != nil { 40 return nil, err 41 } 42 if len(results.Results) != 1 { 43 return nil, errors.Errorf("expected 1 result, got %d", len(results.Results)) 44 } 45 result := results.Results[0] 46 if result.Error != nil { 47 return nil, result.Error 48 } 49 w := apiwatcher.NewNotifyWatcher(u.facade.RawAPICaller(), result) 50 return w, nil 51 } 52 53 // UpgradeSeriesUnitStatus returns the upgrade series status of a 54 // unit from remote state. 55 func (u *UpgradeSeriesAPI) UpgradeSeriesUnitStatus() (model.UpgradeSeriesStatus, string, error) { 56 var results params.UpgradeSeriesStatusResults 57 args := params.Entities{ 58 Entities: []params.Entity{{Tag: u.tag.String()}}, 59 } 60 61 err := u.facade.FacadeCall("UpgradeSeriesUnitStatus", args, &results) 62 if err != nil { 63 return "", "", err 64 } 65 if len(results.Results) != 1 { 66 return "", "", errors.Errorf("expected 1 result, got %d", len(results.Results)) 67 } 68 69 res := results.Results[0] 70 if res.Error != nil { 71 // TODO (externalreality) The code to convert api errors (with 72 // error codes) back to normal Go errors is in bad spot and 73 // causes import cycles which is why we don't use it here and may 74 // be the reason why it has few uses despite being useful. 75 if params.IsCodeNotFound(res.Error) { 76 return "", "", errors.NewNotFound(res.Error, "") 77 } 78 return "", "", res.Error 79 } 80 81 return res.Status, res.Target, nil 82 } 83 84 // SetUpgradeSeriesUnitStatus sets the upgrade series status of the 85 // unit in the remote state. 86 func (u *UpgradeSeriesAPI) SetUpgradeSeriesUnitStatus(status model.UpgradeSeriesStatus, reason string) error { 87 var results params.ErrorResults 88 args := params.UpgradeSeriesStatusParams{ 89 Params: []params.UpgradeSeriesStatusParam{{ 90 Entity: params.Entity{Tag: u.tag.String()}, 91 Status: status, 92 Message: reason, 93 }}, 94 } 95 err := u.facade.FacadeCall("SetUpgradeSeriesUnitStatus", args, &results) 96 if err != nil { 97 return err 98 } 99 if len(results.Results) != 1 { 100 return errors.Errorf("expected 1 result, got %d", len(results.Results)) 101 } 102 result := results.Results[0] 103 if result.Error != nil { 104 return apiservererrors.RestoreError(result.Error) 105 } 106 return nil 107 }