Skip to content

Commit

Permalink
Add caas operator presence, and status fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
wallyworld committed Feb 9, 2018
1 parent d7d2acc commit 02da47a
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 53 deletions.
33 changes: 17 additions & 16 deletions apiserver/common/modelstatus.go
Expand Up @@ -93,28 +93,29 @@ func (c *ModelStatusAPI) modelStatus(tag string) (params.ModelStatus, error) {
return status, errors.Trace(err)
}

volumes, err := st.AllVolumes()
if err != nil {
return status, errors.Trace(err)
}
modelVolumes := ModelVolumeInfo(volumes)

filesystems, err := st.AllFilesystems()
if err != nil {
return status, errors.Trace(err)
}
modelFilesystems := ModelFilesystemInfo(filesystems)

return params.ModelStatus{
result := params.ModelStatus{
ModelTag: tag,
OwnerTag: model.Owner().String(),
Life: params.Life(model.Life().String()),
HostedMachineCount: len(hostedMachines),
ApplicationCount: len(applications),
Machines: modelMachines,
Volumes: modelVolumes,
Filesystems: modelFilesystems,
}, nil
}

if model.Type() == state.ModelTypeIAAS {
volumes, err := st.AllVolumes()
if err != nil {
return status, errors.Trace(err)
}
result.Volumes = ModelVolumeInfo(volumes)

filesystems, err := st.AllFilesystems()
if err != nil {
return status, errors.Trace(err)
}
result.Filesystems = ModelFilesystemInfo(filesystems)
}
return result, nil
}

// ModelFilesystemInfo returns information about filesystems in the model.
Expand Down
49 changes: 49 additions & 0 deletions apiserver/common/modelstatus_test.go
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/juju/juju/constraints"
"github.com/juju/juju/environs"
"github.com/juju/juju/environs/config"
"github.com/juju/juju/feature"
"github.com/juju/juju/instance"
"github.com/juju/juju/provider/dummy"
"github.com/juju/juju/state"
Expand Down Expand Up @@ -218,6 +219,54 @@ func (s *modelStatusSuite) TestModelStatus(c *gc.C) {
})
}

func (s *modelStatusSuite) TestModelStatusCAAS(c *gc.C) {
s.SetFeatureFlags(feature.CAAS)
otherModelOwner := s.Factory.MakeModelUser(c, nil)
otherSt := s.Factory.MakeModel(c, &factory.ModelParams{
Name: "caas-model",
Type: state.ModelTypeCAAS, CloudRegion: "<none>",
Owner: otherModelOwner.UserTag,
ConfigAttrs: testing.Attrs{
"controller": false,
},
StorageProviderRegistry: factory.NilStorageProviderRegistry{}})
defer otherSt.Close()

otherFactory := factory.NewFactory(otherSt)
otherFactory.MakeApplication(c, &factory.ApplicationParams{
Charm: otherFactory.MakeCharm(c, nil),
})

otherModel, err := otherSt.Model()
c.Assert(err, jc.ErrorIsNil)

controllerModelTag := s.IAASModel.ModelTag().String()
hostedModelTag := otherModel.ModelTag().String()

req := params.Entities{
Entities: []params.Entity{{Tag: controllerModelTag}, {Tag: hostedModelTag}},
}
results, err := s.controller.ModelStatus(req)
c.Assert(err, jc.ErrorIsNil)

c.Assert(results.Results, jc.DeepEquals, []params.ModelStatus{
params.ModelStatus{
ModelTag: controllerModelTag,
HostedMachineCount: 0,
ApplicationCount: 0,
OwnerTag: s.Owner.String(),
Life: params.Alive,
},
params.ModelStatus{
ModelTag: hostedModelTag,
HostedMachineCount: 0,
ApplicationCount: 1,
OwnerTag: otherModelOwner.UserTag.String(),
Life: params.Alive,
},
})
}

