Merge branch 'job-service' into new-ui-with-sync-image

This commit is contained in:
kunw 2016-06-16 15:09:48 +08:00
commit 4a04969ae8
17 changed files with 315 additions and 93 deletions

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api
import (
@ -126,7 +141,7 @@ func (pa *RepPolicyAPI) Post() {
pa.Redirect(http.StatusCreated, strconv.FormatInt(pid, 10))
}
// Put modifies name and description of policy
// Put modifies name, description, target and enablement of policy
func (pa *RepPolicyAPI) Put() {
id := pa.GetIDFromURL()
originalPolicy, err := dao.GetRepPolicy(id)
@ -142,7 +157,6 @@ func (pa *RepPolicyAPI) Put() {
policy := &models.RepPolicy{}
pa.DecodeJSONReq(policy)
policy.ProjectID = originalPolicy.ProjectID
policy.TargetID = originalPolicy.TargetID
pa.Validate(policy)
if policy.Name != originalPolicy.Name {
@ -157,19 +171,77 @@ func (pa *RepPolicyAPI) Put() {
}
}
if policy.TargetID != originalPolicy.TargetID {
target, err := dao.GetRepTarget(policy.TargetID)
if err != nil {
log.Errorf("failed to get target %d: %v", policy.TargetID, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if target == nil {
pa.CustomAbort(http.StatusBadRequest, fmt.Sprintf("target %d does not exist", policy.TargetID))
}
}
policy.ID = id
isTargetChanged := !(policy.TargetID == originalPolicy.TargetID)
isEnablementChanged := !(policy.Enabled == policy.Enabled)
var shouldStop, shouldTrigger bool
// if target and enablement are not changed, do nothing
if !isTargetChanged && !isEnablementChanged {
shouldStop = false
shouldTrigger = false
} else if !isTargetChanged && isEnablementChanged {
// target is not changed, but enablement is changed
if policy.Enabled == 0 {
shouldStop = true
shouldTrigger = false
} else {
shouldStop = false
shouldTrigger = true
}
} else if isTargetChanged && !isEnablementChanged {
// target is changed, but enablement is not changed
if policy.Enabled == 0 {
// enablement is 0, do nothing
shouldStop = false
shouldTrigger = false
} else {
// enablement is 1, so stop original target's jobs
// and trigger new target's jobs
shouldStop = true
shouldTrigger = true
}
} else {
// both target and enablement are changed
// enablement: 1 -> 0
if policy.Enabled == 0 {
shouldStop = true
shouldTrigger = false
} else {
shouldStop = false
shouldTrigger = true
}
}
if shouldStop {
if err := postReplicationAction(id, "stop"); err != nil {
log.Errorf("failed to stop replication of %d: %v", id, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
log.Infof("replication of %d has been stopped", id)
}
if err = dao.UpdateRepPolicy(policy); err != nil {
log.Errorf("failed to update policy %d: %v", id, err)
pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if policy.Enabled == originalPolicy.Enabled {
return
}
//enablement has been modified
if policy.Enabled == 1 {
if shouldTrigger {
go func() {
if err := TriggerReplication(id, "", nil, models.RepOpTransfer); err != nil {
log.Errorf("failed to trigger replication of %d: %v", id, err)
@ -177,14 +249,6 @@ func (pa *RepPolicyAPI) Put() {
log.Infof("replication of %d triggered", id)
}
}()
} else {
go func() {
if err := postReplicationAction(id, "stop"); err != nil {
log.Errorf("failed to stop replication of %d: %v", id, err)
} else {
log.Infof("try to stop replication of %d", id)
}
}()
}
}

View File

@ -258,6 +258,16 @@ func (t *TargetAPI) Delete() {
t.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound))
}
policies, err := dao.GetRepPolicyByTarget(id)
if err != nil {
log.Errorf("failed to get policies according target %d: %v", id, err)
t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
if len(policies) > 0 {
t.CustomAbort(http.StatusBadRequest, "the target is used by policies, can not be deleted")
}
if err = dao.DeleteRepTarget(id); err != nil {
log.Errorf("failed to delete target %d: %v", id, err)
t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))

View File

@ -911,6 +911,21 @@ func TestAddRepPolicy(t *testing.T) {
}
func TestGetRepPolicyByTarget(t *testing.T) {
policies, err := GetRepPolicyByTarget(targetID)
if err != nil {
t.Fatalf("failed to get policy according target %d: %v", targetID, err)
}
if len(policies) == 0 {
t.Fatal("unexpected length of policies 0, expected is >0")
}
if policies[0].ID != policyID {
t.Fatalf("unexpected policy: %d, expected: %d", policies[0].ID, policyID)
}
}
func TestGetRepPolicyByName(t *testing.T) {
policy, err := GetRepPolicy(policyID)
if err != nil {

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dao
import (
@ -177,10 +192,24 @@ func GetRepPolicyByProject(projectID int64) ([]*models.RepPolicy, error) {
return policies, nil
}
// GetRepPolicyByTarget ...
func GetRepPolicyByTarget(targetID int64) ([]*models.RepPolicy, error) {
o := GetOrmer()
sql := `select * from replication_policy where target_id = ?`
var policies []*models.RepPolicy
if _, err := o.Raw(sql, targetID).QueryRows(&policies); err != nil {
return nil, err
}
return policies, nil
}
// UpdateRepPolicy ...
func UpdateRepPolicy(policy *models.RepPolicy) error {
o := GetOrmer()
_, err := o.Update(policy, "Name", "Enabled", "Description", "CronStr")
_, err := o.Update(policy, "TargetID", "Name", "Enabled", "Description", "CronStr")
return err
}

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package config
import (

View File

@ -1,76 +0,0 @@
package replication
/*
import (
"encoding/json"
//"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/job"
"github.com/vmware/harbor/models"
"time"
)
const (
jobType = "transfer_img_out"
)
type Runner struct {
job.JobSM
Logger job.Logger
parm ImgOutParm
}
type ImgPuller struct {
job.DummyHandler
img string
logger job.Logger
}
func (ip ImgPuller) Enter() (string, error) {
ip.logger.Infof("I'm pretending to pull img:%s, then sleep 30s", ip.img)
time.Sleep(30 * time.Second)
ip.logger.Infof("wake up from sleep....")
return "push-img", nil
}
type ImgPusher struct {
job.DummyHandler
targetURL string
logger job.Logger
}
func (ip ImgPusher) Enter() (string, error) {
ip.logger.Infof("I'm pretending to push img to:%s, then sleep 30s", ip.targetURL)
time.Sleep(30 * time.Second)
ip.logger.Infof("wake up from sleep....")
return job.JobContinue, nil
}
func init() {
job.Register(jobType, Runner{})
}
func (r Runner) Run(je models.JobEntry) error {
err := r.init(je)
if err != nil {
return err
}
r.Start(job.JobRunning)
return nil
}
func (r *Runner) init(je models.JobEntry) error {
r.JobID = je.ID
r.InitJobSM()
err := json.Unmarshal([]byte(je.ParmsStr), &r.parm)
if err != nil {
return err
}
r.Logger = job.Logger{je.ID}
r.AddTransition(job.JobRunning, "pull-img", ImgPuller{DummyHandler: job.DummyHandler{JobID: r.JobID}, img: r.parm.Image, logger: r.Logger})
//only handle on target for now
url := r.parm.Targets[0].URL
r.AddTransition("pull-img", "push-img", ImgPusher{DummyHandler: job.DummyHandler{JobID: r.JobID}, targetURL: url, logger: r.Logger})
r.AddTransition("push-img", job.JobFinished, job.StatusUpdater{job.DummyHandler{JobID: r.JobID}, job.JobFinished})
return nil
}
*/

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package job
var jobQueue = make(chan int64)

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package job
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package job
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package utils
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package job
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package models
import (

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package models
import (