Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Change Log

## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
- Added UpToDate condition in ArangoDeployment Status

## [1.0.1](https://github.com/arangodb/kube-arangodb/tree/1.0.1) (2020-03-25)
- Added Customizable Affinity settings for ArangoDB Member Pods
Expand Down
13 changes: 12 additions & 1 deletion pkg/apis/deployment/v1/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ const (
ConditionTypeBootstrapSucceded ConditionType = "BootstrapSucceded"
// ConditionTypeTerminating indicates that the member is terminating but not yet terminated.
ConditionTypeTerminating ConditionType = "Terminating"
// ConditionTypeTerminating indicates that the deployment is up to date.
ConditionTypeUpToDate ConditionType = "UpToDate"
)

// Condition represents one current condition of a deployment or deployment member.
Expand All @@ -79,6 +81,10 @@ type Condition struct {
Message string `json:"message,omitempty"`
}

func (c Condition) IsTrue() bool {
return c.Status == v1.ConditionTrue
}

// ConditionList is a list of conditions.
// Each type is allowed only once.
type ConditionList []Condition
Expand Down Expand Up @@ -116,12 +122,17 @@ func (c Condition) Equal(other Condition) bool {
// IsTrue return true when a condition with given type exists and its status is `True`.
func (list ConditionList) IsTrue(conditionType ConditionType) bool {
c, found := list.Get(conditionType)
return found && c.Status == v1.ConditionTrue
return found && c.IsTrue()
}

// Get a condition by type.
// Returns true if found, false if not found.
func (list ConditionList) Get(conditionType ConditionType) (Condition, bool) {
// Covers nil and empty lists
if len(list) == 0 {
return Condition{}, false
}

for _, x := range list {
if x.Type == conditionType {
return x, true
Expand Down
10 changes: 10 additions & 0 deletions pkg/apis/deployment/v1/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,13 @@ func (d *ArangoDeployment) ForeachServerGroup(cb ServerGroupFunc, status *Deploy
}
return nil
}

// IsUpToDate checks if applied version match current version in spec
func (d ArangoDeployment) IsUpToDate() (bool, error) {
sha, err := d.Spec.Checksum()
if err != nil {
return false, err
}

return sha == d.Status.AppliedVersion && d.Status.Conditions.IsTrue(ConditionTypeUpToDate), nil
}
13 changes: 13 additions & 0 deletions pkg/apis/deployment/v1/deployment_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
package v1

import (
"crypto/sha256"
"encoding/json"
"fmt"
"reflect"

"github.com/arangodb/kube-arangodb/pkg/util"
Expand Down Expand Up @@ -413,3 +416,13 @@ func (s DeploymentSpec) ResetImmutableFields(target *DeploymentSpec) []string {
}
return resetFields
}

// Checksum return checksum of current ArangoDeployment Spec section
func (s DeploymentSpec) Checksum() (string, error) {
data, err := json.Marshal(s)
if err != nil {
return "", err
}

return fmt.Sprintf("%0x", sha256.Sum256(data)), nil
}
3 changes: 3 additions & 0 deletions pkg/apis/deployment/v1/deployment_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ type DeploymentStatus struct {
// Reason contains a human readable reason for reaching the current state (can be empty)
Reason string `json:"reason,omitempty"` // Reason for current state

// AppliedVersion defines checksum of applied spec
AppliedVersion string `json:"appliedVersion"`

// ServiceName holds the name of the Service a client can use (inside the k8s cluster)
// to access ArangoDB.
ServiceName string `json:"serviceName,omitempty"`
Expand Down
30 changes: 29 additions & 1 deletion pkg/apis/deployment/v1/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ package v1
import (
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/dchest/uniuri"
"k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -66,6 +67,8 @@ const (
ActionTypePVCResize ActionType = "PVCResize"
// ActionTypePVCResized waits for PVC to resize for defined time
ActionTypePVCResized ActionType = "PVCResized"
// UpToDateUpdateResized define up to date annotation in spec
UpToDateUpdate ActionType = "UpToDateUpdate"
)

const (
Expand All @@ -92,6 +95,8 @@ type Action struct {
Reason string `json:"reason,omitempty"`
// Image used in can of a SetCurrentImage action.
Image string `json:"image,omitempty"`
// Params additional parameters used for action
Params map[string]interface{} `json:"params,omitempty"`
}

// Equal compares two Actions
Expand All @@ -103,7 +108,30 @@ func (a Action) Equal(other Action) bool {
util.TimeCompareEqual(a.CreationTime, other.CreationTime) &&
util.TimeCompareEqualPointer(a.StartTime, other.StartTime) &&
a.Reason == other.Reason &&
a.Image == other.Image
a.Image == other.Image &&
equality.Semantic.DeepEqual(a.Params, other.Params)
}

// AddParam returns copy of action with set parameter
func (a Action) AddParam(key string, value interface{}) Action {
if a.Params == nil {
a.Params = map[string]interface{}{}
}

a.Params[key] = value

return a
}

// GetParam returns action parameter
func (a Action) GetParam(key string) (interface{}, bool) {
if a.Params == nil {
return nil, false
}

i, ok := a.Params[key]

return i, ok
}

// NewAction instantiates a new Action.
Expand Down
23 changes: 23 additions & 0 deletions pkg/deployment/context_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ func (d *Deployment) GetStatus() (api.DeploymentStatus, int32) {
d.status.mutex.Lock()
defer d.status.mutex.Unlock()

return d.getStatus()
}

func (d *Deployment) getStatus() (api.DeploymentStatus, int32) {
version := d.status.version
return *d.status.last.DeepCopy(), version
}
Expand All @@ -115,6 +119,10 @@ func (d *Deployment) UpdateStatus(status api.DeploymentStatus, lastVersion int32
d.status.mutex.Lock()
defer d.status.mutex.Unlock()

return d.updateStatus(status, lastVersion, force...)
}

func (d *Deployment) updateStatus(status api.DeploymentStatus, lastVersion int32, force ...bool) error {
if d.status.version != lastVersion {
// Status is obsolete
d.deps.Log.Error().
Expand Down Expand Up @@ -483,3 +491,18 @@ func (d *Deployment) GetMetricsExporterImage() string {
func (d *Deployment) GetArangoImage() string {
return d.config.ArangoImage
}

func (d *Deployment) WithStatusUpdate(action func(s *api.DeploymentStatus) bool, force ...bool) error {
d.status.mutex.Lock()
defer d.status.mutex.Unlock()

status, version := d.getStatus()

changed := action(&status)

if !changed {
return nil
}

return d.updateStatus(status, version, force...)
}
Loading