Skip to content

Commit

Permalink
Merge branch '3.5' into 3.5-into-main
Browse files Browse the repository at this point in the history
Conflicts:
- agent/agentbootstrap/bootstrap.go
- apiserver/facades/client/modelmanager/modelinfo_test.go
- apiserver/facades/client/modelmanager/modelmanager.go
- apiserver/facades/client/modelmanager/register.go
- apiserver/facades/controller/undertaker/undertaker.go
- apiserver/facades/controller/undertaker/undertaker_test.go
- apiserver/facades/schema.json
- cmd/jujud/agent/agenttest/agent.go
- cmd/jujud/agent/machine/manifolds.go
- database/bootstrap.go
- featuretests/dblog_test.go
- internal/database/bootstrap_test.go
- internal/worker/dbaccessor/manifold.go
- internal/worker/dbaccessor/manifold_test.go
- internal/worker/dbaccessor/package_test.go
  • Loading branch information
jack-w-shaw committed Feb 1, 2024
2 parents 1ca2e5d + 3074a7f commit f17d33b
Show file tree
Hide file tree
Showing 25 changed files with 461 additions and 161 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/merge.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Merge
on:
push:
branches: ['2.9', '3.1', '3.3', '3.4']
branches: ['2.9', '3.1', '3.3', '3.4', '3.5']

jobs:
check-merge:
Expand All @@ -12,7 +12,8 @@ jobs:
2.9: 3.1
3.1: 3.3
3.3: 3.4
3.4: main
3.4: 3.5
3.5: main
steps:
- name: Determine source/target branches
Expand Down
12 changes: 9 additions & 3 deletions agent/agentbootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ type DqliteInitializerFunc func(
ctx stdcontext.Context,
mgr database.BootstrapNodeManager,
logger database.Logger,
preferLoopback bool,
concerns ...database.BootstrapConcern,
) error

Expand Down Expand Up @@ -264,11 +263,18 @@ func (b *AgentBootstrap) Initialize(ctx stdcontext.Context) (_ *state.Controller
machinebootstrap.InsertMachine(agent.BootstrapControllerId),
))
}

// If we're running caas, we need to bind to the loopback address
// and eschew TLS termination.
// This is to prevent dqlite to become all at sea when the controller pod
// is rescheduled. This is only a temporary measure until we have HA
// dqlite for k8s.
isLoopbackPreferred := isCAAS

