side-by-side VM sync management at manager level

This commit is contained in:
Kelven Yang 2013-11-20 17:46:45 -08:00
parent 2d42b2d1ab
commit 278ef81a83
26 changed files with 2273 additions and 56 deletions

View File

@ -213,7 +213,12 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
* UserBareMetal is only used for selecting VirtualMachineGuru, there is no
* VM with this type. UserBareMetal should treat exactly as User.
*/
UserBareMetal(false);
UserBareMetal(false),
/*
* General VM type for queuing VM orchestration work
*/
Instance(false);
boolean _isUsedBySystem;

View File

@ -16,11 +16,13 @@
// under the License.
package org.apache.cloudstack.api;
import java.io.Serializable;
// This interface is a contract that getId() will give the internal
// ID of an entity which extends this interface
// Any class having an internal ID in db table/schema should extend this
// For example, all ControlledEntity, OwnedBy would have an internal ID
public interface InternalIdentity {
public interface InternalIdentity extends Serializable {
long getId();
}

View File

@ -197,6 +197,18 @@ public class CallContext {
}
return register(user, account);
}
public static CallContext register(long callingUserId, long callingAccountId, String contextId) throws CloudAuthenticationException {
Account account = s_entityMgr.findById(Account.class, callingAccountId);
if (account == null) {
throw new CloudAuthenticationException("The account is no longer current.").add(Account.class, Long.toString(callingAccountId));
}
User user = s_entityMgr.findById(User.class, callingUserId);
if (user == null) {
throw new CloudAuthenticationException("The user is no longer current.").add(User.class, Long.toString(callingUserId));
}
return register(user, account, contextId);
}
public static void unregisterAll() {
while ( unregister() != null ) {

View File

@ -108,8 +108,13 @@ public interface VirtualMachineManager extends Manager {
void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) throws InsufficientCapacityException,
ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
void orchestrateStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) throws InsufficientCapacityException,
ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
void advanceStop(String vmUuid, boolean cleanupEvenIfUnableToStop) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException;
void orchestrateStop(String vmUuid, boolean cleanupEvenIfUnableToStop) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException;
void advanceExpunge(String vmUuid) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException;
void destroy(String vmUuid) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException;
@ -117,11 +122,17 @@ public interface VirtualMachineManager extends Manager {
void migrateAway(String vmUuid, long hostId) throws InsufficientServerCapacityException;
void migrate(String vmUuid, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException;
void orchestrateMigrate(String vmUuid, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException;
void migrateWithStorage(String vmUuid, long srcId, long destId, Map<Volume, StoragePool> volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException;
void orchestrateMigrateWithStorage(String vmUuid, long srcId, long destId, Map<Volume, StoragePool> volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException;
void reboot(String vmUuid, Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ResourceUnavailableException;
void orchestrateReboot(String vmUuid, Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ResourceUnavailableException;
void advanceReboot(String vmUuid, Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ResourceUnavailableException,
ConcurrentOperationException, OperationTimedoutException;
@ -137,6 +148,8 @@ public interface VirtualMachineManager extends Manager {
VirtualMachine findById(long vmId);
void storageMigration(String vmUuid, StoragePool storagePoolId);
void orchestrateStorageMigration(String vmUuid, StoragePool storagePoolId);
/**
* @param vmInstance
@ -161,7 +174,11 @@ public interface VirtualMachineManager extends Manager {
* @throws InsufficientCapacityException
*/
NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException,
ResourceUnavailableException, InsufficientCapacityException;
ResourceUnavailableException, InsufficientCapacityException;
NicProfile orchestrateAddVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException,
ResourceUnavailableException, InsufficientCapacityException;
/**
* @param vm
@ -172,6 +189,8 @@ public interface VirtualMachineManager extends Manager {
*/
boolean removeNicFromVm(VirtualMachine vm, Nic nic) throws ConcurrentOperationException, ResourceUnavailableException;
boolean orchestrateRemoveNicFromVm(VirtualMachine vm, Nic nic) throws ConcurrentOperationException, ResourceUnavailableException;
/**
* @param vm
* @param network
@ -181,6 +200,8 @@ public interface VirtualMachineManager extends Manager {
* @throws ConcurrentOperationException
*/
boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException;
boolean orchestrateRemoveVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException;
/**
* @param nic
@ -196,12 +217,15 @@ public interface VirtualMachineManager extends Manager {
*/
VirtualMachineTO toVmTO(VirtualMachineProfile profile);
VirtualMachine reConfigureVm(String vmUuid, ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException;
VirtualMachine orchestrateReConfigureVm(String vmUuid, ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException;
void findHostAndMigrate(String vmUuid, Long newSvcOfferingId, DeploymentPlanner.ExcludeList excludeHostList) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException;
void migrateForScale(String vmUuid, long srcHostId, DeployDestination dest, Long newSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException;
void orchestrateMigrateForScale(String vmUuid, long srcHostId, DeployDestination dest, Long newSvcOfferingId) throws ResourceUnavailableException, ConcurrentOperationException;
}

View File

@ -50,6 +50,8 @@ public interface AlertManager extends Manager {
public static final short ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 24;
public static final short ALERT_TYPE_LOCAL_STORAGE = 25;
public static final short ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = 26; // Generated when the resource limit exceeds the limit. Currently used for recurring snapshots only
public static final short ALERT_TYPE_SYNC = 27;
static final ConfigKey<Double> StorageCapacityThreshold = new ConfigKey<Double>(Double.class, "cluster.storage.capacity.notificationthreshold", "Alert", "0.75",
"Percentage (as a value between 0 and 1) of storage utilization above which alerts will be sent about low storage available.", true, ConfigKey.Scope.Cluster, null);

View File

@ -0,0 +1,45 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import java.io.Serializable;
public class VmWork implements Serializable {
private static final long serialVersionUID = -6946320465729853589L;
long userId;
long accountId;
long vmId;
public VmWork(long userId, long accountId, long vmId) {
this.userId = userId;
this.accountId = accountId;
this.vmId = vmId;
}
public long getUserId() {
return userId;
}
public long getAccountId() {
return accountId;
}
public long getVmId() {
return vmId;
}
}

View File

@ -67,5 +67,6 @@
<bean id="virtualMachineEntityImpl" class="org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntityImpl" />
<bean id="virtualMachinePowerStateSyncImpl" class="com.cloud.vm.VirtualMachinePowerStateSyncImpl" />
</beans>

View File

@ -19,7 +19,6 @@ package com.cloud.vm;
import java.util.Map;
import com.cloud.agent.api.HostVmStateReportEntry;
import com.cloud.vm.VirtualMachine.PowerState;
public interface VirtualMachinePowerStateSync {
@ -28,5 +27,5 @@ public interface VirtualMachinePowerStateSync {
void processHostVmStateReport(long hostId, Map<String, HostVmStateReportEntry> report);
// to adapt legacy ping report
void processHostVmStatePingReport(long hostId, Map<String, PowerState> report);
void processHostVmStatePingReport(long hostId, Map<String, HostVmStateReportEntry> report);
}

View File

@ -27,7 +27,6 @@ import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.PublishScope;
import com.cloud.agent.api.HostVmStateReportEntry;
import com.cloud.vm.VirtualMachine.PowerState;
import com.cloud.vm.dao.VMInstanceDao;
public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStateSync {
@ -56,11 +55,11 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat
}
@Override
public void processHostVmStatePingReport(long hostId, Map<String, PowerState> report) {
public void processHostVmStatePingReport(long hostId, Map<String, HostVmStateReportEntry> report) {
if(s_logger.isDebugEnabled())
s_logger.debug("Process host VM state report from ping process. host: " + hostId);
Map<Long, VirtualMachine.PowerState> translatedInfo = convertHostPingInfos(report);
Map<Long, VirtualMachine.PowerState> translatedInfo = convertToInfos(report);
processReport(hostId, translatedInfo);
}
@ -80,25 +79,6 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat
}
}
}
private Map<Long, VirtualMachine.PowerState> convertHostPingInfos(Map<String, PowerState> states) {
final HashMap<Long, VirtualMachine.PowerState> map = new HashMap<Long, VirtualMachine.PowerState>();
if (states == null) {
return map;
}
for (Map.Entry<String, PowerState> entry : states.entrySet()) {
VMInstanceVO vm = findVM(entry.getKey());
if(vm != null) {
map.put(vm.getId(), entry.getValue());
break;
} else {
s_logger.info("Unable to find matched VM in CloudStack DB. name: " + entry.getKey());
}
}
return map;
}
private Map<Long, VirtualMachine.PowerState> convertToInfos(Map<String, HostVmStateReportEntry> states) {
final HashMap<Long, VirtualMachine.PowerState> map = new HashMap<Long, VirtualMachine.PowerState>();

View File

@ -0,0 +1,42 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import com.cloud.network.Network;
public class VmWorkAddVmToNetwork extends VmWork {
private static final long serialVersionUID = 8861516006586736813L;
Network network;
NicProfile requstedNicProfile;
public VmWorkAddVmToNetwork(long userId, long accountId, long vmId,
Network network, NicProfile requested) {
super(userId, accountId, vmId);
this.network = network;
this.requstedNicProfile = requested;
}
public Network getNetwork() {
return this.network;
}
public NicProfile getRequestedNicProfile() {
return this.requstedNicProfile;
}
}

View File

@ -0,0 +1,152 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
import org.apache.cloudstack.jobs.JobInfo;
import com.cloud.utils.component.AdapterBase;
import com.cloud.vm.dao.VMInstanceDao;
public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatcher {
private static final Logger s_logger = Logger.getLogger(VmWorkJobDispatcher.class);
public static final String VM_WORK_QUEUE = "VmWorkJobQueue";
public static final String VM_WORK_JOB_DISPATCHER = "VmWorkJobDispatcher";
public static final String VM_WORK_JOB_WAKEUP_DISPATCHER = "VmWorkJobWakeupDispatcher";
@Inject private VirtualMachineManagerImpl _vmMgr;
@Inject private AsyncJobManager _asyncJobMgr;
@Inject private VMInstanceDao _instanceDao;
@Override
public void runJob(AsyncJob job) {
VmWork work = null;
try {
String cmd = job.getCmd();
assert(cmd != null);
if(s_logger.isDebugEnabled())
s_logger.debug("Run VM work job: " + cmd);
Class<?> workClz = null;
try {
workClz = Class.forName(job.getCmd());
} catch(ClassNotFoundException e) {
s_logger.error("VM work class " + cmd + " is not found", e);
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, e.getMessage());
return;
}
work = VmWorkSerializer.deserialize(workClz, job.getCmdInfo());
assert(work != null);
if(work == null) {
s_logger.error("Unable to deserialize VM work " + job.getCmd() + ", job info: " + job.getCmdInfo());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, "Unable to deserialize VM work");
return;
}
CallContext.register(work.getUserId(), work.getAccountId(), job.getRelated());
VMInstanceVO vm = _instanceDao.findById(work.getVmId());
if (vm == null) {
s_logger.info("Unable to find vm " + work.getVmId());
}
assert(vm != null);
if(work instanceof VmWorkStart) {
VmWorkStart workStart = (VmWorkStart)work;
_vmMgr.orchestrateStart(vm.getUuid(), workStart.getParams(), workStart.getPlan());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
} else if(work instanceof VmWorkStop) {
VmWorkStop workStop = (VmWorkStop)work;
_vmMgr.orchestrateStop(vm.getUuid(), workStop.isCleanup());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
} else if(work instanceof VmWorkMigrate) {
VmWorkMigrate workMigrate = (VmWorkMigrate)work;
_vmMgr.orchestrateMigrate(vm.getUuid(), workMigrate.getSrcHostId(), workMigrate.getDeployDestination());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
} else if(work instanceof VmWorkMigrateWithStorage) {
VmWorkMigrateWithStorage workMigrateWithStorage = (VmWorkMigrateWithStorage)work;
_vmMgr.orchestrateMigrateWithStorage(vm.getUuid(),
workMigrateWithStorage.getSrcHostId(),
workMigrateWithStorage.getDestHostId(),
workMigrateWithStorage.getVolumeToPool());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
} else if(work instanceof VmWorkMigrateForScale) {
VmWorkMigrateForScale workMigrateForScale = (VmWorkMigrateForScale)work;
_vmMgr.orchestrateMigrateForScale(vm.getUuid(),
workMigrateForScale.getSrcHostId(),
workMigrateForScale.getDeployDestination(),
workMigrateForScale.getNewServiceOfferringId());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
} else if(work instanceof VmWorkReboot) {
VmWorkReboot workReboot = (VmWorkReboot)work;
_vmMgr.orchestrateReboot(vm.getUuid(), workReboot.getParams());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
} else if(work instanceof VmWorkAddVmToNetwork) {
VmWorkAddVmToNetwork workAddVmToNetwork = (VmWorkAddVmToNetwork)work;
NicProfile nic = _vmMgr.orchestrateAddVmToNetwork(vm, workAddVmToNetwork.getNetwork(),
workAddVmToNetwork.getRequestedNicProfile());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0,
JobSerializerHelper.toObjectSerializedString(nic));
} else if(work instanceof VmWorkRemoveNicFromVm) {
VmWorkRemoveNicFromVm workRemoveNicFromVm = (VmWorkRemoveNicFromVm)work;
boolean result = _vmMgr.orchestrateRemoveNicFromVm(vm, workRemoveNicFromVm.getNic());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0,
JobSerializerHelper.toObjectSerializedString(new Boolean(result)));
} else if(work instanceof VmWorkRemoveVmFromNetwork) {
VmWorkRemoveVmFromNetwork workRemoveVmFromNetwork = (VmWorkRemoveVmFromNetwork)work;
boolean result = _vmMgr.orchestrateRemoveVmFromNetwork(vm,
workRemoveVmFromNetwork.getNetwork(), workRemoveVmFromNetwork.getBroadcastUri());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0,
JobSerializerHelper.toObjectSerializedString(new Boolean(result)));
} else if(work instanceof VmWorkReconfigure) {
VmWorkReconfigure workReconfigure = (VmWorkReconfigure)work;
_vmMgr.reConfigureVm(vm.getUuid(), workReconfigure.getNewServiceOffering(),
workReconfigure.isSameHost());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
} else if(work instanceof VmWorkStorageMigration) {
VmWorkStorageMigration workStorageMigration = (VmWorkStorageMigration)work;
_vmMgr.orchestrateStorageMigration(vm.getUuid(), workStorageMigration.getDestStoragePool());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.SUCCEEDED, 0, null);
} else {
assert(false);
s_logger.error("Unhandled VM work command: " + job.getCmd());
RuntimeException e = new RuntimeException("Unsupported VM work command: " + job.getCmd());
String exceptionJson = JobSerializerHelper.toSerializedString(e);
s_logger.error("Serialize exception object into json: " + exceptionJson);
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, exceptionJson);
}
} catch(Throwable e) {
s_logger.error("Unable to complete " + job, e);
String exceptionJson = JobSerializerHelper.toSerializedString(e);
s_logger.info("Serialize exception object into json: " + exceptionJson);
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, exceptionJson);
} finally {
CallContext.unregister();
}
}
}

View File

@ -0,0 +1,86 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import java.util.HashMap;
import java.util.Map;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Pod;
import com.cloud.deploy.DeployDestination;
import com.cloud.host.Host;
import com.cloud.org.Cluster;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
import com.cloud.utils.db.EntityManager;
public class VmWorkMigrate extends VmWork {
private static final long serialVersionUID = 1689203333114836522L;
Long zoneId;
Long podId;
Long clusterId;
Long hostId;
private Map<String, String> storage;
long srcHostId;
public VmWorkMigrate(long userId, long accountId, long vmId, long srcHostId, DeployDestination dst) {
super(userId, accountId, vmId);
this.srcHostId = srcHostId;
zoneId = dst.getDataCenter() != null ? dst.getDataCenter().getId() : null;
podId = dst.getPod() != null ? dst.getPod().getId() : null;
clusterId = dst.getCluster() != null ? dst.getCluster().getId() : null;
hostId = dst.getHost() != null ? dst.getHost().getId() : null;
if (dst.getStorageForDisks() != null) {
storage = new HashMap<String, String>(dst.getStorageForDisks().size());
for (Map.Entry<Volume, StoragePool> entry : dst.getStorageForDisks().entrySet()) {
storage.put(entry.getKey().getUuid(), entry.getValue().getUuid());
}
} else {
storage = null;
}
}
public DeployDestination getDeployDestination() {
DataCenter zone = zoneId != null ? s_entityMgr.findById(DataCenter.class, zoneId) : null;
Pod pod = podId != null ? s_entityMgr.findById(Pod.class, podId) : null;
Cluster cluster = clusterId != null ? s_entityMgr.findById(Cluster.class, clusterId) : null;
Host host = hostId != null ? s_entityMgr.findById(Host.class, hostId) : null;
Map<Volume, StoragePool> vols = null;
if (storage != null) {
vols = new HashMap<Volume, StoragePool>(storage.size());
for (Map.Entry<String, String> entry : storage.entrySet()) {
vols.put(s_entityMgr.findByUuid(Volume.class, entry.getKey()), s_entityMgr.findByUuid(StoragePool.class, entry.getValue()));
}
}
DeployDestination dest = new DeployDestination(zone, pod, cluster, host, vols);
return dest;
}
public long getSrcHostId() {
return srcHostId;
}
static private EntityManager s_entityMgr;
static public void init(EntityManager entityMgr) {
s_entityMgr = entityMgr;
}
}

View File

@ -0,0 +1,48 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import com.cloud.deploy.DeployDestination;
public class VmWorkMigrateForScale extends VmWork {
private static final long serialVersionUID = 6854870395568389613L;
long srcHostId;
DeployDestination deployDestination;
Long newSvcOfferingId;
public VmWorkMigrateForScale(long userId, long accountId, long vmId, long srcHostId,
DeployDestination dest, Long newSvcOfferingId) {
super(userId, accountId, vmId);
this.srcHostId = srcHostId;
this.deployDestination = dest;
this.newSvcOfferingId = newSvcOfferingId;
}
public long getSrcHostId() {
return srcHostId;
}
public DeployDestination getDeployDestination() {
return this.deployDestination;
}
public Long getNewServiceOfferringId() {
return this.newSvcOfferingId;
}
}

View File

@ -0,0 +1,52 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import java.util.Map;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
public class VmWorkMigrateWithStorage extends VmWork {
private static final long serialVersionUID = -5626053872453569165L;
long srcHostId;
long destHostId;
Map<Volume, StoragePool> volumeToPool;
public VmWorkMigrateWithStorage(long userId, long accountId, long vmId, long srcHostId,
long destHostId, Map<Volume, StoragePool> volumeToPool) {
super(userId, accountId, vmId);
this.srcHostId = srcHostId;
this.destHostId = destHostId;
this.volumeToPool = volumeToPool;
}
public long getSrcHostId() {
return this.srcHostId;
}
public long getDestHostId() {
return this.destHostId;
}
public Map<Volume, StoragePool> getVolumeToPool() {
return this.volumeToPool;
}
}

View File

@ -0,0 +1,68 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
public class VmWorkReboot extends VmWork {
private static final long serialVersionUID = 195907627459759933L;
// use serialization friendly map
private Map<String, String> rawParams;
public VmWorkReboot(long userId, long accountId, long vmId, Map<VirtualMachineProfile.Param, Object> params) {
super(userId, accountId, vmId);
setParams(params);
}
public Map<String, String> getRawParams() {
return rawParams;
}
public void setRawParams(Map<String, String> params) {
rawParams = params;
}
public Map<VirtualMachineProfile.Param, Object> getParams() {
Map<VirtualMachineProfile.Param, Object> map = new HashMap<VirtualMachineProfile.Param, Object>();
if(rawParams != null) {
for(Map.Entry<String, String> entry : rawParams.entrySet()) {
VirtualMachineProfile.Param key = new VirtualMachineProfile.Param(entry.getKey());
Object val = JobSerializerHelper.fromObjectSerializedString(entry.getValue());
map.put(key, val);
}
}
return map;
}
public void setParams(Map<VirtualMachineProfile.Param, Object> params) {
if(params != null) {
rawParams = new HashMap<String, String>();
for(Map.Entry<VirtualMachineProfile.Param, Object> entry : params.entrySet()) {
rawParams.put(entry.getKey().getName(), JobSerializerHelper.toObjectSerializedString(
entry.getValue() instanceof Serializable ? (Serializable)entry.getValue() : entry.getValue().toString()));
}
}
}
}

View File

@ -0,0 +1,43 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import com.cloud.offering.ServiceOffering;
public class VmWorkReconfigure extends VmWork {
private static final long serialVersionUID = -4517030323758086615L;
ServiceOffering newServiceOffering;
boolean sameHost;
public VmWorkReconfigure(long userId, long accountId, long vmId,
ServiceOffering newServiceOffering, boolean sameHost) {
super(userId, accountId, vmId);
this.newServiceOffering = newServiceOffering;
this.sameHost = sameHost;
}
public ServiceOffering getNewServiceOffering() {
return this.newServiceOffering;
}
public boolean isSameHost() {
return this.sameHost;
}
}

View File

@ -0,0 +1,33 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
public class VmWorkRemoveNicFromVm extends VmWork {
private static final long serialVersionUID = -4265657031064437923L;
Nic nic;
public VmWorkRemoveNicFromVm(long userId, long accountId, long vmId, Nic nic) {
super(userId, accountId, vmId);
this.nic = nic;
}
public Nic getNic() {
return this.nic;
}
}

View File

@ -0,0 +1,43 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import java.net.URI;
import com.cloud.network.Network;
public class VmWorkRemoveVmFromNetwork extends VmWork {
private static final long serialVersionUID = -5070392905642149925L;
Network network;
URI broadcastUri;
public VmWorkRemoveVmFromNetwork(long userId, long accountId, long vmId, Network network, URI broadcastUri) {
super(userId, accountId, vmId);
this.network = network;
this.broadcastUri = broadcastUri;
}
public Network getNetwork() {
return this.network;
}
public URI getBroadcastUri() {
return this.broadcastUri;
}
}

View File

@ -0,0 +1,75 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
public class VmWorkSerializer {
static class StringMapTypeAdapter implements JsonDeserializer<Map> {
@Override
public Map deserialize(JsonElement src, Type srcType, JsonDeserializationContext context) throws JsonParseException {
Map<String, String> obj = new HashMap<String, String>();
JsonObject json = src.getAsJsonObject();
for (Entry<String, JsonElement> entry : json.entrySet()) {
obj.put(entry.getKey(), entry.getValue().getAsString());
}
return obj;
}
}
protected static Gson s_gson;
static {
GsonBuilder gBuilder = new GsonBuilder();
gBuilder.setVersion(1.3);
gBuilder.registerTypeAdapter(Map.class, new StringMapTypeAdapter());
s_gson = gBuilder.create();
}
public static String serialize(VmWork work) {
// TODO: there are way many generics, too tedious to get serialization work under GSON
// use java binary serialization instead
//
return JobSerializerHelper.toObjectSerializedString(work);
// return s_gson.toJson(work);
}
public static <T extends VmWork> T deserialize(Class<?> clazz, String workInJsonText) {
// TODO: there are way many generics, too tedious to get serialization work under GSON
// use java binary serialization instead
//
return (T)JobSerializerHelper.fromObjectSerializedString(workInJsonText);
// return (T)s_gson.fromJson(workInJsonText, clazz);
}
}

View File

@ -0,0 +1,125 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.utils.Journal;
public class VmWorkStart extends VmWork {
private static final long serialVersionUID = 9038937399817468894L;
private static final Logger s_logger = Logger.getLogger(VmWorkStart.class);
long dcId;
Long podId;
Long clusterId;
Long hostId;
Long poolId;
ExcludeList avoids;
Long physicalNetworkId;
String reservationId;
String journalName;
// use serialization friendly map
private Map<String, String> rawParams;
public VmWorkStart(long userId, long accountId, long vmId) {
super(userId, accountId, vmId);
}
public DeploymentPlan getPlan() {
if(podId != null || clusterId != null || hostId != null || poolId != null || physicalNetworkId != null) {
// this is ugly, to work with legacy code, we need to re-construct the DeploymentPlan hard-codely
// this has to be refactored together with migrating legacy code into the new way
ReservationContext context = null;
if(reservationId != null) {
Journal journal = new Journal.LogJournal("VmWorkStart", s_logger);
context = new ReservationContextImpl(reservationId, journal,
CallContext.current().getCallingUser(),
CallContext.current().getCallingAccount());
}
DeploymentPlan plan = new DataCenterDeployment(
dcId, podId, clusterId, hostId, poolId, physicalNetworkId,
context);
return plan;
}
return null;
}
public void setPlan(DeploymentPlan plan) {
if(plan != null) {
dcId = plan.getDataCenterId();
podId = plan.getPodId();
clusterId = plan.getClusterId();
hostId = plan.getHostId();
poolId = plan.getPoolId();
physicalNetworkId = plan.getPhysicalNetworkId();
avoids = plan.getAvoids();
if(plan.getReservationContext() != null)
reservationId = plan.getReservationContext().getReservationId();
}
}
public Map<String, String> getRawParams() {
return rawParams;
}
public void setRawParams(Map<String, String> params) {
rawParams = params;
}
public Map<VirtualMachineProfile.Param, Object> getParams() {
Map<VirtualMachineProfile.Param, Object> map = new HashMap<VirtualMachineProfile.Param, Object>();
if(rawParams != null) {
for(Map.Entry<String, String> entry : rawParams.entrySet()) {
VirtualMachineProfile.Param key = new VirtualMachineProfile.Param(entry.getKey());
Object val = JobSerializerHelper.fromObjectSerializedString(entry.getValue());
map.put(key, val);
}
}
return map;
}
public void setParams(Map<VirtualMachineProfile.Param, Object> params) {
if(params != null) {
rawParams = new HashMap<String, String>();
for(Map.Entry<VirtualMachineProfile.Param, Object> entry : params.entrySet()) {
rawParams.put(entry.getKey().getName(), JobSerializerHelper.toObjectSerializedString(
entry.getValue() instanceof Serializable ? (Serializable)entry.getValue() : entry.getValue().toString()));
}
}
}
}

View File

@ -0,0 +1,32 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
public class VmWorkStop extends VmWork {
private static final long serialVersionUID = 202908740486785251L;
private final boolean cleanup;
public VmWorkStop(long userId, long accountId, long vmId, boolean cleanup) {
super(userId, accountId, vmId);
this.cleanup = cleanup;
}
public boolean isCleanup() {
return cleanup;
}
}

View File

@ -0,0 +1,35 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.vm;
import com.cloud.storage.StoragePool;
public class VmWorkStorageMigration extends VmWork {
private static final long serialVersionUID = -8677979691741157474L;
StoragePool destPool;
public VmWorkStorageMigration(long userId, long accountId, long vmId, StoragePool destPool) {
super(userId, accountId, vmId);
this.destPool = destPool;
}
public StoragePool getDestStoragePool() {
return this.destPool;
}
}

View File

@ -100,6 +100,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
txn.commit();
} catch(Exception e) {
s_logger.warn("Unexpected exception, ", e);
throw new RuntimeException(e.getMessage(), e);
}
}
@ -119,9 +120,8 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
return true;
} catch(Exception e) {
s_logger.warn("Unexpected exception, ", e);
throw new RuntimeException(e.getMessage(), e);
}
return false;
}
@Override
@ -145,6 +145,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
}
} catch(Exception e) {
s_logger.warn("Unexpected exception, ", e);
throw new RuntimeException(e.getMessage(), e);
}
}
@ -180,7 +181,7 @@ public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServer
txn.commit();
} catch(Exception e) {
s_logger.warn("Unexpected exception, ", e);
txn.rollback();
throw new RuntimeException(e.getMessage(), e);
}
return changedRows;

View File

@ -43,6 +43,6 @@
class="org.apache.cloudstack.framework.jobs.dao.SyncQueueItemDaoImpl" />
<bean id="syncQueueManagerImpl"
class="org.apache.cloudstack.framework.jobs.impl.SyncQueueManagerImpl" />
<bean id="vmWorkJobDaoImpl"
class="org.apache.cloudstack.framework.jobs.dao.VmWorkJobDaoImpl" />
</beans>

View File

@ -63,6 +63,14 @@ public class AsyncJobExecutionContext {
public void setJob(AsyncJob job) {
_job = job;
}
public boolean isJobDispatchedBy(String jobDispatcherName) {
assert(jobDispatcherName != null);
if(_job != null && _job.getDispatcher() != null && _job.getDispatcher().equals(jobDispatcherName))
return true;
return false;
}
public void completeAsyncJob(JobInfo.Status jobStatus, int resultCode, String resultObject) {
assert(_job != null);
@ -159,7 +167,7 @@ public class AsyncJobExecutionContext {
setCurrentExecutionContext(null);
return context;
}
// This is intended to be package level access for AsyncJobManagerImpl only.
public static void setCurrentExecutionContext(AsyncJobExecutionContext currentContext) {
s_currentExectionContext.set(currentContext);