Skip to content

Commit b22315d

Browse files
authored
server: event for HA vm start (#9202)
1 parent 7a8066d commit b22315d

13 files changed

Lines changed: 172 additions & 19 deletions

File tree

api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,22 @@
1717
package com.cloud.network;
1818

1919
import java.util.List;
20+
import java.util.Map;
2021

2122
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
2223
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
2324

25+
import com.cloud.deploy.DeploymentPlanner;
2426
import com.cloud.exception.ConcurrentOperationException;
2527
import com.cloud.exception.InsufficientCapacityException;
28+
import com.cloud.exception.OperationTimedoutException;
2629
import com.cloud.exception.ResourceUnavailableException;
2730
import com.cloud.network.router.VirtualRouter;
2831
import com.cloud.user.Account;
2932
import com.cloud.utils.Pair;
3033
import com.cloud.vm.Nic;
34+
import com.cloud.vm.VirtualMachine;
35+
import com.cloud.vm.VirtualMachineProfile;
3136

3237
public interface VirtualNetworkApplianceService {
3338
/**
@@ -62,6 +67,10 @@ public interface VirtualNetworkApplianceService {
6267

6368
VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException;
6469

70+
void startRouterForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlanner planner)
71+
throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
72+
OperationTimedoutException;
73+
6574
VirtualRouter destroyRouter(long routerId, Account caller, Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException;
6675

6776
VirtualRouter findRouter(long routerId);

api/src/main/java/com/cloud/vm/UserVmService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
4343

4444
import com.cloud.dc.DataCenter;
45+
import com.cloud.deploy.DeploymentPlanner;
4546
import com.cloud.exception.ConcurrentOperationException;
4647
import com.cloud.exception.InsufficientCapacityException;
4748
import com.cloud.exception.ManagementServerException;
@@ -113,6 +114,10 @@ UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, E
113114

114115
void startVirtualMachine(UserVm vm) throws OperationTimedoutException, ResourceUnavailableException, InsufficientCapacityException;
115116

117+
void startVirtualMachineForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params,
118+
DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
119+
ConcurrentOperationException, OperationTimedoutException;
120+
116121
UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException;
117122

118123
UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4802,6 +4802,18 @@ protected void HandlePowerStateReport(final String subject, final String senderA
48024802
}
48034803
}
48044804

4805+
private ApiCommandResourceType getApiCommandResourceTypeForVm(VirtualMachine vm) {
4806+
switch (vm.getType()) {
4807+
case DomainRouter:
4808+
return ApiCommandResourceType.DomainRouter;
4809+
case ConsoleProxy:
4810+
return ApiCommandResourceType.ConsoleProxy;
4811+
case SecondaryStorageVm:
4812+
return ApiCommandResourceType.SystemVm;
4813+
}
4814+
return ApiCommandResourceType.VirtualMachine;
4815+
}
4816+
48054817
private void handlePowerOnReportWithNoPendingJobsOnVM(final VMInstanceVO vm) {
48064818
Host host = _hostDao.findById(vm.getHostId());
48074819
Host poweredHost = _hostDao.findById(vm.getPowerHostId());
@@ -4849,7 +4861,7 @@ private void handlePowerOnReportWithNoPendingJobsOnVM(final VMInstanceVO vm) {
48494861
+ " -> Running) from out-of-context transition. VM network environment may need to be reset");
48504862

48514863
ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, vm.getDomainId(),
4852-
EventTypes.EVENT_VM_START, "Out of band VM power on", vm.getId(), ApiCommandResourceType.VirtualMachine.toString());
4864+
EventTypes.EVENT_VM_START, "Out of band VM power on", vm.getId(), getApiCommandResourceTypeForVm(vm).toString());
48534865
s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Running state according to power-on report from hypervisor");
48544866
break;
48554867

@@ -4884,7 +4896,7 @@ private void handlePowerOffReportWithNoPendingJobsOnVM(final VMInstanceVO vm) {
48844896
case Running:
48854897
case Stopped:
48864898
ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,vm.getDomainId(),
4887-
EventTypes.EVENT_VM_STOP, "Out of band VM power off", vm.getId(), ApiCommandResourceType.VirtualMachine.toString());
4899+
EventTypes.EVENT_VM_STOP, "Out of band VM power off", vm.getId(), getApiCommandResourceTypeForVm(vm).toString());
48884900
case Migrating:
48894901
if (s_logger.isInfoEnabled()) {
48904902
s_logger.info(

server/src/main/java/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@
2222
import javax.naming.ConfigurationException;
2323

2424
import org.apache.cloudstack.consoleproxy.ConsoleAccessManager;
25-
import org.apache.log4j.Logger;
26-
2725
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
2826
import org.apache.cloudstack.framework.security.keys.KeysManager;
2927
import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
28+
import org.apache.log4j.Logger;
3029

3130
import com.cloud.agent.AgentManager;
3231
import com.cloud.agent.api.GetVncPortAnswer;
3332
import com.cloud.agent.api.GetVncPortCommand;
3433
import com.cloud.agent.api.StartupProxyCommand;
34+
import com.cloud.deploy.DeploymentPlanner;
3535
import com.cloud.host.HostVO;
3636
import com.cloud.host.dao.HostDao;
3737
import com.cloud.info.ConsoleProxyInfo;
@@ -41,7 +41,9 @@
4141
import com.cloud.vm.ConsoleProxyVO;
4242
import com.cloud.vm.UserVmVO;
4343
import com.cloud.vm.VMInstanceVO;
44+
import com.cloud.vm.VirtualMachine;
4445
import com.cloud.vm.VirtualMachineManager;
46+
import com.cloud.vm.VirtualMachineProfile;
4547
import com.cloud.vm.dao.ConsoleProxyDao;
4648
import com.cloud.vm.dao.UserVmDao;
4749
import com.cloud.vm.dao.VMInstanceDao;
@@ -182,6 +184,11 @@ public ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting) {
182184
return null;
183185
}
184186

187+
@Override
188+
public void startProxyForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params,
189+
DeploymentPlanner planner) {
190+
}
191+
185192
@Override
186193
public boolean destroyProxy(long proxyVmId) {
187194
return false;

server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManager.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,20 @@
1616
// under the License.
1717
package com.cloud.consoleproxy;
1818

19-
import com.cloud.utils.component.Manager;
20-
import com.cloud.vm.ConsoleProxyVO;
19+
import java.util.Map;
2120

2221
import org.apache.cloudstack.framework.config.ConfigKey;
2322

23+
import com.cloud.deploy.DeploymentPlanner;
24+
import com.cloud.exception.ConcurrentOperationException;
25+
import com.cloud.exception.InsufficientCapacityException;
26+
import com.cloud.exception.OperationTimedoutException;
27+
import com.cloud.exception.ResourceUnavailableException;
28+
import com.cloud.utils.component.Manager;
29+
import com.cloud.vm.ConsoleProxyVO;
30+
import com.cloud.vm.VirtualMachine;
31+
import com.cloud.vm.VirtualMachineProfile;
32+
2433
public interface ConsoleProxyManager extends Manager, ConsoleProxyService {
2534

2635
int DEFAULT_PROXY_CAPACITY = 50;
@@ -53,6 +62,10 @@ public interface ConsoleProxyManager extends Manager, ConsoleProxyService {
5362

5463
ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting);
5564

65+
void startProxyForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlanner planner)
66+
throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
67+
OperationTimedoutException;
68+
5669
boolean stopProxy(long proxyVmId);
5770

5871
boolean rebootProxy(long proxyVmId);

server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@
7575
import com.cloud.dc.dao.HostPodDao;
7676
import com.cloud.deploy.DataCenterDeployment;
7777
import com.cloud.deploy.DeployDestination;
78+
import com.cloud.deploy.DeploymentPlanner;
79+
import com.cloud.event.ActionEvent;
80+
import com.cloud.event.EventTypes;
7881
import com.cloud.exception.ConcurrentOperationException;
7982
import com.cloud.exception.InsufficientAddressCapacityException;
8083
import com.cloud.exception.InsufficientCapacityException;
@@ -493,6 +496,14 @@ public ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting) {
493496
return null;
494497
}
495498

499+
@Override
500+
@ActionEvent(eventType = EventTypes.EVENT_PROXY_START, eventDescription = "restarting console proxy VM for HA", async = true)
501+
public void startProxyForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params,
502+
DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
503+
ConcurrentOperationException, OperationTimedoutException {
504+
virtualMachineManager.advanceStart(vm.getUuid(), params, planner);
505+
}
506+
496507
public ConsoleProxyVO assignProxyFromRunningPool(long dataCenterId) {
497508

498509
if (s_logger.isDebugEnabled()) {

server/src/main/java/com/cloud/ha/HighAvailabilityManagerImpl.java

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import javax.inject.Inject;
2929
import javax.naming.ConfigurationException;
3030

31+
import org.apache.cloudstack.api.ApiCommandResourceType;
32+
import org.apache.cloudstack.context.CallContext;
3133
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
3234
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
3335
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
@@ -66,13 +68,14 @@
6668
import com.cloud.host.Status;
6769
import com.cloud.host.dao.HostDao;
6870
import com.cloud.hypervisor.Hypervisor.HypervisorType;
71+
import com.cloud.network.VpcVirtualNetworkApplianceService;
6972
import com.cloud.resource.ResourceManager;
7073
import com.cloud.server.ManagementServer;
7174
import com.cloud.service.ServiceOfferingVO;
7275
import com.cloud.service.dao.ServiceOfferingDao;
76+
import com.cloud.storage.Storage.StoragePoolType;
7377
import com.cloud.storage.StorageManager;
7478
import com.cloud.storage.VolumeVO;
75-
import com.cloud.storage.Storage.StoragePoolType;
7679
import com.cloud.storage.dao.GuestOSCategoryDao;
7780
import com.cloud.storage.dao.GuestOSDao;
7881
import com.cloud.storage.dao.VolumeDao;
@@ -81,6 +84,7 @@
8184
import com.cloud.utils.component.ManagerBase;
8285
import com.cloud.utils.concurrency.NamedThreadFactory;
8386
import com.cloud.utils.exception.CloudRuntimeException;
87+
import com.cloud.vm.UserVmManager;
8488
import com.cloud.vm.VMInstanceVO;
8589
import com.cloud.vm.VirtualMachine;
8690
import com.cloud.vm.VirtualMachineManager;
@@ -144,6 +148,10 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements Configur
144148
VolumeDao volumeDao;
145149
@Inject
146150
DataStoreProviderManager dataStoreProviderMgr;
151+
@Inject
152+
VpcVirtualNetworkApplianceService routerService;
153+
@Inject
154+
UserVmManager userVmManager;
147155

148156
long _serverId;
149157

@@ -437,6 +445,36 @@ public void scheduleRestart(VMInstanceVO vm, boolean investigate) {
437445

438446
}
439447

448+
private void startVm(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params,
449+
DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
450+
ConcurrentOperationException, OperationTimedoutException {
451+
CallContext ctx = CallContext.register(CallContext.current(), ApiCommandResourceType.VirtualMachine);
452+
ctx.setEventResourceId(vm.getId());
453+
try {
454+
switch (vm.getType()) {
455+
case DomainRouter:
456+
ctx.setEventResourceType(ApiCommandResourceType.DomainRouter);
457+
routerService.startRouterForHA(vm, params, planner);
458+
break;
459+
case ConsoleProxy:
460+
ctx.setEventResourceType(ApiCommandResourceType.ConsoleProxy);
461+
consoleProxyManager.startProxyForHA(vm, params, planner);
462+
break;
463+
case SecondaryStorageVm:
464+
ctx.setEventResourceType(ApiCommandResourceType.SystemVm);
465+
secondaryStorageVmManager.startSecStorageVmForHA(vm, params, planner);
466+
break;
467+
case User:
468+
userVmManager.startVirtualMachineForHA(vm, params, planner);
469+
break;
470+
default:
471+
_itMgr.advanceStart(vm.getUuid(), params, planner);
472+
}
473+
} finally {
474+
CallContext.unregister();
475+
}
476+
}
477+
440478
protected Long restart(final HaWorkVO work) {
441479
s_logger.debug("RESTART with HAWORK");
442480
List<HaWorkVO> items = _haDao.listFutureHaWorkForVm(work.getInstanceId(), work.getId());
@@ -628,10 +666,10 @@ protected Long restart(final HaWorkVO work) {
628666
}
629667
}
630668
// First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency.
631-
_itMgr.advanceStart(vm.getUuid(), params, null);
632-
}catch (InsufficientCapacityException e){
669+
startVm(vm, params, null);
670+
} catch (InsufficientCapacityException e){
633671
s_logger.warn("Failed to deploy vm " + vmId + " with original planner, sending HAPlanner");
634-
_itMgr.advanceStart(vm.getUuid(), params, _haPlanners.get(0));
672+
startVm(vm, params, _haPlanners.get(0));
635673
}
636674

637675
VMInstanceVO started = _instanceDao.findById(vm.getId());
@@ -653,15 +691,15 @@ protected Long restart(final HaWorkVO work) {
653691
} catch (final ResourceUnavailableException e) {
654692
s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
655693
_alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
656-
hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
694+
hostDesc, "The resource is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
657695
} catch (ConcurrentOperationException e) {
658696
s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
659697
_alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
660698
hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
661699
} catch (OperationTimedoutException e) {
662700
s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
663701
_alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
664-
hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
702+
hostDesc, "The operation timed out while trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
665703
}
666704
vm = _itMgr.findById(vm.getId());
667705
work.setUpdateTime(vm.getUpdated());

server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
import com.cloud.dc.dao.HostPodDao;
124124
import com.cloud.dc.dao.VlanDao;
125125
import com.cloud.deploy.DeployDestination;
126+
import com.cloud.deploy.DeploymentPlanner;
126127
import com.cloud.domain.Domain;
127128
import com.cloud.event.ActionEvent;
128129
import com.cloud.event.ActionEventUtils;
@@ -3010,6 +3011,14 @@ public VirtualRouter startRouter(final long routerId, final boolean reprogramNet
30103011
return virtualRouter;
30113012
}
30123013

3014+
@Override
3015+
@ActionEvent(eventType = EventTypes.EVENT_ROUTER_START, eventDescription = "restarting router VM for HA", async = true)
3016+
public void startRouterForHA(VirtualMachine vm, Map<Param, Object> params, DeploymentPlanner planner)
3017+
throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
3018+
OperationTimedoutException {
3019+
_itMgr.advanceStart(vm.getUuid(), params, planner);
3020+
}
3021+
30133022
@Override
30143023
public List<VirtualRouter> getRoutersForNetwork(final long networkId) {
30153024
final List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);

server/src/main/java/com/cloud/storage/secondary/SecondaryStorageVmManager.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,24 @@
1717
package com.cloud.storage.secondary;
1818

1919
import java.util.List;
20+
import java.util.Map;
2021

2122
import org.apache.cloudstack.framework.config.ConfigKey;
2223

2324
import com.cloud.agent.api.Command;
2425
import com.cloud.agent.api.StartupCommand;
26+
import com.cloud.deploy.DeploymentPlanner;
27+
import com.cloud.exception.ConcurrentOperationException;
28+
import com.cloud.exception.InsufficientCapacityException;
29+
import com.cloud.exception.OperationTimedoutException;
30+
import com.cloud.exception.ResourceUnavailableException;
2531
import com.cloud.host.HostVO;
2632
import com.cloud.utils.Pair;
2733
import com.cloud.utils.component.Manager;
2834
import com.cloud.vm.SecondaryStorageVm;
2935
import com.cloud.vm.SecondaryStorageVmVO;
36+
import com.cloud.vm.VirtualMachine;
37+
import com.cloud.vm.VirtualMachineProfile;
3038

3139
public interface SecondaryStorageVmManager extends Manager {
3240

@@ -47,6 +55,10 @@ public interface SecondaryStorageVmManager extends Manager {
4755

4856
public SecondaryStorageVmVO startSecStorageVm(long ssVmVmId);
4957

58+
void startSecStorageVmForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params,
59+
DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
60+
ConcurrentOperationException, OperationTimedoutException;
61+
5062
public boolean stopSecStorageVm(long ssVmVmId);
5163

5264
public boolean rebootSecStorageVm(long ssVmVmId);

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3230,6 +3230,14 @@ public void startVirtualMachine(UserVm vm) throws OperationTimedoutException, Re
32303230
_itMgr.advanceStart(vm.getUuid(), null, null);
32313231
}
32323232

3233+
@Override
3234+
@ActionEvent(eventType = EventTypes.EVENT_VM_START, eventDescription = "restarting VM for HA", async = true)
3235+
public void startVirtualMachineForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params,
3236+
DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
3237+
ConcurrentOperationException, OperationTimedoutException {
3238+
_itMgr.advanceStart(vm.getUuid(), params, planner);
3239+
}
3240+
32333241
@Override
32343242
@ActionEvent(eventType = EventTypes.EVENT_VM_REBOOT, eventDescription = "rebooting Vm", async = true)
32353243
public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {

0 commit comments

Comments
 (0)