mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
[Feature] Add action progress (#1103)
This commit is contained in:
parent
3c02016fe0
commit
1c913aa2b9
6 changed files with 89 additions and 7 deletions
|
@ -1,6 +1,7 @@
|
|||
# Change Log
|
||||
|
||||
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
|
||||
- (Feature) Add action progress
|
||||
|
||||
## [1.2.19](https://github.com/arangodb/kube-arangodb/tree/1.2.19) (2022-10-05)
|
||||
- (Bugfix) Prevent changes when UID is wrong
|
||||
|
|
|
@ -97,6 +97,8 @@ type Action struct {
|
|||
Locals PlanLocals `json:"locals,omitempty"`
|
||||
// ID reference of the task involved in this action (if any)
|
||||
TaskID types.UID `json:"taskID,omitempty"`
|
||||
// Progress describes what is a status of the current action.
|
||||
Progress string `json:"progress,omitempty"`
|
||||
}
|
||||
|
||||
// Equal compares two Actions
|
||||
|
@ -112,7 +114,8 @@ func (a Action) Equal(other Action) bool {
|
|||
a.Image == other.Image &&
|
||||
equality.Semantic.DeepEqual(a.Params, other.Params) &&
|
||||
a.Locals.Equal(other.Locals) &&
|
||||
a.TaskID == other.TaskID
|
||||
a.TaskID == other.TaskID &&
|
||||
a.Progress == other.Progress
|
||||
}
|
||||
|
||||
// AddParam returns copy of action with set parameter
|
||||
|
|
|
@ -97,6 +97,8 @@ type Action struct {
|
|||
Locals PlanLocals `json:"locals,omitempty"`
|
||||
// ID reference of the task involved in this action (if any)
|
||||
TaskID types.UID `json:"taskID,omitempty"`
|
||||
// Progress describes what is a status of the current action.
|
||||
Progress string `json:"progress,omitempty"`
|
||||
}
|
||||
|
||||
// Equal compares two Actions
|
||||
|
@ -112,7 +114,8 @@ func (a Action) Equal(other Action) bool {
|
|||
a.Image == other.Image &&
|
||||
equality.Semantic.DeepEqual(a.Params, other.Params) &&
|
||||
a.Locals.Equal(other.Locals) &&
|
||||
a.TaskID == other.TaskID
|
||||
a.TaskID == other.TaskID &&
|
||||
a.Progress == other.Progress
|
||||
}
|
||||
|
||||
// AddParam returns copy of action with set parameter
|
||||
|
|
|
@ -60,6 +60,7 @@ type ActionContext interface {
|
|||
Metrics() *Metrics
|
||||
|
||||
ActionLocalsContext
|
||||
ActionProgressor
|
||||
|
||||
// GetMemberStatusByID returns the current member status
|
||||
// for the member with given id.
|
||||
|
@ -113,6 +114,14 @@ type ActionLocalsContext interface {
|
|||
BackoffExecution(action api.Action, key api.PlanLocalKey, duration time.Duration) bool
|
||||
}
|
||||
|
||||
// ActionProgressor describe functions to follow a progress of an action.
|
||||
type ActionProgressor interface {
|
||||
// GetProgress returns progress of an action.
|
||||
GetProgress() string
|
||||
// SetProgress sets progress of an action.
|
||||
SetProgress(progress string)
|
||||
}
|
||||
|
||||
// newActionContext creates a new ActionContext implementation.
|
||||
func newActionContext(log logging.Logger, context Context, metrics *Metrics) ActionContext {
|
||||
return &actionContext{
|
||||
|
@ -128,6 +137,7 @@ type actionContext struct {
|
|||
log logging.Logger
|
||||
cachedStatus inspectorInterface.Inspector
|
||||
locals api.PlanLocals
|
||||
Progress string
|
||||
metrics *Metrics
|
||||
}
|
||||
|
||||
|
@ -183,6 +193,16 @@ func (ac *actionContext) SetTime(key api.PlanLocalKey, t time.Time) bool {
|
|||
return ac.Add(key, t.Format(util.TimeLayout), true)
|
||||
}
|
||||
|
||||
// SetProgress sets progress to an action.
|
||||
func (ac *actionContext) SetProgress(progress string) {
|
||||
ac.Progress = progress
|
||||
}
|
||||
|
||||
// GetProgress gets progress of an action.
|
||||
func (ac *actionContext) GetProgress() string {
|
||||
return ac.Progress
|
||||
}
|
||||
|
||||
func (ac *actionContext) GetTime(action api.Action, key api.PlanLocalKey) (time.Time, bool) {
|
||||
s, ok := ac.locals.GetWithParent(action.Locals, key)
|
||||
if !ok {
|
||||
|
|
|
@ -22,10 +22,13 @@ package reconcile
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
driver "github.com/arangodb/go-driver"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/client"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/globals"
|
||||
)
|
||||
|
@ -84,7 +87,7 @@ func (a *actionWaitForMemberUp) CheckProgress(ctx context.Context) (bool, bool,
|
|||
if a.action.Group == api.ServerGroupAgents {
|
||||
return a.checkProgressAgent()
|
||||
}
|
||||
return a.checkProgressCluster()
|
||||
return a.checkProgressCluster(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +141,7 @@ func (a *actionWaitForMemberUp) checkProgressAgent() (bool, bool, error) {
|
|||
|
||||
// checkProgressCluster checks the progress of the action in the case
|
||||
// of a cluster deployment (coordinator/dbserver).
|
||||
func (a *actionWaitForMemberUp) checkProgressCluster() (bool, bool, error) {
|
||||
func (a *actionWaitForMemberUp) checkProgressCluster(ctx context.Context) (bool, bool, error) {
|
||||
h, _ := a.actionCtx.GetMembersState().Health()
|
||||
if h.Error != nil {
|
||||
a.log.Err(h.Error).Debug("Cluster health is missing")
|
||||
|
@ -153,13 +156,32 @@ func (a *actionWaitForMemberUp) checkProgressCluster() (bool, bool, error) {
|
|||
a.log.Str("status", string(sh.Status)).Debug("Member set status not yet good")
|
||||
return false, false, nil
|
||||
}
|
||||
|
||||
// Wait for the member to become ready from a kubernetes point of view
|
||||
// otherwise the coordinators may be rotated to fast and thus none of them
|
||||
// is ready resulting in a short downtime
|
||||
if m, found := a.actionCtx.GetMemberStatusByID(a.MemberID()); !found {
|
||||
m, found := a.actionCtx.GetMemberStatusByID(a.MemberID())
|
||||
if !found {
|
||||
a.log.Error("No such member")
|
||||
return false, true, nil
|
||||
} else if !m.Conditions.IsTrue(api.ConditionTypeReady) {
|
||||
}
|
||||
|
||||
imageInfo, found := a.actionCtx.GetCurrentImageInfo()
|
||||
if !found {
|
||||
a.log.Info("Image not found")
|
||||
return false, false, nil
|
||||
}
|
||||
|
||||
if resources.IsServerProgressAvailable(a.action.Group, imageInfo) {
|
||||
if status, err := a.getServerStatus(ctx); err == nil {
|
||||
progress, _ := status.GetProgress()
|
||||
a.actionCtx.SetProgress(progress)
|
||||
} else {
|
||||
a.log.Err(err).Warn("Failed to get server status to establish a progress")
|
||||
}
|
||||
}
|
||||
|
||||
if !m.Conditions.IsTrue(api.ConditionTypeReady) {
|
||||
a.log.Debug("Member not yet ready")
|
||||
return false, false, nil
|
||||
}
|
||||
|
@ -181,3 +203,36 @@ func (a *actionWaitForMemberUp) checkProgressArangoSync(ctx context.Context) (bo
|
|||
}
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
func (a actionWaitForMemberUp) getServerStatus(ctx context.Context) (client.ServerStatus, error) {
|
||||
cli, err := a.actionCtx.GetMembersState().GetMemberClient(a.action.MemberID)
|
||||
if err != nil {
|
||||
return client.ServerStatus{}, err
|
||||
}
|
||||
conn := cli.Connection()
|
||||
|
||||
req, err := conn.NewRequest("GET", "_admin/status")
|
||||
if err != nil {
|
||||
return client.ServerStatus{}, err
|
||||
}
|
||||
|
||||
ctxChild, cancel := globals.GetGlobalTimeouts().ArangoD().WithTimeout(ctx)
|
||||
defer cancel()
|
||||
|
||||
resp, err := conn.Do(ctxChild, req)
|
||||
if err != nil {
|
||||
return client.ServerStatus{}, err
|
||||
}
|
||||
|
||||
if err := resp.CheckStatus(http.StatusOK); err != nil {
|
||||
return client.ServerStatus{}, err
|
||||
}
|
||||
|
||||
var result client.ServerStatus
|
||||
|
||||
if err := resp.ParseBody("", &result); err != nil {
|
||||
return client.ServerStatus{}, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
@ -294,7 +294,7 @@ func (d *Reconciler) executePlan(ctx context.Context, statusPlan api.Plan, pg pl
|
|||
}
|
||||
|
||||
plan[0].Locals.Merge(actionContext.CurrentLocals())
|
||||
|
||||
plan[0].Progress = actionContext.GetProgress()
|
||||
return plan, recall, false, nil
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue