Skip to content

Commit

Permalink
Check LXD version >= 5.2 in model upgrade and mode migrate process;
Browse files Browse the repository at this point in the history
  • Loading branch information
ycliuhw committed Aug 2, 2022
1 parent b670f4f commit d159efa
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 40 deletions.
1 change: 1 addition & 0 deletions apiserver/facades/client/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,7 @@ var runMigrationPrechecks = func(
backend,
targetControllerVersion,
modelPresence, controllerPresence,
cloudspec.MakeCloudSpecGetterForModel(st),
); err != nil {
return errors.Annotate(err, "source prechecks failed")
}
Expand Down
3 changes: 3 additions & 0 deletions apiserver/facades/client/modelupgrader/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/juju/names/v4"

"github.com/juju/juju/apiserver/common"
"github.com/juju/juju/apiserver/common/cloudspec"
apiservererrors "github.com/juju/juju/apiserver/errors"
"github.com/juju/juju/apiserver/facade"
"github.com/juju/juju/docker/registry"
Expand Down Expand Up @@ -46,6 +47,7 @@ func newFacadeV1(ctx facade.Context) (*ModelUpgraderAPI, error) {

urlGetter := common.NewToolsURLGetter(modelUUID, systemState)
toolsFinder := common.NewToolsFinder(configGetter, st, urlGetter, newEnviron)
environscloudspecGetter := cloudspec.MakeCloudSpecGetterForModel(st)

// Since we know this is a user tag (because AuthClient is true),
// we just do the type assertion to the UserTag.
Expand All @@ -63,5 +65,6 @@ func newFacadeV1(ctx facade.Context) (*ModelUpgraderAPI, error) {
auth,
context.CallContext(st),
registry.New,
environscloudspecGetter,
)
}
35 changes: 22 additions & 13 deletions apiserver/facades/client/modelupgrader/upgrader.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/juju/juju/docker/registry"
"github.com/juju/juju/environs"
"github.com/juju/juju/environs/bootstrap"
environscloudspec "github.com/juju/juju/environs/cloudspec"
"github.com/juju/juju/environs/config"
"github.com/juju/juju/environs/context"
"github.com/juju/juju/rpc/params"
Expand All @@ -39,7 +40,8 @@ type ModelUpgraderAPI struct {
callContext context.ProviderCallContext
newEnviron common.NewEnvironFunc

registryAPIFunc func(repoDetails docker.ImageRepoDetails) (registry.Registry, error)
registryAPIFunc func(repoDetails docker.ImageRepoDetails) (registry.Registry, error)
environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error)
}

// NewModelUpgraderAPI creates a new api server endpoint for managing
Expand All @@ -53,6 +55,7 @@ func NewModelUpgraderAPI(
authorizer facade.Authorizer,
callCtx context.ProviderCallContext,
registryAPIFunc func(docker.ImageRepoDetails) (registry.Registry, error),
environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error),
) (*ModelUpgraderAPI, error) {
if !authorizer.AuthClient() {
return nil, apiservererrors.ErrPerm
Expand All @@ -67,15 +70,16 @@ func NewModelUpgraderAPI(
}

return &ModelUpgraderAPI{
statePool: stPool,
check: blockChecker,
authorizer: authorizer,
toolsFinder: toolsFinder,
apiUser: apiUser,
isAdmin: isAdmin,
callContext: callCtx,
newEnviron: newEnviron,
registryAPIFunc: registryAPIFunc,
statePool: stPool,
check: blockChecker,
authorizer: authorizer,
toolsFinder: toolsFinder,
apiUser: apiUser,
isAdmin: isAdmin,
callContext: callCtx,
newEnviron: newEnviron,
registryAPIFunc: registryAPIFunc,
environscloudspecGetter: environscloudspecGetter,
}, nil
}

Expand Down Expand Up @@ -277,9 +281,14 @@ func (m *ModelUpgraderAPI) validateModelUpgrade(
}
}()

cloudspec, err := m.environscloudspecGetter(modelTag)
if err != nil {
return errors.Trace(err)
}

