[ Server ] [ Harbor ] - sync status - 1
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mittwald/goharbor-client/v5/apiv2"
|
"github.com/mittwald/goharbor-client/v5/apiv2"
|
||||||
@@ -39,6 +40,7 @@ func NewHarborOperator() *HarborOperator {
|
|||||||
|
|
||||||
// HarborOperatorCache 饿汉式单例
|
// HarborOperatorCache 饿汉式单例
|
||||||
var HarborOperatorCache = NewHarborOperator()
|
var HarborOperatorCache = NewHarborOperator()
|
||||||
|
var OctopusReplicationPolicyName = "octopus-sync-replication"
|
||||||
|
|
||||||
func (hOp *HarborOperator) Exec(baseFuncName string, funcArgs ...string) (bool, []string) {
|
func (hOp *HarborOperator) Exec(baseFuncName string, funcArgs ...string) (bool, []string) {
|
||||||
// 参见 HarborFunctionEnum
|
// 参见 HarborFunctionEnum
|
||||||
@@ -56,7 +58,9 @@ func (hOp *HarborOperator) Exec(baseFuncName string, funcArgs ...string) (bool,
|
|||||||
case "SYNC_PROJECT_BETWEEN_HARBOR":
|
case "SYNC_PROJECT_BETWEEN_HARBOR":
|
||||||
resultOk, resultLog = hOp.SyncProjectExec(funcArgs)
|
resultOk, resultLog = hOp.SyncProjectExec(funcArgs)
|
||||||
break
|
break
|
||||||
|
case "SYNC_STATUS_HARBOR":
|
||||||
|
resultOk, resultLog = hOp.SyncStatusExec(funcArgs)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultOk, resultLog
|
return resultOk, resultLog
|
||||||
@@ -221,7 +225,7 @@ func (hOp *HarborOperator) SyncProjectExec(funcArgs []string) (bool, []string) {
|
|||||||
return false, append(syncNotExistHarborProjectError, "targetClient")
|
return false, append(syncNotExistHarborProjectError, "targetClient")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
octopusReplicationPolicyName := "octopus-sync-replication"
|
|
||||||
OctopusSourceHarborName := "octopus-source"
|
OctopusSourceHarborName := "octopus-source"
|
||||||
|
|
||||||
// add source registry to destination harbor
|
// add source registry to destination harbor
|
||||||
@@ -231,7 +235,7 @@ func (hOp *HarborOperator) SyncProjectExec(funcArgs []string) (bool, []string) {
|
|||||||
policies, _ := targetClient.ListReplicationPolicies(ctx)
|
policies, _ := targetClient.ListReplicationPolicies(ctx)
|
||||||
if policies != nil {
|
if policies != nil {
|
||||||
for _, policy := range policies {
|
for _, policy := range policies {
|
||||||
if policy.Name == octopusReplicationPolicyName {
|
if policy.Name == OctopusReplicationPolicyName {
|
||||||
err := targetClient.DeleteReplicationPolicyByID(ctx, policy.ID)
|
err := targetClient.DeleteReplicationPolicyByID(ctx, policy.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorF("[Harbor Sync Project ] - delete exists replication policy failed ! => %v ", policy)
|
log.ErrorF("[Harbor Sync Project ] - delete exists replication policy failed ! => %v ", policy)
|
||||||
@@ -296,9 +300,13 @@ func (hOp *HarborOperator) SyncProjectExec(funcArgs []string) (bool, []string) {
|
|||||||
Type: "name",
|
Type: "name",
|
||||||
Value: "cmii/**", // 根据需要同步的仓库进行调整
|
Value: "cmii/**", // 根据需要同步的仓库进行调整
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Type: "name",
|
||||||
|
Value: "rancher/**", // 根据需要同步的仓库进行调整
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Name: octopusReplicationPolicyName,
|
Name: OctopusReplicationPolicyName,
|
||||||
Override: true,
|
Override: true,
|
||||||
ReplicateDeletion: false,
|
ReplicateDeletion: false,
|
||||||
Speed: nil,
|
Speed: nil,
|
||||||
@@ -322,7 +330,7 @@ func (hOp *HarborOperator) SyncProjectExec(funcArgs []string) (bool, []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
realOctopusReplicationPolicy, err := targetClient.GetReplicationPolicyByName(ctx, octopusReplicationPolicyName)
|
realOctopusReplicationPolicy, err := targetClient.GetReplicationPolicyByName(ctx, OctopusReplicationPolicyName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, []string{
|
return false, []string{
|
||||||
"[Harbor Sync Project ] - failed to get the realOctopusReplicationPolicy!",
|
"[Harbor Sync Project ] - failed to get the realOctopusReplicationPolicy!",
|
||||||
@@ -335,13 +343,65 @@ func (hOp *HarborOperator) SyncProjectExec(funcArgs []string) (bool, []string) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, []string{
|
return false, []string{
|
||||||
"[Harbor Sync Project ] - failed to start the harbor sync execution !",
|
"[ Harbor Sync Project ] - failed to start the harbor sync execution !",
|
||||||
err.Error(),
|
err.Error(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, []string{
|
||||||
|
"[ Harbor Sync Project ] - sync started !",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hOp *HarborOperator) SyncStatusExec(funcArgs []string) (bool, []string) {
|
||||||
|
|
||||||
|
if hOp.TargetHarborClient == nil {
|
||||||
|
ok, createClient := hOp.CheckAndBuildHarborClient(funcArgs[0], true)
|
||||||
|
if !ok {
|
||||||
|
return false, []string{
|
||||||
|
"[ Sync Status ] - Error !",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hOp.TargetHarborClient = createClient
|
||||||
|
}
|
||||||
|
targetClient := hOp.TargetHarborClient
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
// check replication policy exists
|
||||||
|
|
||||||
|
replicationPolicy, err := targetClient.GetReplicationPolicyByName(ctx, OctopusReplicationPolicyName)
|
||||||
|
if err != nil {
|
||||||
|
return false, []string{
|
||||||
|
"[ Sync Status ] - get replication error !",
|
||||||
|
err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// list execution status
|
||||||
|
replicationExecutions, err := targetClient.ListReplicationExecutions(ctx, &replicationPolicy.ID, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, []string{
|
||||||
|
"[ Sync Status ] - replication has no sync work !",
|
||||||
|
err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the newest one only have one here
|
||||||
|
for _, execution := range replicationExecutions {
|
||||||
|
if !strings.HasPrefix(execution.Status, "Succeed") {
|
||||||
|
log.InfoF("[sync status]- status are => %v", execution)
|
||||||
|
// report status
|
||||||
|
return false, []string{
|
||||||
|
fmt.Sprintf("[sync status] - not complete ! progress is => %s %", strconv.FormatInt(execution.Succeed/execution.Total, 10)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, []string{
|
||||||
|
"[sync status]- sync completed !",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (hOp *HarborOperator) Command(baseFuncName string, funcArgs ...string) []string {
|
func (hOp *HarborOperator) Command(baseFuncName string, funcArgs ...string) []string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ public enum HarborFunctionEnum {
|
|||||||
|
|
||||||
SYNC_PROJECT_BETWEEN_HARBOR(
|
SYNC_PROJECT_BETWEEN_HARBOR(
|
||||||
"SYNC_PROJECT_BETWEEN_HARBOR",
|
"SYNC_PROJECT_BETWEEN_HARBOR",
|
||||||
"在源Harbor和目标Harbor之间同步Project, args 为目标Harbor的HostName,不带端口, 源Harbor的HostName,不带端口"
|
"在源Harbor和目标Harbor之间同步Project, args 为目标Harbor的HostName,不带端口; 源Harbor的HostName,不带端口"
|
||||||
|
),
|
||||||
|
|
||||||
|
SYNC_STATUS_HARBOR(
|
||||||
|
"SYNC_STATUS_HARBOR",
|
||||||
|
"查询目标Harbor的同步状态进度, args 为目标Harbor的HostName,不带端口;"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import java.net.InetAddress;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -31,13 +32,28 @@ public class HarborFuncScheduler {
|
|||||||
|
|
||||||
|
|
||||||
// after run
|
// after run
|
||||||
afterRunProcedure();
|
afterRunProcedure(projectDeployContext);
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void afterRunProcedure() {
|
private void afterRunProcedure(ProjectDeployContext projectDeployContext) {
|
||||||
|
|
||||||
|
int maxSyncStatusCheckCount = 1000;
|
||||||
|
int timePinch = 2;
|
||||||
|
|
||||||
|
int waitCount = 0;
|
||||||
|
|
||||||
|
while (waitCount < maxSyncStatusCheckCount && !checkHarborSyncStatus(projectDeployContext)) {
|
||||||
|
waitCount++;
|
||||||
|
|
||||||
|
try {
|
||||||
|
TimeUnit.SECONDS.sleep(timePinch);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("wait for sync status error !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否安装完成, 对安装环境进行判定
|
// 检查是否安装完成, 对安装环境进行判定
|
||||||
log.debug("afterRunProcedure complete!");
|
log.debug("afterRunProcedure complete!");
|
||||||
@@ -202,6 +218,27 @@ public class HarborFuncScheduler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkHarborSyncStatus(ProjectDeployContext projectDeployContext) {
|
||||||
|
ServerInfoPO masterNode = projectDeployContext.getMasterNode();
|
||||||
|
|
||||||
|
ArrayList<String> syncHarborArgList = new ArrayList<>();
|
||||||
|
syncHarborArgList.add(HarborFunctionEnum.SYNC_STATUS_HARBOR.getOpName());
|
||||||
|
syncHarborArgList.add(masterNode.getServerIpInV4());
|
||||||
|
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
"{} start ! args are => {}",
|
||||||
|
HarborFunctionEnum.SYNC_STATUS_HARBOR.getOpName(),
|
||||||
|
syncHarborArgList
|
||||||
|
);
|
||||||
|
|
||||||
|
return funcService.callHarborFuncAndJudge(
|
||||||
|
masterNode.getTopicName(),
|
||||||
|
HarborFunctionEnum.SYNC_STATUS_HARBOR,
|
||||||
|
syncHarborArgList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void beforeRunProcedure(ProjectDeployContext projectDeployContext) {
|
private void beforeRunProcedure(ProjectDeployContext projectDeployContext) {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.wdd.func.controller;
|
||||||
|
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController("/auto")
|
||||||
|
@Api("Octopus自动化介入")
|
||||||
|
public class AutoController {
|
||||||
|
|
||||||
|
@GetMapping("/harbor/status")
|
||||||
|
@ApiOperation("查看Harbor的Sync的同步状态")
|
||||||
|
public void GetHarborSyncStatus(
|
||||||
|
@RequestParam(name = "projectId") @ApiParam("projectId") Long projectId
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user