mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
remove VmWorkJob after adding a nic to a vm (#5658)
Co-authored-by: Daan Hoogland <dahn@onecht.net> Co-authored-by: Suresh Kumar Anaparti <suresh.anaparti@shapeblue.com> Co-authored-by: Wei Zhou <weizhou@apache.org>
This commit is contained in:
parent
4916f3c90d
commit
028d338aaa
@ -42,6 +42,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
import javax.persistence.EntityExistsException;
|
||||||
|
|
||||||
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
|
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
|
||||||
import org.apache.cloudstack.annotation.AnnotationService;
|
import org.apache.cloudstack.annotation.AnnotationService;
|
||||||
@ -191,7 +192,6 @@ import com.cloud.offering.NetworkOffering;
|
|||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
import com.cloud.offerings.NetworkOfferingVO;
|
import com.cloud.offerings.NetworkOfferingVO;
|
||||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
|
||||||
import com.cloud.org.Cluster;
|
import com.cloud.org.Cluster;
|
||||||
import com.cloud.resource.ResourceManager;
|
import com.cloud.resource.ResourceManager;
|
||||||
import com.cloud.resource.ResourceState;
|
import com.cloud.resource.ResourceState;
|
||||||
@ -357,8 +357,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
@Inject
|
@Inject
|
||||||
private StorageManager storageMgr;
|
private StorageManager storageMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private NetworkOfferingDetailsDao networkOfferingDetailsDao;
|
|
||||||
@Inject
|
|
||||||
private NetworkDetailsDao networkDetailsDao;
|
private NetworkDetailsDao networkDetailsDao;
|
||||||
@Inject
|
@Inject
|
||||||
private SecurityGroupManager _securityGroupManager;
|
private SecurityGroupManager _securityGroupManager;
|
||||||
@ -4002,9 +4000,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
|
|
||||||
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||||
if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
|
if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
|
||||||
// avoid re-entrance
|
VmWorkJobVO placeHolder = createPlaceHolderWork(vm.getId(), network.getUuid());
|
||||||
VmWorkJobVO placeHolder = null;
|
|
||||||
placeHolder = createPlaceHolderWork(vm.getId());
|
|
||||||
try {
|
try {
|
||||||
return orchestrateAddVmToNetwork(vm, network, requested);
|
return orchestrateAddVmToNetwork(vm, network, requested);
|
||||||
} finally {
|
} finally {
|
||||||
@ -4040,7 +4036,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException("Unexpected job execution result");
|
throw new RuntimeException("null job execution result");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* duplicated in {@see UserVmManagerImpl} for a {@see UserVmVO}
|
||||||
|
*/
|
||||||
|
private void checkIfNetworkExistsForVM(VirtualMachine virtualMachine, Network network) {
|
||||||
|
List<NicVO> allNics = _nicsDao.listByVmId(virtualMachine.getId());
|
||||||
|
for (NicVO nic : allNics) {
|
||||||
|
if (nic.getNetworkId() == network.getId()) {
|
||||||
|
throw new CloudRuntimeException("A NIC already exists for VM:" + virtualMachine.getInstanceName() + " in network: " + network.getUuid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4048,6 +4056,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
InsufficientCapacityException {
|
InsufficientCapacityException {
|
||||||
final CallContext cctx = CallContext.current();
|
final CallContext cctx = CallContext.current();
|
||||||
|
|
||||||
|
checkIfNetworkExistsForVM(vm, network);
|
||||||
s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested);
|
s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested);
|
||||||
final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
|
final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
|
||||||
final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
|
final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
|
||||||
@ -5631,37 +5640,64 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
|
|
||||||
final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
|
final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
|
||||||
VirtualMachine.Type.Instance, vm.getId(),
|
VirtualMachine.Type.Instance, vm.getId(),
|
||||||
VmWorkAddVmToNetwork.class.getName());
|
VmWorkAddVmToNetwork.class.getName(), network.getUuid());
|
||||||
|
|
||||||
VmWorkJobVO workJob = null;
|
VmWorkJobVO workJob = null;
|
||||||
if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
|
if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
|
||||||
assert pendingWorkJobs.size() == 1;
|
if (pendingWorkJobs.size() > 1) {
|
||||||
|
throw new CloudRuntimeException(String.format("The number of jobs to add network %s to vm %s are %d", network.getUuid(), vm.getInstanceName(), pendingWorkJobs.size()));
|
||||||
|
}
|
||||||
workJob = pendingWorkJobs.get(0);
|
workJob = pendingWorkJobs.get(0);
|
||||||
} else {
|
} else {
|
||||||
|
if (s_logger.isTraceEnabled()) {
|
||||||
|
s_logger.trace(String.format("no jobs to add network %s for vm %s yet", network, vm));
|
||||||
|
}
|
||||||
|
|
||||||
workJob = new VmWorkJobVO(context.getContextId());
|
workJob = createVmWorkJobToAddNetwork(vm, network, requested, context, user, account);
|
||||||
|
|
||||||
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
|
|
||||||
workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
|
|
||||||
|
|
||||||
workJob.setAccountId(account.getId());
|
|
||||||
workJob.setUserId(user.getId());
|
|
||||||
workJob.setVmType(VirtualMachine.Type.Instance);
|
|
||||||
workJob.setVmInstanceId(vm.getId());
|
|
||||||
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
|
|
||||||
|
|
||||||
// save work context info (there are some duplications)
|
|
||||||
final VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
|
|
||||||
VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network.getId(), requested);
|
|
||||||
workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
|
|
||||||
|
|
||||||
_jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
|
|
||||||
}
|
}
|
||||||
AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
|
AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
|
||||||
|
|
||||||
return new VmJobVirtualMachineOutcome(workJob, vm.getId());
|
return new VmJobVirtualMachineOutcome(workJob, vm.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private VmWorkJobVO createVmWorkJobToAddNetwork(
|
||||||
|
VirtualMachine vm,
|
||||||
|
Network network,
|
||||||
|
NicProfile requested,
|
||||||
|
CallContext context,
|
||||||
|
User user,
|
||||||
|
Account account) {
|
||||||
|
VmWorkJobVO workJob;
|
||||||
|
workJob = new VmWorkJobVO(context.getContextId());
|
||||||
|
|
||||||
|
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
|
||||||
|
workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
|
||||||
|
|
||||||
|
workJob.setAccountId(account.getId());
|
||||||
|
workJob.setUserId(user.getId());
|
||||||
|
workJob.setVmType(VirtualMachine.Type.Instance);
|
||||||
|
workJob.setVmInstanceId(vm.getId());
|
||||||
|
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
|
||||||
|
workJob.setSecondaryObjectIdentifier(network.getUuid());
|
||||||
|
|
||||||
|
// save work context info as there might be some duplicates
|
||||||
|
final VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
|
||||||
|
VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network.getId(), requested);
|
||||||
|
workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
|
||||||
|
|
||||||
|
try {
|
||||||
|
_jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
|
||||||
|
} catch (CloudRuntimeException e) {
|
||||||
|
if (e.getCause() instanceof EntityExistsException) {
|
||||||
|
String msg = String.format("A job to add a nic for network %s to vm %s already exists", network.getUuid(), vm.getUuid());
|
||||||
|
s_logger.warn(msg, e);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return workJob;
|
||||||
|
}
|
||||||
|
|
||||||
public Outcome<VirtualMachine> removeNicFromVmThroughJobQueue(
|
public Outcome<VirtualMachine> removeNicFromVmThroughJobQueue(
|
||||||
final VirtualMachine vm, final Nic nic) {
|
final VirtualMachine vm, final Nic nic) {
|
||||||
|
|
||||||
@ -5968,6 +6004,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
}
|
}
|
||||||
|
|
||||||
private VmWorkJobVO createPlaceHolderWork(final long instanceId) {
|
private VmWorkJobVO createPlaceHolderWork(final long instanceId) {
|
||||||
|
return createPlaceHolderWork(instanceId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private VmWorkJobVO createPlaceHolderWork(final long instanceId, String secondaryObjectIdentifier) {
|
||||||
final VmWorkJobVO workJob = new VmWorkJobVO("");
|
final VmWorkJobVO workJob = new VmWorkJobVO("");
|
||||||
|
|
||||||
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER);
|
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER);
|
||||||
@ -5979,6 +6019,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
workJob.setStep(VmWorkJobVO.Step.Starting);
|
workJob.setStep(VmWorkJobVO.Step.Starting);
|
||||||
workJob.setVmType(VirtualMachine.Type.Instance);
|
workJob.setVmType(VirtualMachine.Type.Instance);
|
||||||
workJob.setVmInstanceId(instanceId);
|
workJob.setVmInstanceId(instanceId);
|
||||||
|
if(org.apache.commons.lang3.StringUtils.isNotBlank(secondaryObjectIdentifier)) {
|
||||||
|
workJob.setSecondaryObjectIdentifier(secondaryObjectIdentifier);
|
||||||
|
}
|
||||||
workJob.setInitMsid(ManagementServerNode.getManagementServerId());
|
workJob.setInitMsid(ManagementServerNode.getManagementServerId());
|
||||||
|
|
||||||
_workJobDao.persist(workJob);
|
_workJobDao.persist(workJob);
|
||||||
|
|||||||
@ -17,4 +17,6 @@
|
|||||||
|
|
||||||
--;
|
--;
|
||||||
-- Schema upgrade from 4.16.0.0 to 4.16.1.0
|
-- Schema upgrade from 4.16.0.0 to 4.16.1.0
|
||||||
--;
|
--;
|
||||||
|
|
||||||
|
ALTER TABLE `cloud`.`vm_work_job` ADD COLUMN `secondary_object` char(100) COMMENT 'any additional item that must be checked during queueing' AFTER `vm_instance_id`;
|
||||||
|
|||||||
@ -32,6 +32,8 @@ public interface VmWorkJobDao extends GenericDao<VmWorkJobVO, Long> {
|
|||||||
|
|
||||||
List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd);
|
List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd);
|
||||||
|
|
||||||
|
List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd, String secondaryObjectIdentifier);
|
||||||
|
|
||||||
void updateStep(long workJobId, Step step);
|
void updateStep(long workJobId, Step step);
|
||||||
|
|
||||||
void expungeCompletedWorkJobs(Date cutDate);
|
void expungeCompletedWorkJobs(Date cutDate);
|
||||||
|
|||||||
@ -67,6 +67,7 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
|
|||||||
PendingWorkJobByCommandSearch.and("jobStatus", PendingWorkJobByCommandSearch.entity().getStatus(), Op.EQ);
|
PendingWorkJobByCommandSearch.and("jobStatus", PendingWorkJobByCommandSearch.entity().getStatus(), Op.EQ);
|
||||||
PendingWorkJobByCommandSearch.and("vmType", PendingWorkJobByCommandSearch.entity().getVmType(), Op.EQ);
|
PendingWorkJobByCommandSearch.and("vmType", PendingWorkJobByCommandSearch.entity().getVmType(), Op.EQ);
|
||||||
PendingWorkJobByCommandSearch.and("vmInstanceId", PendingWorkJobByCommandSearch.entity().getVmInstanceId(), Op.EQ);
|
PendingWorkJobByCommandSearch.and("vmInstanceId", PendingWorkJobByCommandSearch.entity().getVmInstanceId(), Op.EQ);
|
||||||
|
PendingWorkJobByCommandSearch.and("secondaryObjectIdentifier", PendingWorkJobByCommandSearch.entity().getSecondaryObjectIdentifier(), Op.EQ);
|
||||||
PendingWorkJobByCommandSearch.and("step", PendingWorkJobByCommandSearch.entity().getStep(), Op.NEQ);
|
PendingWorkJobByCommandSearch.and("step", PendingWorkJobByCommandSearch.entity().getStep(), Op.NEQ);
|
||||||
PendingWorkJobByCommandSearch.and("cmd", PendingWorkJobByCommandSearch.entity().getCmd(), Op.EQ);
|
PendingWorkJobByCommandSearch.and("cmd", PendingWorkJobByCommandSearch.entity().getCmd(), Op.EQ);
|
||||||
PendingWorkJobByCommandSearch.done();
|
PendingWorkJobByCommandSearch.done();
|
||||||
@ -119,6 +120,19 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
|
|||||||
return this.listBy(sc, filter);
|
return this.listBy(sc, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd, String secondaryObjectIdentifier) {
|
||||||
|
SearchCriteria<VmWorkJobVO> sc = PendingWorkJobByCommandSearch.create();
|
||||||
|
sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS);
|
||||||
|
sc.setParameters("vmType", type);
|
||||||
|
sc.setParameters("vmInstanceId", instanceId);
|
||||||
|
sc.setParameters("secondaryObjectIdentifier", secondaryObjectIdentifier);
|
||||||
|
sc.setParameters("cmd", jobCmd);
|
||||||
|
|
||||||
|
Filter filter = new Filter(VmWorkJobVO.class, "created", true, null, null);
|
||||||
|
return this.listBy(sc, filter);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateStep(long workJobId, Step step) {
|
public void updateStep(long workJobId, Step step) {
|
||||||
VmWorkJobVO jobVo = findById(workJobId);
|
VmWorkJobVO jobVo = findById(workJobId);
|
||||||
|
|||||||
@ -384,7 +384,7 @@ public class AsyncJobVO implements AsyncJob, JobInfo {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append("AsyncJobVO {id:").append(getId());
|
sb.append("AsyncJobVO: {id:").append(getId());
|
||||||
sb.append(", userId: ").append(getUserId());
|
sb.append(", userId: ").append(getUserId());
|
||||||
sb.append(", accountId: ").append(getAccountId());
|
sb.append(", accountId: ").append(getAccountId());
|
||||||
sb.append(", instanceType: ").append(getInstanceType());
|
sb.append(", instanceType: ").append(getInstanceType());
|
||||||
|
|||||||
@ -58,6 +58,9 @@ public class VmWorkJobVO extends AsyncJobVO {
|
|||||||
@Column(name = "vm_instance_id")
|
@Column(name = "vm_instance_id")
|
||||||
long vmInstanceId;
|
long vmInstanceId;
|
||||||
|
|
||||||
|
@Column(name = "secondary_object")
|
||||||
|
String secondaryObjectIdentifier;
|
||||||
|
|
||||||
protected VmWorkJobVO() {
|
protected VmWorkJobVO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,4 +92,25 @@ public class VmWorkJobVO extends AsyncJobVO {
|
|||||||
public void setVmInstanceId(long vmInstanceId) {
|
public void setVmInstanceId(long vmInstanceId) {
|
||||||
this.vmInstanceId = vmInstanceId;
|
this.vmInstanceId = vmInstanceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSecondaryObjectIdentifier() {
|
||||||
|
return secondaryObjectIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecondaryObjectIdentifier(String secondaryObjectIdentifier) {
|
||||||
|
this.secondaryObjectIdentifier = secondaryObjectIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append("VmWorkJobVO : {").
|
||||||
|
append(", step: ").append(getStep()).
|
||||||
|
append(", vmType: ").append(getVmType()).
|
||||||
|
append(", vmInstanceId: ").append(getVmInstanceId()).
|
||||||
|
append(", secondaryObjectIdentifier: ").append(getSecondaryObjectIdentifier()).
|
||||||
|
append(super.toString()).
|
||||||
|
append("}");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1386,12 +1386,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
Account vmOwner = _accountMgr.getAccount(vmInstance.getAccountId());
|
Account vmOwner = _accountMgr.getAccount(vmInstance.getAccountId());
|
||||||
_networkModel.checkNetworkPermissions(vmOwner, network);
|
_networkModel.checkNetworkPermissions(vmOwner, network);
|
||||||
|
|
||||||
List<NicVO> allNics = _nicDao.listByVmId(vmInstance.getId());
|
checkIfNetExistsForVM(vmInstance, network);
|
||||||
for (NicVO nic : allNics) {
|
|
||||||
if (nic.getNetworkId() == network.getId()) {
|
|
||||||
throw new CloudRuntimeException("A NIC already exists for VM:" + vmInstance.getInstanceName() + " in network: " + network.getUuid());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macAddress = validateOrReplaceMacAddress(macAddress, network.getId());
|
macAddress = validateOrReplaceMacAddress(macAddress, network.getId());
|
||||||
|
|
||||||
@ -1458,10 +1453,22 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallContext.current().putContextParameter(Nic.class, guestNic.getUuid());
|
CallContext.current().putContextParameter(Nic.class, guestNic.getUuid());
|
||||||
s_logger.debug("Successful addition of " + network + " from " + vmInstance);
|
s_logger.debug(String.format("Successful addition of %s from %s through %s", network, vmInstance, guestNic));
|
||||||
return _vmDao.findById(vmInstance.getId());
|
return _vmDao.findById(vmInstance.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* duplicated in {@see VirtualMachineManagerImpl} for a {@see VMInstanceVO}
|
||||||
|
*/
|
||||||
|
private void checkIfNetExistsForVM(VirtualMachine virtualMachine, Network network) {
|
||||||
|
List<NicVO> allNics = _nicDao.listByVmId(virtualMachine.getId());
|
||||||
|
for (NicVO nic : allNics) {
|
||||||
|
if (nic.getNetworkId() == network.getId()) {
|
||||||
|
throw new CloudRuntimeException("A NIC already exists for VM:" + virtualMachine.getInstanceName() + " in network: " + network.getUuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the given MAC address is invalid it replaces the given MAC with the next available MAC address
|
* If the given MAC address is invalid it replaces the given MAC with the next available MAC address
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user