if err := b.bootstrapDqlite(
ctx,
database.NewNodeManager(b.agentConfig, b.logger, coredatabase.NoopSlowQueryLogger{}),
database.NewNodeManager(b.agentConfig, isLoopbackPreferred, b.logger, coredatabase.NoopSlowQueryLogger{}),
b.logger,
false,
databaseBootstrapConcerns...,
); err != nil {
return nil, errors.Trace(err)
Expand Down
4 changes: 2 additions & 2 deletions agent/agentbootstrap/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -589,11 +589,11 @@ func (e *fakeEnviron) Provider() environs.EnvironProvider {
return e.provider
}

func bootstrapDqliteWithDummyCloudType(ctx context.Context, mgr database.BootstrapNodeManager, logger database.Logger, preferLoopback bool, concerns ...database.BootstrapConcern) error {
func bootstrapDqliteWithDummyCloudType(ctx context.Context, mgr database.BootstrapNodeManager, logger database.Logger, concerns ...database.BootstrapConcern) error {
// The dummy cloud type needs to be inserted before the other operations.
concerns = append([]database.BootstrapConcern{
database.BootstrapControllerInitConcern(database.EmptyInit, jujujujutesting.InsertDummyCloudType),
}, concerns...)

return database.BootstrapDqlite(ctx, mgr, logger, preferLoopback, concerns...)
return database.BootstrapDqlite(ctx, mgr, logger, concerns...)
}
1 change: 0 additions & 1 deletion api/base/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ type ModelInfo struct {
ControllerUUID string
IsController bool
ProviderType string
DefaultBase string
Cloud string
CloudRegion string
CloudCredential string
Expand Down
17 changes: 11 additions & 6 deletions apiserver/facades/client/modelmanager/modelinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package modelmanager_test

import (
"context"
stdcontext "context"
"strings"
"time"
Expand Down Expand Up @@ -289,7 +290,7 @@ func (s *modelInfoSuite) TestModelInfo(c *gc.C) {
s.PatchValue(&commonsecrets.GetProvider, func(string) (provider.SecretBackendProvider, error) {
return mockSecretProvider{}, nil
})
info := s.getModelInfo(c, s.st.model.cfg.UUID())
info := s.getModelInfo(c, s.modelmanager, s.st.model.cfg.UUID())
_true := true
s.assertModelInfo(c, info, s.expectedModelInfo(c, &_true))
s.st.CheckCalls(c, []jujutesting.StubCall{
Expand Down Expand Up @@ -340,22 +341,26 @@ func (s *modelInfoSuite) TestModelInfoWriteAccess(c *gc.C) {
mary := names.NewUserTag("mary@local")
s.authorizer.HasWriteTag = mary
s.setAPIUser(c, mary)
info := s.getModelInfo(c, s.st.model.cfg.UUID())
info := s.getModelInfo(c, s.modelmanager, s.st.model.cfg.UUID())
c.Assert(info.Users, gc.HasLen, 1)
c.Assert(info.Users[0].UserName, gc.Equals, "mary")
c.Assert(info.Machines, gc.HasLen, 2)
}

func (s *modelInfoSuite) TestModelInfoNonOwner(c *gc.C) {
s.setAPIUser(c, names.NewUserTag("charlotte@local"))
info := s.getModelInfo(c, s.st.model.cfg.UUID())
info := s.getModelInfo(c, s.modelmanager, s.st.model.cfg.UUID())
c.Assert(info.Users, gc.HasLen, 1)
c.Assert(info.Users[0].UserName, gc.Equals, "charlotte")
c.Assert(info.Machines, gc.HasLen, 0)
}

func (s *modelInfoSuite) getModelInfo(c *gc.C, modelUUID string) params.ModelInfo {
results, err := s.modelmanager.ModelInfo(stdcontext.Background(), params.Entities{
type modelInfo interface {
ModelInfo(context.Context, params.Entities) (params.ModelInfoResults, error)
}

func (s *modelInfoSuite) getModelInfo(c *gc.C, modelInfo modelInfo, modelUUID string) params.ModelInfo {
results, err := modelInfo.ModelInfo(context.Background(), params.Entities{
Entities: []params.Entity{{
names.NewModelTag(modelUUID).String(),
}},
Expand Down Expand Up @@ -595,7 +600,7 @@ func (s *modelInfoSuite) assertSuccessWithMissingData(c *gc.C, test incompleteMo
func (s *modelInfoSuite) assertSuccess(c *gc.C, modelUUID string, desiredLife state.Life, expectedLife life.Value) {
s.st.model.life = desiredLife
// should get no errors
info := s.getModelInfo(c, modelUUID)
info := s.getModelInfo(c, s.modelmanager, modelUUID)
c.Assert(info.UUID, gc.Equals, modelUUID)
c.Assert(info.Life, gc.Equals, expectedLife)
}
Expand Down
110 changes: 57 additions & 53 deletions apiserver/facades/client/modelmanager/modelmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -707,69 +707,73 @@ func (m *ModelManagerAPI) ListModelSummaries(ctx context.Context, req params.Mod
}

for _, mi := range modelInfos {
summary := &params.ModelSummary{
Name: mi.Name,
UUID: mi.UUID,
Type: string(mi.Type),
OwnerTag: names.NewUserTag(mi.Owner).String(),
ControllerUUID: mi.ControllerUUID,
IsController: mi.IsController,
Life: life.Value(mi.Life.String()),

CloudTag: mi.CloudTag,
CloudRegion: mi.CloudRegion,

CloudCredentialTag: mi.CloudCredentialTag,

SLA: &params.ModelSLAInfo{
Level: mi.SLALevel,
Owner: mi.Owner,
},
summary := m.makeModelSummary(mi)
result.Results = append(result.Results, params.ModelSummaryResult{Result: summary})
}
return result, nil

ProviderType: mi.ProviderType,
AgentVersion: mi.AgentVersion,
}

Status: common.EntityStatusFromState(mi.Status),
Counts: []params.ModelEntityCount{},
UserLastConnection: mi.UserLastConnection,
}
func (m *ModelManagerAPI) makeModelSummary(mi state.ModelSummary) *params.ModelSummary {
summary := &params.ModelSummary{
Name: mi.Name,
UUID: mi.UUID,
Type: string(mi.Type),
OwnerTag: names.NewUserTag(mi.Owner).String(),
ControllerUUID: mi.ControllerUUID,
IsController: mi.IsController,
Life: life.Value(mi.Life.String()),

if mi.MachineCount > 0 {
summary.Counts = append(summary.Counts, params.ModelEntityCount{params.Machines, mi.MachineCount})
}
CloudTag: mi.CloudTag,
CloudRegion: mi.CloudRegion,

if mi.CoreCount > 0 {
summary.Counts = append(summary.Counts, params.ModelEntityCount{params.Cores, mi.CoreCount})
}
CloudCredentialTag: mi.CloudCredentialTag,

if mi.UnitCount > 0 {
summary.Counts = append(summary.Counts, params.ModelEntityCount{params.Units, mi.UnitCount})
}
SLA: &params.ModelSLAInfo{
Level: mi.SLALevel,
Owner: mi.Owner,
},

access, err := common.StateToParamsUserAccessPermission(mi.Access)
if err == nil {
summary.UserAccess = access
}
if mi.Migration != nil {
migration := mi.Migration
startTime := migration.StartTime()
endTime := new(time.Time)
*endTime = migration.EndTime()
var zero time.Time
if *endTime == zero {
endTime = nil
}
ProviderType: mi.ProviderType,
AgentVersion: mi.AgentVersion,

summary.Migration = &params.ModelMigrationStatus{
Status: migration.StatusMessage(),
Start: &startTime,
End: endTime,
}
Status: common.EntityStatusFromState(mi.Status),
Counts: []params.ModelEntityCount{},
UserLastConnection: mi.UserLastConnection,
}
if mi.MachineCount > 0 {
summary.Counts = append(summary.Counts, params.ModelEntityCount{params.Machines, mi.MachineCount})
}

if mi.CoreCount > 0 {
summary.Counts = append(summary.Counts, params.ModelEntityCount{params.Cores, mi.CoreCount})
}

if mi.UnitCount > 0 {
summary.Counts = append(summary.Counts, params.ModelEntityCount{params.Units, mi.UnitCount})
}

access, err := common.StateToParamsUserAccessPermission(mi.Access)
if err == nil {
summary.UserAccess = access
}
if mi.Migration != nil {
migration := mi.Migration
startTime := migration.StartTime()
endTime := new(time.Time)
*endTime = migration.EndTime()
var zero time.Time
if *endTime == zero {
endTime = nil
}

result.Results = append(result.Results, params.ModelSummaryResult{Result: summary})
summary.Migration = &params.ModelMigrationStatus{
Status: migration.StatusMessage(),
Start: &startTime,
End: endTime,
}
}
return result, nil
return summary
}

// fillInStatusBasedOnCloudCredentialValidity fills in the Status on every model (if credential is invalid).
Expand Down
2 changes: 1 addition & 1 deletion apiserver/facades/controller/machineundertaker/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
// Backend defines the methods the machine undertaker needs from
// state.State.
type Backend interface {
// AllRemovedMachines returns all of the machines which have been
// AllMachineRemovals returns all of the machines which have been
// marked for removal.
AllMachineRemovals() ([]string, error)

Expand Down
17 changes: 14 additions & 3 deletions apiserver/facades/controller/undertaker/undertaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,30 @@ func (u *UndertakerAPI) ProcessDyingModel(ctx context.Context) error {

// RemoveModel removes any records of this model from Juju.
func (u *UndertakerAPI) RemoveModel(ctx context.Context) error {
if err := u.removeModelSecrets(ctx); err != nil {
return errors.Annotate(err, "removing model secrets")
}
return u.st.RemoveDyingModel()
}

func (u *UndertakerAPI) removeModelSecrets(ctx context.Context) error {
secretBackendCfg, err := u.secretBackendConfigGetter(ctx)
if errors.Is(err, errors.NotFound) {
// If backends or settings are missing, then no secrets to remove.
return nil
}
if err != nil {
return errors.Annotate(err, "getting secrets backends config")
}
for _, cfg := range secretBackendCfg.Configs {
if err := u.removeModelSecrets(&cfg); err != nil {
if err := u.removeModelSecretsForBackend(&cfg); err != nil {
return errors.Annotatef(err, "cleaning model from inactive secrets provider %q", cfg.BackendType)
}
}
return u.st.RemoveDyingModel()
return nil
}

func (u *UndertakerAPI) removeModelSecrets(cfg *provider.ModelBackendConfig) error {
func (u *UndertakerAPI) removeModelSecretsForBackend(cfg *provider.ModelBackendConfig) error {
p, err := GetProvider(cfg.BackendType)
if err != nil {
return errors.Trace(err)
Expand Down
Loading

0 comments on commit f17d33b

Please sign in to comment.