Skip to content

Commit

Permalink
Merge pull request #141 from tlm/v5-to-v6
Browse files Browse the repository at this point in the history
V5 to v6
  • Loading branch information
tlm authored Jun 12, 2024
2 parents 8c1d144 + 30f08a4 commit f320c1e
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
45 changes: 43 additions & 2 deletions model.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ type Model interface {
HasStatus
HasStatusHistory

// AgentVersion returns the version currently in use by the model.
AgentVersion() string

Type() string
Cloud() string
CloudRegion() string
Expand Down Expand Up @@ -144,6 +147,9 @@ type Model interface {
// ModelArgs represent the bare minimum information that is needed
// to represent a model.
type ModelArgs struct {
// AgentVersion defines the current version in use by the model.
AgentVersion string

Type string
Owner names.UserTag
Config map[string]interface{}
Expand All @@ -159,7 +165,8 @@ type ModelArgs struct {
// NewModel returns a Model based on the args specified.
func NewModel(args ModelArgs) Model {
m := &model{
Version: 10,
Version: 11,
AgentVersion_: args.AgentVersion,
Type_: args.Type,
Owner_: args.Owner.Id(),
Config_: args.Config,
Expand Down Expand Up @@ -254,6 +261,9 @@ func parentId(machineId string) string {
type model struct {
Version int `yaml:"version"`

// AgentVersion_ defines the agent version in use by the model.
AgentVersion_ string `yaml:"agent-version"`

Type_ string `yaml:"type"`
Owner_ string `yaml:"owner"`
Config_ map[string]interface{} `yaml:"config"`
Expand Down Expand Up @@ -314,6 +324,11 @@ type model struct {
PasswordHash_ string `yaml:"password-hash,omitempty"`
}

// AgentVersion returns the current agent version in use the by the model.
func (m *model) AgentVersion() string {
return m.AgentVersion_
}

func (m *model) Type() string {
return m.Type_
}
Expand Down Expand Up @@ -1092,6 +1107,15 @@ func (m *model) Validate() error {
return errors.NotValidf("missing status")
}

if m.AgentVersion_ != "" {
agentVersion, err := version.Parse(m.AgentVersion_)
if err != nil {
return errors.Annotate(err, "agent version not parsable")
} else if agentVersion == version.Zero {
return errors.NotValidf("agent version cannot be zero")
}
}

validationCtx := newValidationContext()
for _, machine := range m.Machines_.Machines_ {
if err := m.validateMachine(validationCtx, machine); err != nil {
Expand Down Expand Up @@ -1522,6 +1546,7 @@ var modelDeserializationFuncs = map[int]modelDeserializationFunc{
8: newModelImporter(8, schema.FieldMap(modelV8Fields())),
9: newModelImporter(9, schema.FieldMap(modelV9Fields())),
10: newModelImporter(10, schema.FieldMap(modelV10Fields())),
11: newModelImporter(11, schema.FieldMap(modelV11Fields())),
}

func modelV1Fields() (schema.Fields, schema.Defaults) {
Expand Down Expand Up @@ -1635,11 +1660,17 @@ func modelV10Fields() (schema.Fields, schema.Defaults) {
return fields, defaults
}

func modelV11Fields() (schema.Fields, schema.Defaults) {
fields, defaults := modelV10Fields()
fields["agent-version"] = schema.String()
return fields, defaults
}

func newModelFromValid(valid map[string]interface{}, importVersion int) (*model, error) {
// We're always making a version 8 model, no matter what we got on
// the way in.
result := &model{
Version: 10,
Version: 11,
Type_: IAAS,
Owner_: valid["owner"].(string),
Config_: valid["config"].(map[string]interface{}),
Expand Down Expand Up @@ -1903,6 +1934,16 @@ func newModelFromValid(valid map[string]interface{}, importVersion int) (*model,

result.SecretBackendID_ = valid["secret-backend-id"].(string)
}

// When we are importing v11 onwards agent version will be a first class
// citizen on the model. Before this we can attempt to get the value from
// config.
if importVersion >= 11 {
result.AgentVersion_ = valid["agent-version"].(string)
} else if result.Config_ != nil && result.Config_["agent-version"] != nil {
result.AgentVersion_ = result.Config_["agent-version"].(string)
}

return result, nil
}

Expand Down
25 changes: 22 additions & 3 deletions model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ func (s *ModelSerializationSuite) TestParsingYAMLWithMissingModificationStatus(c

func (s *ModelSerializationSuite) testParsingYAMLWithMachine(c *gc.C, machineFn func(Model)) {
args := ModelArgs{
Type: IAAS,
Owner: names.NewUserTag("magic"),
AgentVersion: "3.1.1",
Type: IAAS,
Owner: names.NewUserTag("magic"),
Config: map[string]interface{}{
"name": "awesome",
"uuid": "some-uuid",
Expand Down Expand Up @@ -202,6 +203,7 @@ func (s *ModelSerializationSuite) testParsingYAMLWithMachine(c *gc.C, machineFn
addMinimalApplication(initial)
model := s.exportImport(c, initial)

c.Check(model.AgentVersion(), gc.Equals, "3.1.1")
c.Assert(model.Type(), gc.Equals, IAAS)
c.Assert(model.Owner(), gc.Equals, args.Owner)
c.Assert(model.Tag().Id(), gc.Equals, "some-uuid")
Expand Down Expand Up @@ -1165,7 +1167,7 @@ func (s *ModelSerializationSuite) TestSerializesToLatestVersion(c *gc.C) {
c.Assert(ok, jc.IsTrue)
version, ok := versionValue.(int)
c.Assert(ok, jc.IsTrue)
c.Assert(version, gc.Equals, 10)
c.Assert(version, gc.Equals, 11)
}

func (s *ModelSerializationSuite) TestVersion1Works(c *gc.C) {
Expand Down Expand Up @@ -1634,6 +1636,23 @@ func (s *ModelSerializationSuite) TestRemoteSecretsValidate(c *gc.C) {
c.Assert(err, gc.ErrorMatches, `remote secret\[0\] consumer \(foo\) not valid`)
}

func (s *ModelSerializationSuite) TestAgentVersionPre11Import(c *gc.C) {
initial := s.newModel(ModelArgs{
Config: map[string]any{
"agent-version": "3.3.3",
},
})
data := asStringMap(c, initial)
data["version"] = 10
bytes, err := yaml.Marshal(data)
c.Assert(err, jc.ErrorIsNil)

model, err := Deserialize(bytes)
c.Check(err, jc.ErrorIsNil)

c.Check(model.AgentVersion(), gc.Equals, "3.3.3")
}

// modelV1example was taken from a Juju 2.1 model dump, which is version
// 1, and among other things is missing model status, which version 2 makes
// manditory.
Expand Down

0 comments on commit f320c1e

Please sign in to comment.