mirror of
https://github.com/goharbor/harbor
synced 2024-09-21 07:27:55 +00:00
Check the status behind error when trying to update the scan schedule
Check the status behind error when trying to update the scan schedule Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
parent
f200125abb
commit
3b07be5a72
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||||
|
@ -18,7 +19,9 @@ import (
|
||||||
var (
|
var (
|
||||||
// GlobalClient is an instance of the default client that can be used globally
|
// GlobalClient is an instance of the default client that can be used globally
|
||||||
// Notes: the client needs to be initialized before can be used
|
// Notes: the client needs to be initialized before can be used
|
||||||
GlobalClient Client
|
GlobalClient Client
|
||||||
|
statusBehindErrorPattern = "mismatch job status for stopping job: .*, job status (.*) is behind Running"
|
||||||
|
statusBehindErrorReg = regexp.MustCompile(statusBehindErrorPattern)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client wraps interface to access jobservice.
|
// Client wraps interface to access jobservice.
|
||||||
|
@ -30,6 +33,21 @@ type Client interface {
|
||||||
// TODO Redirect joblog when we see there's memory issue.
|
// TODO Redirect joblog when we see there's memory issue.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StatusBehindError represents the error got when trying to stop a success/failed job
|
||||||
|
type StatusBehindError struct {
|
||||||
|
status string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns the detail message about the error
|
||||||
|
func (s *StatusBehindError) Error() string {
|
||||||
|
return "status behind error"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status returns the current status of the job
|
||||||
|
func (s *StatusBehindError) Status() string {
|
||||||
|
return s.status
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultClient is the default implementation of Client interface
|
// DefaultClient is the default implementation of Client interface
|
||||||
type DefaultClient struct {
|
type DefaultClient struct {
|
||||||
endpoint string
|
endpoint string
|
||||||
|
@ -156,5 +174,25 @@ func (d *DefaultClient) PostAction(uuid, action string) error {
|
||||||
}{
|
}{
|
||||||
Action: action,
|
Action: action,
|
||||||
}
|
}
|
||||||
return d.client.Post(url, req)
|
if err := d.client.Post(url, req); err != nil {
|
||||||
|
status, flag := isStatusBehindError(err)
|
||||||
|
if flag {
|
||||||
|
return &StatusBehindError{
|
||||||
|
status: status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isStatusBehindError(err error) (string, bool) {
|
||||||
|
if err == nil {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
strs := statusBehindErrorReg.FindStringSubmatch(err.Error())
|
||||||
|
if len(strs) != 2 {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return strs[1], true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package job
|
package job
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/job/models"
|
"github.com/goharbor/harbor/src/common/job/models"
|
||||||
"github.com/goharbor/harbor/src/common/job/test"
|
"github.com/goharbor/harbor/src/common/job/test"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -62,3 +64,20 @@ func TestPostAction(t *testing.T) {
|
||||||
err2 := testClient.PostAction(ID, "stop")
|
err2 := testClient.PostAction(ID, "stop")
|
||||||
assert.Nil(err2)
|
assert.Nil(err2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsStatusBehindError(t *testing.T) {
|
||||||
|
// nil error
|
||||||
|
status, flag := isStatusBehindError(nil)
|
||||||
|
assert.False(t, flag)
|
||||||
|
|
||||||
|
// not status behind error
|
||||||
|
err := errors.New("not status behind error")
|
||||||
|
status, flag = isStatusBehindError(err)
|
||||||
|
assert.False(t, flag)
|
||||||
|
|
||||||
|
// status behind error
|
||||||
|
err = errors.New("mismatch job status for stopping job: 9feedf9933jffs, job status Error is behind Running")
|
||||||
|
status, flag = isStatusBehindError(err)
|
||||||
|
assert.True(t, flag)
|
||||||
|
assert.Equal(t, "Error", status)
|
||||||
|
}
|
||||||
|
|
|
@ -62,9 +62,12 @@ func (aj *AJAPI) updateSchedule(ajr models.AdminJobReq) {
|
||||||
|
|
||||||
// stop the scheduled job and remove it.
|
// stop the scheduled job and remove it.
|
||||||
if err = utils_core.GetJobServiceClient().PostAction(jobs[0].UUID, common_job.JobActionStop); err != nil {
|
if err = utils_core.GetJobServiceClient().PostAction(jobs[0].UUID, common_job.JobActionStop); err != nil {
|
||||||
if e, ok := err.(*common_http.Error); !ok || e.Code != http.StatusNotFound {
|
_, ok := err.(*common_job.StatusBehindError)
|
||||||
aj.SendInternalServerError(err)
|
if !ok {
|
||||||
return
|
if e, ok := err.(*common_http.Error); !ok || e.Code != http.StatusNotFound {
|
||||||
|
aj.SendInternalServerError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ package operation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -49,9 +48,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
statusBehindErrorPattern = "mismatch job status for stopping job: .*, job status (.*) is behind Running"
|
jobNotFoundErrorMsg = "object is not found"
|
||||||
statusBehindErrorReg = regexp.MustCompile(statusBehindErrorPattern)
|
|
||||||
jobNotFoundErrorMsg = "object is not found"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewController returns a controller implementation
|
// NewController returns a controller implementation
|
||||||
|
@ -163,8 +160,9 @@ func (c *controller) StopReplication(executionID int64) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err = c.scheduler.Stop(task.JobID); err != nil {
|
if err = c.scheduler.Stop(task.JobID); err != nil {
|
||||||
status, flag := isStatusBehindError(err)
|
isStatusBehindError, ok := err.(*job.StatusBehindError)
|
||||||
if flag {
|
if ok {
|
||||||
|
status := isStatusBehindError.Status()
|
||||||
switch hjob.Status(status) {
|
switch hjob.Status(status) {
|
||||||
case hjob.ErrorStatus:
|
case hjob.ErrorStatus:
|
||||||
status = models.TaskStatusFailed
|
status = models.TaskStatusFailed
|
||||||
|
@ -215,17 +213,6 @@ func isTaskInFinalStatus(task *models.Task) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func isStatusBehindError(err error) (string, bool) {
|
|
||||||
if err == nil {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
strs := statusBehindErrorReg.FindStringSubmatch(err.Error())
|
|
||||||
if len(strs) != 2 {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
return strs[1], true
|
|
||||||
}
|
|
||||||
|
|
||||||
func isJobNotFoundError(err error) bool {
|
func isJobNotFoundError(err error) bool {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
package operation
|
package operation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -382,20 +381,3 @@ func TestIsTaskRunning(t *testing.T) {
|
||||||
assert.Equal(t, c.isFinalStatus, isTaskInFinalStatus(c.task))
|
assert.Equal(t, c.isFinalStatus, isTaskInFinalStatus(c.task))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIsStatusBehindError(t *testing.T) {
|
|
||||||
// nil error
|
|
||||||
status, flag := isStatusBehindError(nil)
|
|
||||||
assert.False(t, flag)
|
|
||||||
|
|
||||||
// not status behind error
|
|
||||||
err := errors.New("not status behind error")
|
|
||||||
status, flag = isStatusBehindError(err)
|
|
||||||
assert.False(t, flag)
|
|
||||||
|
|
||||||
// status behind error
|
|
||||||
err = errors.New("mismatch job status for stopping job: 9feedf9933jffs, job status Error is behind Running")
|
|
||||||
status, flag = isStatusBehindError(err)
|
|
||||||
assert.True(t, flag)
|
|
||||||
assert.Equal(t, "Error", status)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user