github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/common/unitstate.go (about) 1 // Copyright 2020 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 "github.com/juju/juju/rpc/params" 12 ) 13 14 // UnitStateAPI provides common agent-side API functions to 15 // call into apiserver.common/UnitState 16 type UnitStateAPI struct { 17 facade base.FacadeCaller 18 tag names.UnitTag 19 } 20 21 // NewUniterStateAPI creates a UnitStateAPI that uses the provided FacadeCaller 22 // for making calls. 23 func NewUniterStateAPI(facade base.FacadeCaller, tag names.UnitTag) *UnitStateAPI { 24 return &UnitStateAPI{facade: facade, tag: tag} 25 } 26 27 // State returns the state persisted by the charm running in this unit 28 // and the state internal to the uniter for this unit. 29 func (u *UnitStateAPI) State() (params.UnitStateResult, error) { 30 var results params.UnitStateResults 31 args := params.Entities{ 32 Entities: []params.Entity{{Tag: u.tag.String()}}, 33 } 34 err := u.facade.FacadeCall("State", args, &results) 35 if err != nil { 36 return params.UnitStateResult{}, err 37 } 38 if len(results.Results) != 1 { 39 return params.UnitStateResult{}, errors.Errorf("expected 1 result, got %d", len(results.Results)) 40 } 41 result := results.Results[0] 42 if result.Error != nil { 43 return params.UnitStateResult{}, result.Error 44 } 45 return result, nil 46 } 47 48 // SetState sets the state persisted by the charm running in this unit 49 // and the state internal to the uniter for this unit. 50 func (u *UnitStateAPI) SetState(unitState params.SetUnitStateArg) error { 51 unitState.Tag = u.tag.String() 52 var results params.ErrorResults 53 args := params.SetUnitStateArgs{ 54 Args: []params.SetUnitStateArg{unitState}, 55 } 56 err := u.facade.FacadeCall("SetState", args, &results) 57 if err != nil { 58 return errors.Trace(err) 59 } 60 // Make sure we correctly decode quota-related errors. 61 return maybeRestoreQuotaLimitError(results.OneError()) 62 } 63 64 // maybeRestoreQuotaLimitError checks if the server emitted a quota limit 65 // exceeded error and restores it back to a typed error from juju/errors. 66 // Ideally, we would use apiserver/common.RestoreError but apparently, that 67 // package imports worker/uniter/{operation, remotestate} causing an import 68 // cycle when api/common is imported by api/uniter. 69 func maybeRestoreQuotaLimitError(err error) error { 70 if params.IsCodeQuotaLimitExceeded(err) { 71 return errors.NewQuotaLimitExceeded(nil, err.Error()) 72 } 73 return err 74 }