From ba47b4c00fa91fd6731142947f36957856768bda Mon Sep 17 00:00:00 2001 From: Ziming Zhang Date: Mon, 29 Jul 2019 10:19:01 +0800 Subject: [PATCH] get execution status on the fly Signed-off-by: Ziming Zhang Change-Id: Iefcf8946d7a2c7a27bc22bd326ee9723b4b79c66 --- .../postgresql/0010_1.9.0_schema.up.sql | 9 +---- src/core/api/retention.go | 2 +- src/pkg/retention/controller.go | 15 +------ src/pkg/retention/dao/models/retention.go | 23 +++++++---- src/pkg/retention/dao/retention.go | 40 ++++++++++++++++++- src/pkg/retention/manager.go | 12 ------ src/pkg/retention/manager_test.go | 12 +----- 7 files changed, 59 insertions(+), 54 deletions(-) diff --git a/make/migrations/postgresql/0010_1.9.0_schema.up.sql b/make/migrations/postgresql/0010_1.9.0_schema.up.sql index 0718b19ae..f4e0b6519 100644 --- a/make/migrations/postgresql/0010_1.9.0_schema.up.sql +++ b/make/migrations/postgresql/0010_1.9.0_schema.up.sql @@ -109,16 +109,9 @@ create table retention_execution ( id serial PRIMARY KEY NOT NULL, policy_id integer, - status varchar(20), dry_run boolean, trigger varchar(20), - total integer, - succeed integer, - failed integer, - in_progress integer, - stopped integer, - start_time timestamp, - end_time timestamp + start_time timestamp ); create table retention_task diff --git a/src/core/api/retention.go b/src/core/api/retention.go index f431ce5a9..1bf1751b0 100644 --- a/src/core/api/retention.go +++ b/src/core/api/retention.go @@ -190,7 +190,7 @@ func (r *RetentionAPI) CreateRetention() { return } if err := r.pm.GetMetadataManager().Add(p.Scope.Reference, - map[string]string{"retention_id": strconv.FormatInt(p.Scope.Reference, 10)}); err != nil { + map[string]string{"retention_id": strconv.FormatInt(id, 10)}); err != nil { r.SendInternalServerError(err) } r.Redirect(http.StatusCreated, strconv.FormatInt(id, 10)) diff --git a/src/pkg/retention/controller.go b/src/pkg/retention/controller.go index 8435925f8..7085e1da2 100644 --- a/src/pkg/retention/controller.go +++ b/src/pkg/retention/controller.go @@ -192,26 +192,13 @@ func (r *DefaultAPIController) TriggerRetentionExec(policyID int64, trigger stri exec := &Execution{ PolicyID: policyID, StartTime: time.Now(), - Status: ExecutionStatusInProgress, Trigger: trigger, DryRun: dryRun, } id, err := r.manager.CreateExecution(exec) - num, err := r.launcher.Launch(p, id, dryRun) - if err != nil { + if _, err = r.launcher.Launch(p, id, dryRun); err != nil { return 0, err } - if num == 0 { - exec := &Execution{ - ID: id, - EndTime: time.Now(), - Status: ExecutionStatusSucceed, - } - err = r.manager.UpdateExecution(exec) - if err != nil { - return 0, err - } - } return id, err } diff --git a/src/pkg/retention/dao/models/retention.go b/src/pkg/retention/dao/models/retention.go index a3d24de70..b66ae69b7 100644 --- a/src/pkg/retention/dao/models/retention.go +++ b/src/pkg/retention/dao/models/retention.go @@ -6,6 +6,14 @@ import ( "github.com/astaxie/beego/orm" ) +// const definitions +const ( + ExecutionStatusInProgress string = "InProgress" + ExecutionStatusSucceed string = "Succeed" + ExecutionStatusFailed string = "Failed" + ExecutionStatusStopped string = "Stopped" +) + func init() { orm.RegisterModel( new(RetentionPolicy), @@ -31,17 +39,18 @@ type RetentionPolicy struct { type RetentionExecution struct { ID int64 `orm:"pk;auto;column(id)" json:"id"` PolicyID int64 `orm:"column(policy_id)"` - Status string DryRun bool // manual, scheduled Trigger string - Total int - Succeed int - Failed int - InProgress int - Stopped int StartTime time.Time - EndTime time.Time + EndTime time.Time `orm:"-"` + Status string `orm:"-"` + Total int `orm:"-"` + Succeed int `orm:"-"` + Failed int `orm:"-"` + InProgress int `orm:"-"` + Stopped int `orm:"-"` + Pending int `orm:"-"` } // RetentionTask ... diff --git a/src/pkg/retention/dao/retention.go b/src/pkg/retention/dao/retention.go index a88546f8a..bce0042b0 100644 --- a/src/pkg/retention/dao/retention.go +++ b/src/pkg/retention/dao/retention.go @@ -3,7 +3,6 @@ package dao import ( "errors" "fmt" - "github.com/goharbor/harbor/src/common/dao" "github.com/goharbor/harbor/src/pkg/retention/dao/models" "github.com/goharbor/harbor/src/pkg/retention/q" @@ -85,9 +84,43 @@ func GetExecution(id int64) (*models.RetentionExecution, error) { if err := o.Read(e); err != nil { return nil, err } + if err := fillStatus(e); err != nil { + return nil, err + } return e, nil } +// fillStatus the priority is InProgress Stopped Failed Succeed +func fillStatus(exec *models.RetentionExecution) error { + o := dao.GetOrmer() + if _, err := o.Raw("select status, count(*) num from retention_task where execution_id = ? group by status", exec.ID). + RowsToStruct(exec, "status", "num"); err != nil { + return err + } + exec.Total = exec.Pending + exec.InProgress + exec.Succeed + exec.Failed + exec.Stopped + if exec.Total == 0 { + exec.Status = models.ExecutionStatusSucceed + exec.EndTime = exec.StartTime + return nil + } + if exec.Pending+exec.InProgress > 0 { + exec.Status = models.ExecutionStatusInProgress + } else if exec.Stopped > 0 { + exec.Status = models.ExecutionStatusStopped + } else if exec.Failed > 0 { + exec.Status = models.ExecutionStatusFailed + } else { + exec.Status = models.ExecutionStatusSucceed + } + if exec.Status != models.ExecutionStatusInProgress { + if err := o.Raw("select max(end_time) from retention_task where execution_id = ?", exec.ID). + QueryRow(&exec.EndTime); err != nil { + return err + } + } + return nil +} + // ListExecutions List Executions func ListExecutions(policyID int64, query *q.Query) ([]*models.RetentionExecution, error) { o := dao.GetOrmer() @@ -102,6 +135,11 @@ func ListExecutions(policyID int64, query *q.Query) ([]*models.RetentionExecutio if err != nil { return nil, err } + for _, e := range execs { + if err := fillStatus(e); err != nil { + return nil, err + } + } return execs, nil } diff --git a/src/pkg/retention/manager.go b/src/pkg/retention/manager.go index 945626acc..36f8dc2f0 100644 --- a/src/pkg/retention/manager.go +++ b/src/pkg/retention/manager.go @@ -42,8 +42,6 @@ type Manager interface { GetPolicy(ID int64) (*policy.Metadata, error) // Create a new retention execution CreateExecution(execution *Execution) (int64, error) - // Update the specified execution - UpdateExecution(execution *Execution) error // Get the specified execution GetExecution(eid int64) (*Execution, error) // List execution histories @@ -123,20 +121,10 @@ func (d *DefaultManager) CreateExecution(execution *Execution) (int64, error) { exec.PolicyID = execution.PolicyID exec.StartTime = time.Now() exec.DryRun = execution.DryRun - exec.Status = execution.Status exec.Trigger = execution.Trigger return dao.CreateExecution(exec) } -// UpdateExecution Update Execution -func (d *DefaultManager) UpdateExecution(execution *Execution) error { - exec := &models.RetentionExecution{} - exec.ID = execution.ID - exec.EndTime = execution.EndTime - exec.Status = execution.Status - return dao.UpdateExecution(exec, "end_time", "status") -} - // ListExecutions List Executions func (d *DefaultManager) ListExecutions(policyID int64, query *q.Query) ([]*Execution, error) { execs, err := dao.ListExecutions(policyID, query) diff --git a/src/pkg/retention/manager_test.go b/src/pkg/retention/manager_test.go index 80a813bdb..6de10a98a 100644 --- a/src/pkg/retention/manager_test.go +++ b/src/pkg/retention/manager_test.go @@ -145,7 +145,6 @@ func TestExecution(t *testing.T) { e1 := &Execution{ PolicyID: policyID, StartTime: time.Now(), - Status: ExecutionStatusInProgress, Trigger: ExecutionTriggerManual, DryRun: false, } @@ -158,15 +157,6 @@ func TestExecution(t *testing.T) { assert.NotNil(t, e1) assert.EqualValues(t, id, e1.ID) - e1.Status = ExecutionStatusFailed - err = m.UpdateExecution(e1) - assert.Nil(t, err) - - e1, err = m.GetExecution(id) - assert.Nil(t, err) - assert.NotNil(t, e1) - assert.EqualValues(t, ExecutionStatusFailed, e1.Status) - es, err := m.ListExecutions(policyID, nil) assert.Nil(t, err) assert.EqualValues(t, 1, len(es)) @@ -187,7 +177,7 @@ func TestTask(t *testing.T) { // get tk, err := m.GetTask(id) require.Nil(t, err) - assert.Equal(t, id, tk.ExecutionID) + assert.EqualValues(t, 1, tk.ExecutionID) // update task.ID = id