func (s *modelStatusSuite) TestModelStatusRunsForAllModels(c *gc.C) {
req := params.Entities{
Entities: []params.Entity{
Expand Down
35 changes: 20 additions & 15 deletions apiserver/facades/controller/caasunitprovisioner/provisioner.go
Expand Up @@ -339,28 +339,36 @@ func (a *Facade) updateUnitsFromCloud(app Application, units []params.Applicatio
unitUpdate.Deletes = append(unitUpdate.Deletes, u.DestroyOperation())
}

unitUpdateProperties := func(unitParams params.ApplicationUnitParams) state.UnitUpdateProperties {
return state.UnitUpdateProperties{
unitUpdateProperties := func(unitParams params.ApplicationUnitParams, includeStatus bool) state.UnitUpdateProperties {
props := state.UnitUpdateProperties{
ProviderId: unitParams.ProviderId,
Address: unitParams.Address,
Ports: unitParams.Ports,
Status: &status.StatusInfo{
}
if includeStatus {
props.Status = &status.StatusInfo{
Status: status.Status(unitParams.Status),
Message: unitParams.Info,
Data: unitParams.Data,
},
}
}
return props
}

shouldUpdate := func(u Unit, params params.ApplicationUnitParams) (bool, error) {
if u.ProviderId() == "" {
return true, nil
shouldUpdateStatus := func(u Unit, params params.ApplicationUnitParams) (bool, error) {
// The container runtime can spam us with unimportant
// status updates, so ignore any irrelevant ones.
// TODO(caas) - the pods may get bounced but we don't model that yet
// so ignore allocating and running for now.
switch status.Status(params.Status) {
case status.Unknown, status.Allocating, status.Running:
return false, nil
}
existingStatus, err := u.AgentStatus()
if err != nil {
return false, errors.Trace(err)
}
if string(existingStatus.Status) != params.Status ||
if existingStatus.Status.String() != params.Status ||
existingStatus.Message != params.Info ||
len(existingStatus.Data) != len(params.Data) ||
reflect.DeepEqual(existingStatus.Data, params.Data) {
Expand All @@ -380,15 +388,12 @@ func (a *Facade) updateUnitsFromCloud(app Application, units []params.Applicatio
continue
}
// Check to see if any update is needed.
update, err := shouldUpdate(u, unitParams)
updateStatus, err := shouldUpdateStatus(u, unitParams)
if err != nil {
return errors.Trace(err)
}
if !update {
continue
}
unitUpdate.Updates = append(unitUpdate.Updates,
u.UpdateOperation(unitUpdateProperties(unitParams)))
u.UpdateOperation(unitUpdateProperties(unitParams, updateStatus)))
}

// For newly added units in the cloud, either update state units which
Expand All @@ -399,13 +404,13 @@ func (a *Facade) updateUnitsFromCloud(app Application, units []params.Applicatio
if idx < len(unassociatedUnits) {
u := unassociatedUnits[idx]
unitUpdate.Updates = append(unitUpdate.Updates,
u.UpdateOperation(unitUpdateProperties(unitParams)))
u.UpdateOperation(unitUpdateProperties(unitParams, true)))
idx += 1
continue
}

unitUpdate.Adds = append(unitUpdate.Adds,
app.AddOperation(unitUpdateProperties(unitParams)))
app.AddOperation(unitUpdateProperties(unitParams, true)))
}
return app.UpdateUnits(&unitUpdate)
}
Expand Up @@ -204,7 +204,7 @@ func (s *CAASProvisionerSuite) TestUpdateApplicationsUnitsNoTags(c *gc.C) {
{ProviderId: "another-uuid", Address: "another-address", Ports: []string{"another-port"},
Status: "running", Info: "another message"},
{ProviderId: "last-uuid", Address: "last-address", Ports: []string{"last-port"},
Status: "running", Info: "last message"},
Status: "error", Info: "last message"},
}
args := params.UpdateApplicationUnitArgs{
Args: []params.UpdateApplicationUnits{
Expand All @@ -224,13 +224,12 @@ func (s *CAASProvisionerSuite) TestUpdateApplicationsUnitsNoTags(c *gc.C) {
s.st.application.CheckCall(c, 0, "AddOperation", state.UnitUpdateProperties{
ProviderId: "last-uuid",
Address: "last-address", Ports: []string{"last-port"},
Status: &status.StatusInfo{Status: status.Running, Message: "last message"},
Status: &status.StatusInfo{Status: status.Error, Message: "last message"},
})
s.st.application.units[0].(*mockUnit).CheckCallNames(c, "Life", "UpdateOperation")
s.st.application.units[0].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{
ProviderId: "uuid",
Address: "address", Ports: []string{"port"},
Status: &status.StatusInfo{Status: status.Running, Message: "message"},
})
s.st.application.units[1].(*mockUnit).CheckCallNames(c, "Life", "UpdateOperation")
s.st.application.units[1].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{
Expand All @@ -252,7 +251,7 @@ func (s *CAASProvisionerSuite) TestUpdateApplicationsUnitsWithTags(c *gc.C) {
{ProviderId: "uuid", UnitTag: "unit-gitlab-0", Address: "address", Ports: []string{"port"},
Status: "running", Info: "message"},
{ProviderId: "another-uuid", UnitTag: "unit-gitlab-1", Address: "another-address", Ports: []string{"another-port"},
Status: "running", Info: "another message"},
Status: "error", Info: "another message"},
}
args := params.UpdateApplicationUnitArgs{
Args: []params.UpdateApplicationUnits{
Expand All @@ -272,13 +271,12 @@ func (s *CAASProvisionerSuite) TestUpdateApplicationsUnitsWithTags(c *gc.C) {
s.st.application.units[0].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{
ProviderId: "uuid",
Address: "address", Ports: []string{"port"},
Status: &status.StatusInfo{Status: status.Running, Message: "message"},
})
s.st.application.units[1].(*mockUnit).CheckCallNames(c, "Life", "UpdateOperation")
s.st.application.units[1].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{
ProviderId: "another-uuid",
Address: "another-address", Ports: []string{"another-port"},
Status: &status.StatusInfo{Status: status.Running, Message: "another message"},
Status: &status.StatusInfo{Status: status.Error, Message: "another message"},
})
s.st.application.units[2].(*mockUnit).CheckCallNames(c, "Life")
}
15 changes: 7 additions & 8 deletions cmd/juju/status/output_tabular.go
Expand Up @@ -24,6 +24,8 @@ import (
"github.com/juju/juju/status"
)

const caasModelType = "caas"

// FormatTabular writes a tabular summary of machines, applications, and
// units. Any subordinate items are indented by two spaces beneath
// their superior.
Expand All @@ -38,7 +40,7 @@ func FormatTabular(writer io.Writer, forceColor bool, value interface{}) error {
}

maxVersionWidth := iaasMaxVersionWidth
if fs.Model.Type == "caas" {
if fs.Model.Type == caasModelType {
maxVersionWidth = caasMaxVersionWidth
}
truncatedWidth := maxVersionWidth - len(ellipsis)
Expand Down Expand Up @@ -112,7 +114,7 @@ func FormatTabular(writer io.Writer, forceColor bool, value interface{}) error {
app := fs.Applications[appName]
version := app.Version
// CAAS versions may have repo prefix we don't care about.
if fs.Model.Type == "caas" {
if fs.Model.Type == caasModelType {
parts := strings.Split(version, "/")
if len(parts) == 2 {
version = parts[1]
Expand Down Expand Up @@ -149,8 +151,6 @@ func FormatTabular(writer io.Writer, forceColor bool, value interface{}) error {
}
}

const caasModelType = "caas"

pUnit := func(name string, u unitStatus, level int) {
message := u.WorkloadStatusInfo.Message
agentDoing := agentDoing(u.JujuStatusInfo)
Expand All @@ -161,17 +161,16 @@ func FormatTabular(writer io.Writer, forceColor bool, value interface{}) error {
name += "*"
}
w.Print(indent("", level*2, name))
w.PrintStatus(u.WorkloadStatusInfo.Current)
w.PrintStatus(u.JujuStatusInfo.Current)
if fs.Model.Type == caasModelType {
w.PrintStatus(u.JujuStatusInfo.Current)
p(
u.Address,
strings.Join(u.OpenedPorts, ","),
message,
)
return
}
w.PrintStatus(u.WorkloadStatusInfo.Current)
w.PrintStatus(u.JujuStatusInfo.Current)
p(
u.Machine,
u.PublicAddress,
Expand All @@ -181,7 +180,7 @@ func FormatTabular(writer io.Writer, forceColor bool, value interface{}) error {
}

if fs.Model.Type == caasModelType {
outputHeaders("Unit", "Status", "Address", "Ports", "Message")
outputHeaders("Unit", "Workload", "Agent", "Address", "Ports", "Message")
} else {
outputHeaders("Unit", "Workload", "Agent", "Machine", "Public address", "Ports", "Message")
}
Expand Down
12 changes: 9 additions & 3 deletions cmd/juju/status/status_test.go
Expand Up @@ -4186,13 +4186,19 @@ func (s *StatusSuite) TestFormatTabularCAASModel(c *gc.C) {
JujuStatusInfo: statusInfoContents{
Current: status.Allocating,
},
WorkloadStatusInfo: statusInfoContents{
Current: status.Active,
},
},
"foo/1": {
Address: "10.0.0.1",
OpenedPorts: []string{"80/TCP"},
JujuStatusInfo: statusInfoContents{
Current: status.Running,
},
WorkloadStatusInfo: statusInfoContents{
Current: status.Active,
},
},
},
},
Expand All @@ -4208,9 +4214,9 @@ Model Controller Cloud/Region Version
App Version Status Scale Charm Store Rev OS Notes
foo 1/2 0
Unit Status Address Ports Message
foo/0 allocating
foo/1 running 10.0.0.1 80/TCP
Unit Workload Agent Address Ports Message
foo/0 active allocating
foo/1 active running 10.0.0.1 80/TCP
`[1:])
}

Expand Down

0 comments on commit 02da47a

Please sign in to comment.