Skip to content

Commit

Permalink
fix: converges agent version states
Browse files Browse the repository at this point in the history
The controller state is removed, and the agent version is now queried
from the model-backed state.
  • Loading branch information
manadart committed Nov 25, 2024
1 parent 8ef57ae commit 4de5885
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 171 deletions.
41 changes: 39 additions & 2 deletions domain/modelagent/state/modelstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ package state

import (
"context"
"database/sql"
"fmt"

"github.com/canonical/sqlair"
"github.com/juju/version/v2"

"github.com/juju/juju/core/database"
"github.com/juju/juju/core/machine"
"github.com/juju/juju/core/model"
"github.com/juju/juju/domain"
applicationerrors "github.com/juju/juju/domain/application/errors"
machineerrors "github.com/juju/juju/domain/machine/errors"
modelerrors "github.com/juju/juju/domain/model/errors"
"github.com/juju/juju/internal/errors"
)

Expand All @@ -28,8 +32,8 @@ func NewModelState(factory database.TxnRunnerFactory) *ModelState {
}
}

// CheckMachineExists check to see if the given machine exists in the model. If
// the machine does not exist an error satisfying
// CheckMachineExists check to see if the given machine exists in the model.
// If the machine does not exist an error satisfying
// [machineerrors.MachineNotFound] is returned.
func (m *ModelState) CheckMachineExists(
ctx context.Context,
Expand Down Expand Up @@ -161,3 +165,36 @@ WHERE name = $unitName.name

return err
}

func (st *ModelState) GetTargetAgentVersion(ctx context.Context) (version.Number, error) {
db, err := st.DB()
if err != nil {
return version.Zero, errors.Capture(err)
}

res := dbAgentVersion{}

stmt, err := st.Prepare("SELECT &dbAgentVersion.target_version FROM agent_version", res)
if err != nil {
return version.Zero, fmt.Errorf("preparing agent version query: %w", err)
}

err = db.Txn(ctx, func(ctx context.Context, tx *sqlair.TX) error {
err := tx.Query(ctx, stmt).Get(&res)
if errors.Is(err, sql.ErrNoRows) {
return modelerrors.AgentVersionNotFound
} else if err != nil {
return fmt.Errorf("getting agent version: %w", err)
}
return nil
})
if err != nil {
return version.Zero, errors.Capture(err)
}

vers, err := version.Parse(res.TargetAgentVersion)
if err != nil {
return version.Zero, fmt.Errorf("parsing agent version: %w", err)
}
return vers, nil
}
54 changes: 54 additions & 0 deletions domain/modelagent/state/modelstate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ package state
import (
"context"

"github.com/canonical/sqlair"
jc "github.com/juju/testing/checkers"
"github.com/juju/version/v2"
gc "gopkg.in/check.v1"

"github.com/juju/juju/core/machine"
"github.com/juju/juju/domain"
applicationerrors "github.com/juju/juju/domain/application/errors"
machineerrors "github.com/juju/juju/domain/machine/errors"
modelerrors "github.com/juju/juju/domain/model/errors"
schematesting "github.com/juju/juju/domain/schema/testing"
)

Expand Down Expand Up @@ -40,3 +44,53 @@ func (s *modelStateSuite) TestCheckUnitDoesNotExist(c *gc.C) {
)
c.Check(err, jc.ErrorIs, applicationerrors.UnitNotFound)
}

// TestGetModelAgentVersionSuccess tests that State.GetModelAgentVersion is
// correct in the expected case when the model exists.
func (s *modelStateSuite) TestGetModelAgentVersionSuccess(c *gc.C) {
expectedVersion, err := version.Parse("4.21.54")
c.Assert(err, jc.ErrorIsNil)

st := NewModelState(s.TxnRunnerFactory())
s.setAgentVersion(c, expectedVersion.String())

obtainedVersion, err := st.GetTargetAgentVersion(context.Background())
c.Check(err, jc.ErrorIsNil)
c.Check(obtainedVersion, jc.DeepEquals, expectedVersion)
}

// TestGetModelAgentVersionModelNotFound tests that State.GetModelAgentVersion
// returns modelerrors.NotFound when the model does not exist in the DB.
func (s *modelStateSuite) TestGetModelAgentVersionModelNotFound(c *gc.C) {
st := NewModelState(s.TxnRunnerFactory())

_, err := st.GetTargetAgentVersion(context.Background())
c.Check(err, jc.ErrorIs, modelerrors.AgentVersionNotFound)
}

// TestGetModelAgentVersionCantParseVersion tests that State.GetModelAgentVersion
// returns an appropriate error when the agent version in the DB is invalid.
func (s *modelStateSuite) TestGetModelAgentVersionCantParseVersion(c *gc.C) {
s.setAgentVersion(c, "invalid-version")

st := NewModelState(s.TxnRunnerFactory())
_, err := st.GetTargetAgentVersion(context.Background())
c.Check(err, gc.ErrorMatches, `parsing agent version: invalid version "invalid-version".*`)
}

// Set the agent version for the given model in the DB.
func (s *modelStateSuite) setAgentVersion(c *gc.C, vers string) {
db, err := domain.NewStateBase(s.TxnRunnerFactory()).DB()
c.Assert(err, jc.ErrorIsNil)

q := "INSERT INTO agent_version (target_version) values ($M.target_version)"

args := sqlair.M{"target_version": vers}
stmt, err := sqlair.Prepare(q, args)
c.Assert(err, jc.ErrorIsNil)

err = db.Txn(context.Background(), func(ctx context.Context, tx *sqlair.TX) error {
return tx.Query(ctx, stmt, args).Run()
})
c.Assert(err, jc.ErrorIsNil)
}
77 changes: 0 additions & 77 deletions domain/modelagent/state/state.go

This file was deleted.

91 changes: 0 additions & 91 deletions domain/modelagent/state/state_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion domain/modelagent/state/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package state

// dbAgentVersion represents the target agent version from the model table.
type dbAgentVersion struct {
TargetAgentVersion string `db:"target_agent_version"`
TargetAgentVersion string `db:"target_version"`
}

// machineName represents the single column of a machine that is the machines
Expand Down

0 comments on commit 4de5885

Please sign in to comment.