Skip to content

Commit 2d1a6b0

Browse files
author
Alena Prokharchyk
committed
bug 14615: deployVm can work 2 diff ways now: 1) Default way - create and start the vm. 2) Create the vm without starting it. Note that vm's volumes stay in Allocated state -not created on the backend till the point where vm starts
status 14615: resolved fixed
1 parent b646c82 commit 2d1a6b0

14 files changed

Lines changed: 254 additions & 199 deletions

File tree

api/src/com/cloud/api/ApiConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ public class ApiConstants {
328328
public static final String PURPOSE = "purpose";
329329
public static final String IS_TAGGED = "istagged";
330330
public static final String INSTANCE_NAME = "instancename";
331+
public static final String START_VM = "startvm";
332+
331333

332334
public enum HostDetails {
333335
all, capacity, events, stats, min;

api/src/com/cloud/api/commands/DeployVMCmd.java

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
132132
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="Deploy vm for the project")
133133
private Long projectId;
134134

135+
@Parameter(name=ApiConstants.START_VM, type=CommandType.BOOLEAN, description="true if network offering supports specifying ip ranges; defaulted to true if not specified")
136+
private Boolean startVm;
137+
135138

136139
/////////////////////////////////////////////////////
137140
/////////////////// Accessors ///////////////////////
@@ -223,7 +226,6 @@ public List<Long> getNetworkIds() {
223226
return networks;
224227
}
225228
}
226-
227229
return networkIds;
228230
}
229231

@@ -239,6 +241,10 @@ public Long getHostId() {
239241
return hostId;
240242
}
241243