isControllerModel := model.IsControllerModel()
if !isControllerModel {
validators := upgradevalidation.ValidatorsForModelUpgrade(force, targetVersion)
validators := upgradevalidation.ValidatorsForModelUpgrade(force, targetVersion, cloudspec)
checker := upgradevalidation.NewModelUpgradeCheck(modelTag.Id(), m.statePool, st, model, validators...)
blockers, err = checker.Validate()
if err != nil {
Expand All @@ -290,7 +299,7 @@ func (m *ModelUpgraderAPI) validateModelUpgrade(

checker := upgradevalidation.NewModelUpgradeCheck(
modelTag.Id(), m.statePool, st, model,
upgradevalidation.ValidatorsForControllerUpgrade(true, targetVersion)...,
upgradevalidation.ValidatorsForControllerUpgrade(true, targetVersion, cloudspec)...,
)
blockers, err = checker.Validate()
if err != nil {
Expand All @@ -301,7 +310,7 @@ func (m *ModelUpgraderAPI) validateModelUpgrade(
if err != nil {
return errors.Trace(err)
}
validators := upgradevalidation.ValidatorsForControllerUpgrade(false, targetVersion)
validators := upgradevalidation.ValidatorsForControllerUpgrade(false, targetVersion, cloudspec)
for _, modelUUID := range modelUUIDs {
if modelUUID == modelTag.Id() {
// We have done checks for controller model above already.
Expand Down
68 changes: 66 additions & 2 deletions apiserver/facades/client/modelupgrader/upgrader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package modelupgrader_test

import (
"net/http"

"github.com/golang/mock/gomock"
"github.com/juju/errors"
"github.com/juju/names/v4"
Expand All @@ -24,13 +26,16 @@ import (
"github.com/juju/juju/docker/registry/image"
registrymocks "github.com/juju/juju/docker/registry/mocks"
"github.com/juju/juju/environs"
environscloudspec "github.com/juju/juju/environs/cloudspec"
"github.com/juju/juju/environs/context"
envtools "github.com/juju/juju/environs/tools"
"github.com/juju/juju/provider/lxd"
"github.com/juju/juju/rpc/params"
"github.com/juju/juju/state"
coretesting "github.com/juju/juju/testing"
coretools "github.com/juju/juju/tools"
"github.com/juju/juju/upgrades/upgradevalidation"
upgradevalidationmocks "github.com/juju/juju/upgrades/upgradevalidation/mocks"
)

type modelUpgradeSuite struct {
Expand All @@ -45,6 +50,7 @@ type modelUpgradeSuite struct {
bootstrapEnviron *mocks.MockBootstrapEnviron
blockChecker *mocks.MockBlockCheckerInterface
registryProvider *registrymocks.MockRegistry
cloudSpec environscloudspec.CloudSpec
}

var _ = gc.Suite(&modelUpgradeSuite{})
Expand All @@ -60,6 +66,7 @@ func (s *modelUpgradeSuite) SetUpTest(c *gc.C) {
}

s.callContext = context.NewEmptyCloudCallContext()
s.cloudSpec = environscloudspec.CloudSpec{Type: "lxd"}
}

func (s *modelUpgradeSuite) getModelUpgraderAPI(c *gc.C) (*gomock.Controller, *modelupgrader.ModelUpgraderAPI) {
Expand All @@ -81,6 +88,9 @@ func (s *modelUpgradeSuite) getModelUpgraderAPI(c *gc.C) (*gomock.Controller, *m
func(docker.ImageRepoDetails) (registry.Registry, error) {
return s.registryProvider, nil
},
func(names.ModelTag) (environscloudspec.CloudSpec, error) {
return s.cloudSpec, nil
},
)
c.Assert(err, jc.ErrorIsNil)
return ctrl, api
Expand Down Expand Up @@ -133,6 +143,14 @@ func (s *modelUpgradeSuite) assertUpgradeModelForControllerModelJuju3(c *gc.C, d
3: version.MustParse("2.9.1"),
})

server := upgradevalidationmocks.NewMockServer(ctrl)
serverFactory := upgradevalidationmocks.NewMockServerFactory(ctrl)
s.PatchValue(&upgradevalidation.NewServerFactory,
func(httpClient *http.Client) lxd.ServerFactory {
return serverFactory
},
)

ctrlModelTag := coretesting.ModelTag
model1ModelUUID, err := utils.NewUUID()
c.Assert(err, jc.ErrorIsNil)
Expand Down Expand Up @@ -215,6 +233,10 @@ func (s *modelUpgradeSuite) assertUpgradeModelForControllerModelJuju3(c *gc.C, d
"yakkety",
"zesty",
).Return(nil, nil),
// - check LXD version.
serverFactory.EXPECT().RemoteServer(s.cloudSpec).Return(server, nil),
server.EXPECT().ServerVersion().Return("5.2"),

ctrlState.EXPECT().AllModelUUIDs().Return([]string{ctrlModelTag.Id(), model1ModelUUID.String()}, nil),

// 2. Check other models.
Expand Down Expand Up @@ -251,6 +273,9 @@ func (s *modelUpgradeSuite) assertUpgradeModelForControllerModelJuju3(c *gc.C, d
"yakkety",
"zesty",
).Return(nil, nil),
// - check LXD version.
serverFactory.EXPECT().RemoteServer(s.cloudSpec).Return(server, nil),
server.EXPECT().ServerVersion().Return("5.2"),
}
if !dryRun {
assertions = append(assertions,
Expand Down Expand Up @@ -290,6 +315,14 @@ func (s *modelUpgradeSuite) TestUpgradeModelForControllerModelJuju3Failed(c *gc.
3: version.MustParse("2.9.2"),
})

server := upgradevalidationmocks.NewMockServer(ctrl)
serverFactory := upgradevalidationmocks.NewMockServerFactory(ctrl)
s.PatchValue(&upgradevalidation.NewServerFactory,
func(httpClient *http.Client) lxd.ServerFactory {
return serverFactory
},
)

ctrlModelTag := coretesting.ModelTag
model1ModelUUID, err := utils.NewUUID()
c.Assert(err, jc.ErrorIsNil)
Expand Down Expand Up @@ -372,6 +405,9 @@ func (s *modelUpgradeSuite) TestUpgradeModelForControllerModelJuju3Failed(c *gc.
"yakkety",
"zesty",
).Return(map[string]int{"xenial": 2}, nil),
// - check LXD version.
serverFactory.EXPECT().RemoteServer(s.cloudSpec).Return(server, nil),
server.EXPECT().ServerVersion().Return("5.1"),
ctrlModel.EXPECT().Owner().Return(names.NewUserTag("admin")),
ctrlModel.EXPECT().Name().Return("controller"),

Expand Down Expand Up @@ -415,6 +451,9 @@ func (s *modelUpgradeSuite) TestUpgradeModelForControllerModelJuju3Failed(c *gc.
"saucy": 11, "trusty": 12, "utopic": 13, "vivid": 14, "wily": 15,
"xenial": 16, "yakkety": 17, "zesty": 18,
}, nil),
// - check LXD version.
serverFactory.EXPECT().RemoteServer(s.cloudSpec).Return(server, nil),
server.EXPECT().ServerVersion().Return("5.1"),
model1.EXPECT().Owner().Return(names.NewUserTag("admin")),
model1.EXPECT().Name().Return("model-1"),
)
Expand All @@ -433,11 +472,13 @@ cannot upgrade to "3.9.99" due to issues with these models:
- mongo version has to be "4.4" at least, but current version is "4.3"
- the model hosts deprecated windows machine(s): win10(1) win7(2)
- the model hosts deprecated ubuntu machine(s): xenial(2)
- LXD version has to be "5.2.0" at least, but current version is "5.1.0"
"admin/model-1":
- current model ("2.9.0") has to be upgraded to "2.9.2" at least
- model is under "exporting" mode, upgrade blocked
- the model hosts deprecated windows machine(s): win10(1) win7(3)
- the model hosts deprecated ubuntu machine(s): artful(1) cosmic(2) disco(3) eoan(4) groovy(5) hirsute(6) impish(7) precise(8) quantal(9) raring(10) saucy(11) trusty(12) utopic(13) vivid(14) wily(15) xenial(16) yakkety(17) zesty(18)`[1:])
- the model hosts deprecated ubuntu machine(s): artful(1) cosmic(2) disco(3) eoan(4) groovy(5) hirsute(6) impish(7) precise(8) quantal(9) raring(10) saucy(11) trusty(12) utopic(13) vivid(14) wily(15) xenial(16) yakkety(17) zesty(18)
- LXD version has to be "5.2.0" at least, but current version is "5.1.0"`[1:])
}

func (s *modelUpgradeSuite) assertUpgradeModelJuju3(c *gc.C, dryRun bool) {
Expand All @@ -448,6 +489,14 @@ func (s *modelUpgradeSuite) assertUpgradeModelJuju3(c *gc.C, dryRun bool) {
3: version.MustParse("2.9.1"),
})

server := upgradevalidationmocks.NewMockServer(ctrl)
serverFactory := upgradevalidationmocks.NewMockServerFactory(ctrl)
s.PatchValue(&upgradevalidation.NewServerFactory,
func(httpClient *http.Client) lxd.ServerFactory {
return serverFactory
},
)

modelUUID := coretesting.ModelTag.Id()
model := mocks.NewMockModel(ctrl)
st := mocks.NewMockState(ctrl)
Expand Down Expand Up @@ -504,6 +553,9 @@ func (s *modelUpgradeSuite) assertUpgradeModelJuju3(c *gc.C, dryRun bool) {
"yakkety",
"zesty",
).Return(nil, nil),
// - check LXD version.
serverFactory.EXPECT().RemoteServer(s.cloudSpec).Return(server, nil),
server.EXPECT().ServerVersion().Return("5.2"),
}
if !dryRun {
assertions = append(assertions,
Expand Down Expand Up @@ -543,6 +595,14 @@ func (s *modelUpgradeSuite) TestUpgradeModelJuju3Failed(c *gc.C) {
3: version.MustParse("2.9.1"),
})

server := upgradevalidationmocks.NewMockServer(ctrl)
serverFactory := upgradevalidationmocks.NewMockServerFactory(ctrl)
s.PatchValue(&upgradevalidation.NewServerFactory,
func(httpClient *http.Client) lxd.ServerFactory {
return serverFactory
},
)

modelUUID := coretesting.ModelTag.Id()
model := mocks.NewMockModel(ctrl)
st := mocks.NewMockState(ctrl)
Expand Down Expand Up @@ -603,6 +663,9 @@ func (s *modelUpgradeSuite) TestUpgradeModelJuju3Failed(c *gc.C) {
"saucy": 11, "trusty": 12, "utopic": 13, "vivid": 14, "wily": 15,
"xenial": 16, "yakkety": 17, "zesty": 18,
}, nil),
// - check LXD version.
serverFactory.EXPECT().RemoteServer(s.cloudSpec).Return(server, nil),
server.EXPECT().ServerVersion().Return("5.1"),
model.EXPECT().Owner().Return(names.NewUserTag("admin")),
model.EXPECT().Name().Return("model-1"),
)
Expand All @@ -618,7 +681,8 @@ cannot upgrade to "3.9.99" due to issues with these models:
"admin/model-1":
- unexpected upgrade series lock found
- the model hosts deprecated windows machine(s): win10(1) win7(3)
- the model hosts deprecated ubuntu machine(s): artful(1) cosmic(2) disco(3) eoan(4) groovy(5) hirsute(6) impish(7) precise(8) quantal(9) raring(10) saucy(11) trusty(12) utopic(13) vivid(14) wily(15) xenial(16) yakkety(17) zesty(18)`[1:])
- the model hosts deprecated ubuntu machine(s): artful(1) cosmic(2) disco(3) eoan(4) groovy(5) hirsute(6) impish(7) precise(8) quantal(9) raring(10) saucy(11) trusty(12) utopic(13) vivid(14) wily(15) xenial(16) yakkety(17) zesty(18)
- LXD version has to be "5.2.0" at least, but current version is "5.1.0"`[1:])
}

