Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 2.9 to 3.1 with sidecar teardown #15674

Merged
merged 59 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
d94e2e8
Introduces the ability to teardown sidecar charms.
tlm Mar 20, 2023
3a87c38
Prevent introduction of dead units or unwanted units (by scale).
hpidcock Apr 13, 2023
2791f38
Handle unit not found as dead life for removed unit.
hpidcock Apr 13, 2023
359b142
Safeguard against unit introduction introducing new unit in scale down.
hpidcock Apr 13, 2023
3e60fee
Fix lifeflag worker to check for ErrNotFound not errors.NotFound.
hpidcock Apr 13, 2023
4b9f022
Improve caasapplicationprovisioner during startup and app removal.
hpidcock Apr 13, 2023
e0e3c96
Fix handling of errors for UnitIntroduction.
hpidcock Apr 13, 2023
a8f5462
Fix missing copyright statement
hpidcock Apr 13, 2023
9c47857
Add provisioning state to application for caasapplicationprovisioner …
hpidcock Apr 15, 2023
8a52ce4
Improve unit introduction within state.
hpidcock Apr 16, 2023
32459be
Remove GarbageCollect used by caasapplicationprovisioner + extra logs.
hpidcock Apr 16, 2023
8ae2c6e
Enable public.ecr.aws
hpidcock Apr 16, 2023
851208c
Cleanup + fix unit tests for sidecar teardown.
hpidcock Apr 18, 2023
cb35703
Fix linter issues.
hpidcock Apr 18, 2023
e75fac5
Merge branch '2.9' into teardown-2.0
hpidcock Apr 18, 2023
d68eabb
Improve storage reattachment for sidecar charms + storage destroy log…
hpidcock Apr 23, 2023
0c9a426
Start of refactor of caasapplicationprovisioner for better testing.
hpidcock Apr 25, 2023
c50b562
caasapplicationprovisioner operation tests.
hpidcock Apr 26, 2023
1c22212
Add full caasapplicationprovisioner application worker test.
hpidcock Apr 26, 2023
8df6cc6
Add test for UpsertCAASUnit
hpidcock Apr 27, 2023
ca077ae
Implement migration and fix tests.
hpidcock Apr 28, 2023
1672b51
Use juju-qa-fixed-rev for refresh integreation test
jack-w-shaw May 23, 2023
1a2759d
Merge pull request #15636 from jack-w-shaw/JUJU-3822_replace_ubuntu_w…
jujubot May 24, 2023
2bb76c9
Adds tls-certificates-operator to fix mattermost-k8s.
anvial May 23, 2023
524980b
Switch to 'juju-qa-dummy-sink' and 'juju-qa-dummy-source' charms.
anvial May 24, 2023
097abc1
Use juju-qa-test rather than postgres
SimonRichardson May 24, 2023
c316413
Merge pull request #15650 from SimonRichardson/fix-machine-test-logs-aws
jujubot May 24, 2023
e2d4dd7
Replace deprecated yq -j flag with -o=j
barrettj12 May 24, 2023
4436840
Merge pull request #15652 from barrettj12/ojson
jujubot May 25, 2023
870f6c7
[bash tests] print controller teardown logs
barrettj12 May 25, 2023
ee886dd
Merge pull request #15653 from barrettj12/teardown-logs
jujubot May 25, 2023
0bb6df2
Merge pull request #15633 from anvial/JUJU-3821-fix-test-deploy-aks-c…
jujubot May 25, 2023
682a4b0
Adds BOOTSTRAP_PROVIDER=k8s before aks-controller boostraping.
anvial May 25, 2023
f16dd80
Merge pull request #15657 from anvial/JUJU-3842-fix-deploy-aks-clean-…
jujubot May 25, 2023
f98085e
Ignore failure on `aws ec2 delete-network-interface`
hpidcock May 25, 2023
686b6f2
Merge pull request #15660 from hpidcock/ignore-delete-network-interface
jujubot May 25, 2023
6841e1b
Fix data race in GetOSFromSeries
hpidcock May 26, 2023
c75361d
Fix relation departing test waiting.
hpidcock May 26, 2023
f639f09
Merge pull request #15661 from hpidcock/fix-data-race-getosfromseries
jujubot May 26, 2023
68ef945
Merge pull request #15662 from hpidcock/fix-relation-departing-test
jujubot May 26, 2023
4f1418a
Fix test-branch by using a simple charm.
hpidcock May 26, 2023
c14bcb3
Merge pull request #15663 from hpidcock/fix-test-branch
jujubot May 26, 2023
619ae83
Fix storage-attached hook that was requeued.
hpidcock May 2, 2023
4f58067
Fix ApplicationWorkerSuite.TestWorker flapping.
hpidcock May 2, 2023
0d62596
Fix LifeFlag watcher client test.
hpidcock May 2, 2023
f747552
Updates life flag not found error.
tlm May 8, 2023
5d23dcc
Adds missing tests for DestroyUnits.
tlm May 8, 2023
6e14eda
Update error name for life flag.
tlm May 8, 2023
cb6e938
Apply feedback to caas sidecar teardown.
hpidcock May 24, 2023
52f4bee
Fix storage not provisioned in TestNewHookRunnerWithStorage
hpidcock May 28, 2023
25ea0ca
Update juju/descriptions/v3
hpidcock May 28, 2023
1be46d0
Fix error handling for storage + PR feedback.
hpidcock May 29, 2023
0ab55fd
Fix uniter remotestate storage tests.
hpidcock May 29, 2023
243fd66
Merge pull request #15313 from tlm/teardown-2.0
jujubot May 29, 2023
a6e567b
Merge branch '2.9' into merge-2.9-3.1-sidecar-teardown
hpidcock May 30, 2023
90bc277
Fix non-microk8s cloud finding (e.g. minikube, from kubeconfig)
hpidcock Mar 27, 2023
e7596ce
Fix merge and regenerate mocks.
hpidcock May 30, 2023
a35072d
Fix TestUpsertCAASUnit
hpidcock May 30, 2023
54b093c
Fix controller terminating due to caasapplicationprovisioner.
hpidcock Jun 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/agent/caasapplication/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package caasapplication