244+
public boolean getStartVm() {
245+
return startVm == null ? true : startVm;
246+
}
247+
242248
private Map<Long, String> getIpToNetworkMap() {
243249
if ((networkIds != null || ipAddress != null) && ipToNetworkList != null) {
244250
throw new InvalidParameterValueException("NetworkIds and ipAddress can't be specified along with ipToNetworkMap parameter");
@@ -311,32 +317,37 @@ public AsyncJob.Type getInstanceType() {
311317
@Override
312318
public void execute(){
313319
UserVm result;
314-
try {
315-
UserContext.current().setEventDetails("Vm Id: "+getEntityId());
316-
if (getHypervisor() == HypervisorType.BareMetal) {
317-
result = _bareMetalVmService.startVirtualMachine(this);
318-
} else {
319-
result = _userVmService.startVirtualMachine(this);
320-
}
321-
322-
if (result != null) {
323-
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
324-
response.setResponseName(getCommandName());
325-
this.setResponseObject(response);
326-
} else {
327-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to deploy vm");
320+
321+
if (getStartVm()) {
322+
try {
323+
UserContext.current().setEventDetails("Vm Id: "+getEntityId());
324+
if (getHypervisor() == HypervisorType.BareMetal) {
325+
result = _bareMetalVmService.startVirtualMachine(this);
326+
} else {
327+
result = _userVmService.startVirtualMachine(this);
328+
}
329+
} catch (ResourceUnavailableException ex) {
330+
s_logger.warn("Exception: ", ex);
331+
throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
332+
} catch (ConcurrentOperationException ex) {
333+
s_logger.warn("Exception: ", ex);
334+
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
335+
} catch (InsufficientCapacityException ex) {
336+
s_logger.info(ex);
337+
s_logger.trace(ex);
338+
throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
328339
}
329-
} catch (ResourceUnavailableException ex) {
330-
s_logger.warn("Exception: ", ex);
331-
throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
332-
} catch (ConcurrentOperationException ex) {
333-
s_logger.warn("Exception: ", ex);
334-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
335-
} catch (InsufficientCapacityException ex) {
336-
s_logger.info(ex);
337-
s_logger.trace(ex);
338-
throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
339-
}
340+
} else {
341+
result = _userVmService.getUserVm(getEntityId());
342+
}
343+
344+
if (result != null) {
345+
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
346+
response.setResponseName(getCommandName());
347+
this.setResponseObject(response);
348+
} else {
349+
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to deploy vm");
350+
}
340351
}
341352

342353
@Override

api/src/com/cloud/api/commands/StartVMCmd.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public long getEntityOwnerId() {
8686
}
8787

8888
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
89-
// tracked
89+
// tracked
9090
}
9191

9292
@Override
@@ -111,7 +111,8 @@ public Long getInstanceId() {
111111
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
112112
try {
113113
UserContext.current().setEventDetails("Vm Id: " + getId());
114-
UserVm result;
114+
115+
UserVm result ;
115116
if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
116117
result = _bareMetalVmService.startVirtualMachine(this);
117118
} else {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.cloud.user.Account;
5151
import com.cloud.uservm.UserVm;
5252
import com.cloud.utils.exception.ExecutionException;
53+
import com.cloud.vm.VirtualMachineProfile.Param;
5354

5455
public interface UserVmService {
5556
/**
@@ -364,8 +365,6 @@ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffe
364365

365366
UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOperationException;
366367

367-
UserVm startVirtualMachine(long vmId, Long hostId) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
368-
369368
void deletePrivateTemplateRecord(Long templateId);
370369

371370
/**

core/src/com/cloud/vm/UserVmVO.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
3838
@Column(name="display_name", updatable=true, nullable=true)
3939
private String displayName;
4040

41+
@Column(name="update_parameters", updatable=true)
42+
protected boolean updateParameters = true;
43+
4144
transient String password;
4245

4346
@Override
@@ -119,4 +122,12 @@ public void setAccountId(long accountId){
119122
public void setDomainId(long domainId){
120123
this.domainId = domainId;
121124
}
125+
126+
public void setUpdateParameters(boolean updateParameters) {
127+
this.updateParameters = updateParameters;
128+
}
129+
130+
public boolean isUpdateParameters() {
131+
return updateParameters;
132+
}
122133
}

server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.cloud.api.commands.CreateTemplateCmd;
3333
import com.cloud.api.commands.DeployVMCmd;
3434
import com.cloud.api.commands.DetachVolumeCmd;
35+
import com.cloud.api.commands.StartVMCmd;
3536
import com.cloud.api.commands.UpgradeVMCmd;
3637
import com.cloud.baremetal.PxeServerManager.PxeServerType;
3738
import com.cloud.configuration.Resource.ResourceType;
@@ -383,8 +384,7 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE
383384
}
384385

385386
public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
386-
long vmId = cmd.getEntityId();
387-
UserVmVO vm = _vmDao.findById(vmId);
387+
UserVmVO vm = _vmDao.findById(cmd.getInstanceId());
388388

389389
List<HostVO> servers = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.PxeServer, vm.getDataCenterIdToDeployIn());
390390
if (servers.size() == 0) {
@@ -402,6 +402,30 @@ public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableExc
402402

403403
return startVirtualMachine(cmd, params);
404404
}
405+
406+
407+
public UserVm startVirtualMachine(StartVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
408+
UserVmVO vm = _vmDao.findById(cmd.getInstanceId());
409+
410+
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
411+
if (template == null || template.getFormat() != Storage.ImageFormat.BAREMETAL) {
412+
throw new InvalidParameterValueException("Invalid template with id = " + vm.getTemplateId());
413+
}
414+
415+
Map<VirtualMachineProfile.Param, Object> params = null;
416+
if (vm.isUpdateParameters()) {
417+
List<HostVO> servers = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.PxeServer, vm.getDataCenterIdToDeployIn());
418+
if (servers.size() == 0) {
419+
throw new CloudRuntimeException("Cannot find PXE server, please make sure there is one PXE server per zone");
420+
}
421+
HostVO pxeServer = servers.get(0);
422+
params = new HashMap<VirtualMachineProfile.Param, Object>();
423+
params.put(Param.PxeSeverType, _pxeMgr.getPxeServerType(pxeServer));
424+
}
425+
426+
Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> vmDetailsPair = super.startVirtualMachine(vm.getId(), cmd.getHostId(), params);
427+
return vmDetailsPair.first();
428+
}
405429

406430
@Override
407431
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {

server/src/com/cloud/storage/StorageManagerImpl.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,11 +3046,17 @@ public void prepare(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDe
30463046
}
30473047
recreateVols.add(vol);
30483048
} else {
3049-
if (s_logger.isDebugEnabled()) {
3050-
s_logger.debug("Volume " + vol + " is not recreatable! Cannot recreate on storagepool: " + assignedPool);
3049+
if (assignedPool.getId() != vol.getPoolId()) {
3050+
if (s_logger.isDebugEnabled()) {
3051+
s_logger.debug("Volume " + vol + " is not recreatable! Cannot recreate on storagepool: " + assignedPool);
3052+
}
3053+
throw new StorageUnavailableException("Volume is not recreatable, Unable to create " + vol, Volume.class, vol.getId());
3054+
// copy volume usecase - not yet developed.
3055+
} else {
3056+
StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
3057+
vm.addDisk(new VolumeTO(vol, pool));
30513058
}
3052-
throw new StorageUnavailableException("Volume is not recreatable, Unable to create " + vol, Volume.class, vol.getId());
3053-
// copy volume usecase - not yet developed.
3059+
30543060
}
30553061
}
30563062
} else {

server/src/com/cloud/vm/ItWorkDao.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ public interface ItWorkDao extends GenericDao<ItWorkVO, String> {
3737
boolean updateStep(ItWorkVO work, Step step);
3838

3939
List<ItWorkVO> listWorkInProgressFor(long nodeId);
40+
4041
}

server/src/com/cloud/vm/UserVmManager.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@
1414

1515
import java.util.HashMap;
1616
import java.util.List;
17+
import java.util.Map;
1718

1819
import com.cloud.agent.api.VmStatsEntry;
20+
import com.cloud.exception.ConcurrentOperationException;
21+
import com.cloud.exception.InsufficientCapacityException;
22+
import com.cloud.exception.ResourceUnavailableException;
1923
import com.cloud.projects.Project.ListProjectResourcesCriteria;
2024
import com.cloud.server.Criteria;
2125
import com.cloud.user.Account;
2226
import com.cloud.uservm.UserVm;
27+
import com.cloud.utils.Pair;
2328

2429
/**
2530
*
@@ -91,4 +96,7 @@ public interface UserVmManager extends VirtualMachineGuru<UserVmVO>, UserVmServi
9196
List<UserVmVO> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List<Long> permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria);
9297

9398
String getChecksum(Long hostId, String templatePath);
99+
100+
Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
101+
94102
}

0 commit comments

Comments
 (0)