Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -926,16 +926,38 @@ public void done(ErrorCodeList errorCodeList) {

logger.debug(String.format("HaStartVmJudger[%s] says the VM[uuid:%s, name:%s] is qualified for HA start, now we are starting it",
judger.getClass(), self.getUuid(), self.getName()));
String hostUuid = self.getHostUuid();
String suspectHostUuid = StringUtils.trimToNull(hostUuid);
String peerHostUuid = StringUtils.trimToNull(msg.getAccessiblePeerHostUuid());
UpdateQuery sql = SQL.New(VmInstanceVO.class)
.eq(VmInstanceVO_.uuid, self.getUuid())
.set(VmInstanceVO_.state, VmInstanceState.Stopped)
.set(VmInstanceVO_.hostUuid, null);

if (self.getHostUuid() != null) {
sql.set(VmInstanceVO_.lastHostUuid, self.getHostUuid());
if (hostUuid != null) {
sql.set(VmInstanceVO_.lastHostUuid, hostUuid);
}

sql.update();
refreshVO();
if (suspectHostUuid == null) {
logger.debug(String.format("HA-start vm[%s]: skip creating pre-fence tag because suspect host is absent",
self.getUuid()));
} else if (peerHostUuid == null) {
logger.debug(String.format("HA-start vm[%s]: skip creating pre-fence tag because peer host is absent",
self.getUuid()));
} else {
Map<String, String> tokens = new HashMap<>();
tokens.put(VmSystemTags.HA_PRE_FENCE_SUSPECT_HOST_UUID_TOKEN, suspectHostUuid);
tokens.put(VmSystemTags.HA_PRE_FENCE_ACCESSIBLE_PEER_HOST_UUID_TOKEN, peerHostUuid);

SystemTagCreator creator = VmSystemTags.HA_PRE_FENCE_PENDING.newSystemTagCreator(self.getUuid());
creator.inherent = true;
creator.recreate = true;
creator.ignoreIfExisting = true;
creator.setTagByTokens(tokens);
creator.create();
}

startVm(msg, new Completion(msg, chain) {
@Override
Expand Down Expand Up @@ -8728,4 +8750,3 @@ public void run(MessageReply reply) {
});
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@
import org.springframework.beans.factory.annotation.Configurable;
import org.zstack.core.cloudbus.CloudBus;
import org.zstack.core.cloudbus.CloudBusCallBack;
import org.zstack.core.asyncbatch.While;
import org.zstack.core.componentloader.PluginRegistry;
import org.zstack.core.workflow.FlowChainBuilder;
import org.zstack.header.core.Completion;
import org.zstack.header.core.WhileDoneCompletion;
import org.zstack.header.core.workflow.Flow;
import org.zstack.header.core.workflow.FlowChain;
import org.zstack.header.core.workflow.FlowDoneHandler;
import org.zstack.header.core.workflow.FlowErrorHandler;
import org.zstack.header.core.workflow.FlowRollback;
import org.zstack.header.core.workflow.FlowTrigger;
import org.zstack.header.core.workflow.NoRollbackFlow;
import org.zstack.header.errorcode.ErrorCode;
import org.zstack.header.errorcode.ErrorCodeList;
import org.zstack.header.host.HostConstant;
import org.zstack.header.message.MessageReply;
import org.zstack.header.vm.*;
import org.zstack.utils.Utils;
import org.zstack.utils.logging.CLogger;

import java.util.List;
import java.util.Map;
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE)
public class VmStartOnHypervisorFlow implements Flow {
Expand All @@ -26,34 +35,68 @@ public class VmStartOnHypervisorFlow implements Flow {
@Autowired
private PluginRegistry pluginRgty;

private final List<VmBeforeStartOnHypervisorExtensionPoint> exts = pluginRgty.getExtensionList(VmBeforeStartOnHypervisorExtensionPoint.class);;

private void fireExtensions(VmInstanceSpec spec) {
for (VmBeforeStartOnHypervisorExtensionPoint ext : exts) {
ext.beforeStartVmOnHypervisor(spec);
}
}

@Override
public void run(final FlowTrigger chain, final Map data) {
final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString());
FlowChain fchain = FlowChainBuilder.newSimpleFlowChain();
fchain.setName(String.format("vm-start-on-hypervisor-vm-%s", spec.getVmInventory().getUuid()));
fchain.then(new NoRollbackFlow() {
@Override
public void run(FlowTrigger trigger, Map d) {
new While<>(pluginRgty.getExtensionList(VmBeforeStartOnHypervisorExtensionPoint.class))
.each((ext, comp) -> ext.beforeStartVmOnHypervisor(spec, new Completion(comp) {
@Override
public void success() {
comp.done();
}

fireExtensions(spec);

StartVmOnHypervisorMsg msg = new StartVmOnHypervisorMsg();
msg.setVmSpec(spec);
bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, spec.getDestHost().getUuid());
bus.send(msg, new CloudBusCallBack(chain) {
@Override
public void fail(ErrorCode errorCode) {
comp.addError(errorCode);
comp.done();
}
})).run(new WhileDoneCompletion(trigger) {
@Override
public void done(ErrorCodeList errorCodeList) {
if (errorCodeList.getCauses().size() > 0) {
trigger.fail(errorCodeList.getCauses().get(0));
} else {
trigger.next();
}
}
});
}
});
fchain.then(new NoRollbackFlow() {
@Override
public void run(MessageReply reply) {
if (reply.isSuccess()) {
data.put(VmStartOnHypervisorFlow.class.getName(), true);
chain.next();
} else {
chain.fail(reply.getError());
}
public void run(FlowTrigger trigger, Map d) {
StartVmOnHypervisorMsg msg = new StartVmOnHypervisorMsg();
msg.setVmSpec(spec);
bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, spec.getDestHost().getUuid());
bus.send(msg, new CloudBusCallBack(trigger) {
@Override
public void run(MessageReply reply) {
if (reply.isSuccess()) {
data.put(VmStartOnHypervisorFlow.class.getName(), true);
trigger.next();
} else {
trigger.fail(reply.getError());
}
}
});
}
});
fchain.done(new FlowDoneHandler(chain) {
@Override
public void handle(Map d) {
chain.next();
}
}).error(new FlowErrorHandler(chain) {
@Override
public void handle(ErrorCode errCode, Map d) {
chain.fail(errCode);
}
}).start();
}

@Override
Expand Down
7 changes: 7 additions & 0 deletions compute/src/main/java/org/zstack/compute/vm/VmSystemTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,11 @@ public String desensitizeTag(SystemTag systemTag, String tag) {
}

public static PatternedSystemTag VM_STATE_PAUSED_AFTER_MIGRATE = new PatternedSystemTag(("vmPausedAfterMigrate"), VmInstanceVO.class);

public static String HA_PRE_FENCE_SUSPECT_HOST_UUID_TOKEN = "suspectHostUuid";
public static String HA_PRE_FENCE_ACCESSIBLE_PEER_HOST_UUID_TOKEN = "accessiblePeerHostUuid";
public static PatternedSystemTag HA_PRE_FENCE_PENDING =
new PatternedSystemTag(String.format("haPreFencePending::{%s}::{%s}",
HA_PRE_FENCE_SUSPECT_HOST_UUID_TOKEN,
HA_PRE_FENCE_ACCESSIBLE_PEER_HOST_UUID_TOKEN), VmInstanceVO.class);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class HaStartVmInstanceMsg extends NeedReplyMessage implements VmInstance
private String vmInstanceUuid;
private String judgerClassName;
private List<String> softAvoidHostUuids;
private String accessiblePeerHostUuid;
private String haReason;

public String getJudgerClassName() {
return judgerClassName;
Expand All @@ -29,6 +31,14 @@ public void setSoftAvoidHostUuids(List<String> softAvoidHostUuids) {
this.softAvoidHostUuids = softAvoidHostUuids;
}

public String getAccessiblePeerHostUuid() {
return accessiblePeerHostUuid;
}

public void setAccessiblePeerHostUuid(String accessiblePeerHostUuid) {
this.accessiblePeerHostUuid = accessiblePeerHostUuid;
}

@Override
public String getVmInstanceUuid() {
return vmInstanceUuid;
Expand All @@ -37,4 +47,12 @@ public String getVmInstanceUuid() {
public void setVmInstanceUuid(String vmInstanceUuid) {
this.vmInstanceUuid = vmInstanceUuid;
}

public String getHaReason() {
return haReason;
}

public void setHaReason(String haReason) {
this.haReason = haReason;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package org.zstack.header.vm;

import org.zstack.header.core.Completion;

/**
*/
public interface VmBeforeStartOnHypervisorExtensionPoint {
void beforeStartVmOnHypervisor(VmInstanceSpec spec);
default void beforeStartVmOnHypervisor(VmInstanceSpec spec) {}

default void beforeStartVmOnHypervisor(VmInstanceSpec spec, Completion completion) {
beforeStartVmOnHypervisor(spec);
completion.success();
}
}