import (
"github.com/juju/errors"
"github.com/juju/names/v4"

"github.com/juju/juju/api/base"
Expand Down Expand Up @@ -42,6 +43,11 @@ func (c *Client) UnitIntroduction(podName string, podUUID string) (*UnitConfig,
return nil, err
}
if err := result.Error; err != nil {
if params.IsCodeAlreadyExists(err) {
return nil, errors.AlreadyExists
} else if params.IsCodeNotAssigned(err) {
return nil, errors.NotAssigned
}
Comment on lines +46 to +50
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could have used apiservererrors.RestoreError() here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will handle in 2.9

return nil, err
}
return &UnitConfig{
Expand Down
47 changes: 45 additions & 2 deletions api/agent/caasapplication/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
package caasapplication_test

import (
"errors"

"github.com/juju/errors"
"github.com/juju/names/v4"
"github.com/juju/testing"
jc "github.com/juju/testing/checkers"
Expand Down Expand Up @@ -76,6 +75,50 @@ func (s *provisionerSuite) TestUnitIntroductionFail(c *gc.C) {
c.Assert(called, jc.IsTrue)
}

func (s *provisionerSuite) TestUnitIntroductionFailAlreadyExists(c *gc.C) {
var called bool
client := newClient(func(objType string, version int, id, request string, a, result interface{}) error {
called = true
c.Assert(objType, gc.Equals, "CAASApplication")
c.Assert(id, gc.Equals, "")
c.Assert(request, gc.Equals, "UnitIntroduction")
c.Assert(a, gc.FitsTypeOf, params.CAASUnitIntroductionArgs{})
args := a.(params.CAASUnitIntroductionArgs)
c.Assert(args.PodName, gc.Equals, "pod-name")
c.Assert(args.PodUUID, gc.Equals, "pod-uuid")
c.Assert(result, gc.FitsTypeOf, &params.CAASUnitIntroductionResult{})
*(result.(*params.CAASUnitIntroductionResult)) = params.CAASUnitIntroductionResult{
Error: &params.Error{Code: params.CodeAlreadyExists},
}
return nil
})
_, err := client.UnitIntroduction("pod-name", "pod-uuid")
c.Assert(errors.Is(err, errors.AlreadyExists), jc.IsTrue)
c.Assert(called, jc.IsTrue)
}

func (s *provisionerSuite) TestUnitIntroductionFailNotAssigned(c *gc.C) {
var called bool
client := newClient(func(objType string, version int, id, request string, a, result interface{}) error {
called = true
c.Assert(objType, gc.Equals, "CAASApplication")
c.Assert(id, gc.Equals, "")
c.Assert(request, gc.Equals, "UnitIntroduction")
c.Assert(a, gc.FitsTypeOf, params.CAASUnitIntroductionArgs{})
args := a.(params.CAASUnitIntroductionArgs)
c.Assert(args.PodName, gc.Equals, "pod-name")
c.Assert(args.PodUUID, gc.Equals, "pod-uuid")
c.Assert(result, gc.FitsTypeOf, &params.CAASUnitIntroductionResult{})
*(result.(*params.CAASUnitIntroductionResult)) = params.CAASUnitIntroductionResult{
Error: &params.Error{Code: params.CodeNotAssigned},
}
return nil
})
_, err := client.UnitIntroduction("pod-name", "pod-uuid")
c.Assert(errors.Is(err, errors.NotAssigned), jc.IsTrue)
c.Assert(called, jc.IsTrue)
}

func (s *provisionerSuite) TestUnitTerminating(c *gc.C) {
tests := []struct {
willRestart bool
Expand Down
24 changes: 24 additions & 0 deletions api/agent/lifeflag/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2023 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package lifeflag

import (
"github.com/juju/names/v4"

"github.com/juju/juju/api/base"
"github.com/juju/juju/api/common/lifeflag"
"github.com/juju/juju/core/life"
"github.com/juju/juju/core/watcher"
)

// Client is the client used for connecting to the life flag facade.
type Client interface {
Life(names.Tag) (life.Value, error)
Watch(names.Tag) (watcher.NotifyWatcher, error)
}

// NewClient creates a new life flag client.
func NewClient(caller base.APICaller) Client {
return lifeflag.NewClient(caller, "AgentLifeFlag")
}
3 changes: 2 additions & 1 deletion api/agent/uniter/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/juju/juju/api/base"
apiwatcher "github.com/juju/juju/api/watcher"
apiservererrors "github.com/juju/juju/apiserver/errors"
"github.com/juju/juju/core/watcher"
"github.com/juju/juju/rpc/params"
)
Expand Down Expand Up @@ -106,7 +107,7 @@ func (sa *StorageAccessor) StorageAttachment(storageTag names.StorageTag, unitTa
}
result := results.Results[0]
if result.Error != nil {
return params.StorageAttachment{}, result.Error
return params.StorageAttachment{}, apiservererrors.RestoreError(result.Error)
}
return result.Result, nil
}
Expand Down
37 changes: 37 additions & 0 deletions api/agent/uniter/uniter.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,3 +641,40 @@ func (st *State) CloudSpec() (*params.CloudSpec, error) {
}
return result.Result, nil
}

// UnitWorkloadVersion returns the version of the workload reported by
// the specified unit.
func (st *State) UnitWorkloadVersion(tag names.UnitTag) (string, error) {
var results params.StringResults
args := params.Entities{
Entities: []params.Entity{{Tag: tag.String()}},
}
err := st.facade.FacadeCall("WorkloadVersion", args, &results)
if err != nil {
return "", err
}
if len(results.Results) != 1 {
return "", fmt.Errorf("expected 1 result, got %d", len(results.Results))
}
result := results.Results[0]
if result.Error != nil {
return "", result.Error
}
return result.Result, nil
}

// SetUnitWorkloadVersion sets the specified unit's workload version to
// the provided value.
func (st *State) SetUnitWorkloadVersion(tag names.UnitTag, version string) error {
var result params.ErrorResults
args := params.EntityWorkloadVersions{
Entities: []params.EntityWorkloadVersion{
{Tag: tag.String(), WorkloadVersion: version},
},
}
err := st.facade.FacadeCall("SetWorkloadVersion", args, &result)
if err != nil {
return err
}
return result.OneError()
}
37 changes: 37 additions & 0 deletions api/agent/uniter/uniter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,40 @@ func (s *uniterSuite) TestOpenedPortRangesByEndpointOldAPINotSupported(c *gc.C)
_, err := client.OpenedPortRangesByEndpoint()
c.Assert(err, gc.ErrorMatches, `OpenedPortRangesByEndpoint\(\) \(need V18\+\) not implemented`)
}

func (s *uniterSuite) TestUnitWorkloadVersion(c *gc.C) {
apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
c.Assert(objType, gc.Equals, "Uniter")
c.Assert(request, gc.Equals, "WorkloadVersion")
c.Assert(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: "unit-mysql-0"}}})
c.Assert(result, gc.FitsTypeOf, &params.StringResults{})
*(result.(*params.StringResults)) = params.StringResults{
Results: []params.StringResult{{Result: "mysql-1.2.3"}},
}
return nil
})
caller := testing.BestVersionCaller{apiCaller, 17}
client := uniter.NewState(caller, names.NewUnitTag("mysql/0"))

