Skip to content

Commit

Permalink
<fix>[host]: Enhanced grayscale upgrade
Browse files Browse the repository at this point in the history
DBImpact

Resolves: ZSTAC-56920

Change-Id: I6268627663736675786f6d7778727071676b7762
  • Loading branch information
kaicai.hu committed Jan 15, 2024
1 parent 07ead38 commit 8a451d0
Show file tree
Hide file tree
Showing 53 changed files with 1,614 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,19 @@

import org.springframework.beans.factory.annotation.Autowired;
import org.zstack.core.CoreGlobalProperty;
import org.zstack.core.upgrade.UpgradeGlobalConfig;
import org.zstack.core.cloudbus.CloudBus;
import org.zstack.core.db.DatabaseFacade;
import org.zstack.core.db.Q;
import org.zstack.core.db.SimpleQuery;
import org.zstack.core.db.SimpleQuery.Op;
import org.zstack.core.errorcode.ErrorFacade;
import org.zstack.header.agent.versioncontrol.AgentVersionVO;
import org.zstack.header.apimediator.ApiMessageInterceptionException;
import org.zstack.header.apimediator.ApiMessageInterceptor;
import org.zstack.header.apimediator.StopRoutingException;
import org.zstack.header.host.*;
import org.zstack.header.message.APIMessage;
import org.zstack.utils.ShellResult;
import org.zstack.utils.ShellUtils;
import org.zstack.utils.Utils;
import org.zstack.utils.gson.JSONObjectUtil;
import org.zstack.utils.logging.CLogger;
import org.zstack.utils.network.NetworkUtils;

import static org.zstack.core.Platform.argerr;
Expand Down Expand Up @@ -58,8 +53,6 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti
validate((APIDeleteHostMsg) msg);
} else if (msg instanceof APIChangeHostStateMsg){
validate((APIChangeHostStateMsg) msg);
} else if (msg instanceof APIReconnectHostMsg){
validate((APIReconnectHostMsg) msg);
} else if (msg instanceof APIGetHostWebSshUrlMsg) {
validate((APIGetHostWebSshUrlMsg) msg);
}
Expand Down Expand Up @@ -115,17 +108,4 @@ private void validate(APIChangeHostStateMsg msg){
throw new ApiMessageInterceptionException(operr("can not maintain host[uuid:%s, status:%s]which is not Connected", msg.getHostUuid(), hostStatus));
}
}