func (s *modelUpgradeSuite) TestAbortCurrentUpgrade(c *gc.C) {
Expand Down
29 changes: 17 additions & 12 deletions apiserver/facades/controller/migrationmaster/facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/juju/juju/apiserver/facade"
coremigration "github.com/juju/juju/core/migration"
coremodel "github.com/juju/juju/core/model"
environscloudspec "github.com/juju/juju/environs/cloudspec"
"github.com/juju/juju/migration"
"github.com/juju/juju/rpc/params"
"github.com/juju/juju/state/watcher"
Expand All @@ -26,12 +27,13 @@ import (
// API implements the API required for the model migration
// master worker.
type API struct {
backend Backend
precheckBackend migration.PrecheckBackend
pool migration.Pool
authorizer facade.Authorizer
resources facade.Resources
presence facade.Presence
backend Backend
precheckBackend migration.PrecheckBackend
pool migration.Pool
authorizer facade.Authorizer
resources facade.Resources
presence facade.Presence
environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error)
}

type APIV1 struct {
Expand All @@ -52,17 +54,19 @@ func NewAPI(
resources facade.Resources,
authorizer facade.Authorizer,
presence facade.Presence,
environscloudspecGetter func(names.ModelTag) (environscloudspec.CloudSpec, error),
) (*API, error) {
if !authorizer.AuthController() {
return nil, apiservererrors.ErrPerm
}
return &API{
backend: backend,
precheckBackend: precheckBackend,
pool: pool,
authorizer: authorizer,
resources: resources,
presence: presence,
backend: backend,
precheckBackend: precheckBackend,
pool: pool,
authorizer: authorizer,
resources: resources,
presence: presence,
environscloudspecGetter: environscloudspecGetter,
}, nil
}

Expand Down Expand Up @@ -186,6 +190,7 @@ func (api *API) Prechecks(arg params.PrechecksArgs) error {
arg.TargetControllerVersion,
api.presence.ModelPresence(model.UUID()),
api.presence.ModelPresence(controllerModel.UUID()),
api.environscloudspecGetter,
)
}

Expand Down
Loading

0 comments on commit d159efa

Please sign in to comment.