workloadVersion, err := client.UnitWorkloadVersion(names.NewUnitTag("mysql/0"))
c.Assert(err, jc.ErrorIsNil)
c.Assert(workloadVersion, gc.Equals, "mysql-1.2.3")
}

func (s *uniterSuite) TestSetUnitWorkloadVersion(c *gc.C) {
apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
c.Assert(objType, gc.Equals, "Uniter")
c.Assert(request, gc.Equals, "SetWorkloadVersion")
c.Assert(arg, gc.DeepEquals, params.EntityWorkloadVersions{Entities: []params.EntityWorkloadVersion{{Tag: "unit-mysql-0", WorkloadVersion: "mysql-1.2.3"}}})
c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
*(result.(*params.ErrorResults)) = params.ErrorResults{
Results: []params.ErrorResult{{}},
}
return nil
})
caller := testing.BestVersionCaller{apiCaller, 17}
client := uniter.NewState(caller, names.NewUnitTag("mysql/0"))

err := client.SetUnitWorkloadVersion(names.NewUnitTag("mysql/0"), "mysql-1.2.3")
c.Assert(err, jc.ErrorIsNil)
}
41 changes: 20 additions & 21 deletions api/controller/lifeflag/facade.go → api/common/lifeflag/facade.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016 Canonical Ltd.
// Copyright 2023 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package lifeflag
Expand All @@ -8,6 +8,7 @@ import (
"github.com/juju/names/v4"

"github.com/juju/juju/api/base"
apiwatcher "github.com/juju/juju/api/watcher"
"github.com/juju/juju/core/life"
"github.com/juju/juju/core/watcher"
"github.com/juju/juju/rpc/params"
Expand All @@ -16,21 +17,19 @@ import (
// NewWatcherFunc exists to let us test Watch properly.
type NewWatcherFunc func(base.APICaller, params.NotifyWatchResult) watcher.NotifyWatcher

// Facade makes calls to the LifeFlag facade.
type Facade struct {
caller base.FacadeCaller
newWatcher NewWatcherFunc
// Client makes calls to the LifeFlag facade.
type Client struct {
caller base.FacadeCaller
}

// NewFacade returns a new Facade using the supplied caller.
func NewFacade(caller base.APICaller, newWatcher NewWatcherFunc) *Facade {
return &Facade{
caller: base.NewFacadeCaller(caller, "LifeFlag"),
newWatcher: newWatcher,
// NewClient returns a new Facade using the supplied caller.
func NewClient(caller base.APICaller, facadeName string) *Client {
return &Client{
caller: base.NewFacadeCaller(caller, facadeName),
}
}

// ErrNotFound indicates that the requested entity no longer exists.
// ErrEntityNotFound indicates that the requested entity no longer exists.
//
// We avoid errors.NotFound, because errors.NotFound is non-specific, and
// it's our job to communicate *this specific condition*. There are many
Expand All @@ -41,17 +40,17 @@ func NewFacade(caller base.APICaller, newWatcher NewWatcherFunc) *Facade {
// We're still vulnerable to apiservers returning unjustified CodeNotFound
// but at least we're safe from accidental errors.NotFound injection in
// the api client mechanism.
var ErrNotFound = errors.New("entity not found")
const ErrEntityNotFound = errors.ConstError("entity not found")

// Watch returns a NotifyWatcher that sends a value whenever the
// entity's life value may have changed; or ErrNotFound; or some
// entity's life value may have changed; or ErrEntityNotFound; or some
// other error.
func (facade *Facade) Watch(entity names.Tag) (watcher.NotifyWatcher, error) {
func (c *Client) Watch(entity names.Tag) (watcher.NotifyWatcher, error) {
args := params.Entities{
Entities: []params.Entity{{Tag: entity.String()}},
}
var results params.NotifyWatchResults
err := facade.caller.FacadeCall("Watch", args, &results)
err := c.caller.FacadeCall("Watch", args, &results)
if err != nil {
return nil, errors.Trace(err)
}
Expand All @@ -61,22 +60,22 @@ func (facade *Facade) Watch(entity names.Tag) (watcher.NotifyWatcher, error) {
result := results.Results[0]
if err := result.Error; err != nil {
if params.IsCodeNotFound(err) {
return nil, ErrNotFound
return nil, ErrEntityNotFound
}
return nil, errors.Trace(result.Error)
}
w := facade.newWatcher(facade.caller.RawAPICaller(), result)
w := apiwatcher.NewNotifyWatcher(c.caller.RawAPICaller(), result)
return w, nil
}

// Life returns the entity's life value; or ErrNotFound; or some
// Life returns the entity's life value; or ErrEntityNotFound; or some
// other error.
func (facade *Facade) Life(entity names.Tag) (life.Value, error) {
func (c *Client) Life(entity names.Tag) (life.Value, error) {
args := params.Entities{
Entities: []params.Entity{{Tag: entity.String()}},
}
var results params.LifeResults
err := facade.caller.FacadeCall("Life", args, &results)
err := c.caller.FacadeCall("Life", args, &results)
if err != nil {
return "", errors.Trace(err)
}
Expand All @@ -86,7 +85,7 @@ func (facade *Facade) Life(entity names.Tag) (life.Value, error) {
result := results.Results[0]
if err := result.Error; err != nil {
if params.IsCodeNotFound(err) {
return "", ErrNotFound
return "", ErrEntityNotFound
}
return "", errors.Trace(result.Error)
}
Expand Down
Loading
Loading