private void validate(APIReconnectHostMsg msg) {
String hostUuid = msg.getHostUuid();
if (UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) {
AgentVersionVO agentVersionVO = dbf.findByUuid(msg.getUuid(), AgentVersionVO.class);
if (agentVersionVO == null) {
agentVersionVO = new AgentVersionVO();
agentVersionVO.setUuid(hostUuid);
agentVersionVO.setAgentType("kvm-agent");
dbf.persist(agentVersionVO);
}
}
}
}
34 changes: 15 additions & 19 deletions compute/src/main/java/org/zstack/compute/host/HostBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.zstack.compute.vm.VmSchedHistoryRecorder;
import org.zstack.core.upgrade.UpgradeChecker;
import org.zstack.core.upgrade.UpgradeGlobalConfig;
import org.zstack.core.asyncbatch.While;
import org.zstack.core.cascade.CascadeConstant;
Expand All @@ -21,7 +22,6 @@
import org.zstack.core.thread.*;
import org.zstack.core.workflow.FlowChainBuilder;
import org.zstack.core.workflow.ShareFlow;
import org.zstack.header.agent.versioncontrol.AgentVersionVO;
import org.zstack.header.allocator.AllocationScene;
import org.zstack.header.allocator.HostAllocatorConstant;
import org.zstack.header.core.Completion;
Expand Down Expand Up @@ -89,6 +89,8 @@ public abstract class HostBase extends AbstractHost {
protected EventFacade evtf;
@Autowired
protected HostMaintenancePolicyManager hostMaintenancePolicyMgr;
@Autowired
protected UpgradeChecker upgradeChecker;

public static class HostDisconnectedCanonicalEvent extends CanonicalEventEmitter {
HostCanonicalEvents.HostDisconnectedData data;
Expand Down Expand Up @@ -585,6 +587,7 @@ public void handle(ErrorCode errCode, Map data) {
private void handle(final APIReconnectHostMsg msg) {
ReconnectHostMsg rmsg = new ReconnectHostMsg();
rmsg.setHostUuid(self.getUuid());
rmsg.setCalledByAPI(true);
bus.makeTargetServiceIdByResourceUuid(rmsg, HostConstant.SERVICE_ID, self.getUuid());
bus.send(rmsg, new CloudBusCallBack(msg) {
@Override
Expand Down Expand Up @@ -934,10 +937,6 @@ public void done(ErrorCodeList errorCodeList) {
}

changeConnectionState(HostStatusEvent.disconnected);

CollectionUtils.safeForEach(pluginRgty.getExtensionList(PingHostFailedExtensionPoint.class),
extension -> extension.afterPingHostFailed(self.getUuid(), errorCode));

completion.success(reply);
} else {
reply.setConnected(true);
Expand Down Expand Up @@ -1023,25 +1022,21 @@ private boolean skipReconnectHost(final ReconnectHostMsg msg) {
return true;
}

if (skipConnectHost()) {
return true;
if (msg.isCalledByAPI()) {
return false;
}

return false;
return upgradeChecker.skipConnectAgent(self.getUuid());
}

private boolean skipConnectHost() {
if (UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) {
AgentVersionVO agentVersionVO = dbf.findByUuid(self.getUuid(), AgentVersionVO.class);
if (agentVersionVO == null) {
return true;
}
private boolean skipConnectHost(final ConnectHostMsg msg) {
if (msg.isNewAdd() || msg.isCalledByAPI()) {
return false;
}

return false;
return upgradeChecker.skipConnectAgent(self.getUuid());
}


private void reconnectHost(final ReconnectHostMsg msg, final NoErrorCompletion completion) {
thdf.chainSubmit(new ChainTask(msg, completion) {
@Override
Expand All @@ -1066,6 +1061,7 @@ public void run(final SyncTaskChain chain) {

ConnectHostMsg connectMsg = new ConnectHostMsg(self.getUuid());
connectMsg.setNewAdd(false);
connectMsg.setCalledByAPI(msg.isCalledByAPI());
bus.makeTargetServiceIdByResourceUuid(connectMsg, HostConstant.SERVICE_ID, self.getUuid());
bus.send(connectMsg, new CloudBusCallBack(msg, chain, completion) {
@Override
Expand Down Expand Up @@ -1271,8 +1267,8 @@ public String getSyncSignature() {
@Override
public void run(SyncTaskChain chain) {
checkState();

if (skipConnectHost()) {
if(skipConnectHost(msg)){
completion.success();
chain.next();
return;
Expand Down
2 changes: 2 additions & 0 deletions conf/db/upgrade/V5.0.0__schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,5 @@ CREATE TABLE IF NOT EXISTS `zstack`.`JitSecurityMachineVO` (
PRIMARY KEY (`uuid`),
CONSTRAINT fkJitSecurityMachineVOSecurityMachineVO FOREIGN KEY (uuid) REFERENCES SecurityMachineVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `zstack`.`AgentVersionVO` ADD CONSTRAINT fkAgentVersionVOResourceVO FOREIGN KEY (uuid) REFERENCES ResourceVO (uuid) ON DELETE CASCADE;
2 changes: 1 addition & 1 deletion conf/persistence.xml
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
<class>org.zstack.header.volume.VolumeHostRefVO</class>
<class>org.zstack.directory.DirectoryVO</class>
<class>org.zstack.directory.ResourceDirectoryRefVO</class>
<class>org.zstack.header.agent.versioncontrol.AgentVersionVO</class>
<class>org.zstack.core.upgrade.AgentVersionVO</class>
<class>org.zstack.header.host.HostIpmiVO</class>
<class>org.zstack.header.sshkeypair.SshKeyPairVO</class>
<class>org.zstack.header.sshkeypair.SshKeyPairRefVO</class>
Expand Down
8 changes: 8 additions & 0 deletions conf/serviceConfig/upgrade.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<service xmlns="http://zstack.org/schema/zstack">
<id>upgrade</id>
<message>
<name>org.zstack.core.upgrade.APIQueryAgentVersionMsg</name>
<serviceId>query</serviceId>
</message>
</service>
20 changes: 20 additions & 0 deletions conf/springConfigXml/upgrade.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:zstack="http://zstack.org/schema/zstack"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://zstack.org/schema/zstack
http://zstack.org/schema/zstack/plugin.xsd"
default-init-method="init" default-destroy-method="destroy">

<bean id="UpgradeChecker" class="org.zstack.core.upgrade.UpgradeChecker">
<zstack:plugin>
<zstack:extension interface="org.zstack.header.Component" />
</zstack:plugin>
</bean>
</beans>
1 change: 1 addition & 0 deletions conf/zstack.xml
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,5 @@
<import resource="springConfigXml/sugonSdnController.xml"/>
<import resource="springConfigXml/TfPortAllocator.xml"/>
<import resource="springConfigXml/HostNetworkManager.xml"/>
<import resource="springConfigXml/upgrade.xml"/>
</beans>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.zstack.core.upgrade;

import org.springframework.http.HttpMethod;
import org.zstack.header.query.APIQueryMessage;
import org.zstack.header.query.AutoQuery;
import org.zstack.header.rest.RestRequest;

import java.util.Collections;
import java.util.List;


@AutoQuery(replyClass = APIQueryAgentVersionReply.class, inventoryClass = AgentVersionInventory.class)
@RestRequest(
path = "/agent-version",
optionalPaths = {"/agent-version/{uuid}"},
method = HttpMethod.GET,
responseClass = APIQueryAgentVersionReply.class
)
public class APIQueryAgentVersionMsg extends APIQueryMessage {
public static List<String> __example__() {
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.zstack.core.upgrade

import org.zstack.core.upgrade.APIQueryAgentVersionReply
import org.zstack.header.query.APIQueryMessage

doc {
title "QueryAgentVersion"

category "core"

desc """查询 Agent 版本信息"""

rest {
request {
url "GET /v1/agent-version"
url "GET /v1/agent-version/{uuid}"

header (Authorization: 'OAuth the-session-uuid')

clz APIQueryAgentVersionMsg.class

desc """"""

params APIQueryMessage.class
}

response {
clz APIQueryAgentVersionReply.class
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.zstack.core.upgrade;

import org.zstack.header.query.APIQueryReply;
import org.zstack.header.rest.RestResponse;

import java.util.List;

@RestResponse(allTo = "inventories")
public class APIQueryAgentVersionReply extends APIQueryReply {
private List<AgentVersionInventory> inventories;

public List<AgentVersionInventory> getInventories() {
return inventories;
}

public void setInventories(List<AgentVersionInventory> inventories) {
this.inventories = inventories;
}

public static APIQueryAgentVersionReply __example__() {
APIQueryAgentVersionReply reply = new APIQueryAgentVersionReply();

return reply;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.zstack.core.upgrade


import org.zstack.core.upgrade.AgentVersionVO
import org.zstack.header.errorcode.ErrorCode

doc {

title "查询 Agent 版本信息返回"

ref {
name "inventories"
path "org.zstack.core.upgrade.APIQueryAgentVersionReply.inventories"
desc "null"
type "List"
since "5.0.0"
clz AgentVersionVO.class
}
field {
name "success"
desc ""
type "boolean"
since "5.0.0"
}
ref {
name "error"
path "org.zstack.core.upgrade.APIQueryAgentVersionReply.error"
desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false
type "ErrorCode"
since "5.0.0"
clz ErrorCode.class
}
}
Loading

0 comments on commit 8a451d0

Please sign in to comment.