Skip to content

Commit 562a7db

Browse files
committed
Merge remote-tracking branch 'origin/4.14'
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
2 parents db665fa + cd8e28b commit 562a7db

File tree

6 files changed

+148
-196
lines changed

6 files changed

+148
-196
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ UserVm moveVMToUser(AssignVMCmd moveUserVMCmd) throws ResourceAllocationExceptio
490490

491491
UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException;
492492

493+
UserVm restoreVirtualMachine(Account caller, long vmId, Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException;
494+
493495
UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
494496
VirtualMachineMigrationException;
495497

engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.cloud.storage.StoragePool;
4444
import com.cloud.template.VirtualMachineTemplate;
4545
import com.cloud.user.Account;
46+
import com.cloud.uservm.UserVm;
4647
import com.cloud.utils.component.Manager;
4748
import com.cloud.utils.fsm.NoTransitionException;
4849

@@ -234,4 +235,6 @@ static String getHypervisorHostname(String name) {
234235
* - Keep the VM as it is on the hypervisor
235236
*/
236237
boolean unmanage(String vmUuid);
238+
239+
UserVm restoreVirtualMachine(long vmId, Long newTemplateId) throws ResourceUnavailableException, InsufficientCapacityException;
237240
}

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

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@
201201
import com.cloud.user.Account;
202202
import com.cloud.user.ResourceLimitService;
203203
import com.cloud.user.User;
204+
import com.cloud.uservm.UserVm;
204205
import com.cloud.utils.DateUtil;
205206
import com.cloud.utils.Journal;
206207
import com.cloud.utils.Pair;
@@ -5629,4 +5630,107 @@ protected void resourceCountDecrement (long accountId, Long cpu, Long memory) {
56295630
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, memory);
56305631
}
56315632

5633+
@Override
5634+
public UserVm restoreVirtualMachine(final long vmId, final Long newTemplateId) throws ResourceUnavailableException, InsufficientCapacityException {
5635+
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
5636+
if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
5637+
VmWorkJobVO placeHolder = null;
5638+
placeHolder = createPlaceHolderWork(vmId);
5639+
try {
5640+
return orchestrateRestoreVirtualMachine(vmId, newTemplateId);
5641+
} finally {
5642+
if (placeHolder != null) {
5643+
_workJobDao.expunge(placeHolder.getId());
5644+
}
5645+
}
5646+
} else {
5647+
final Outcome<VirtualMachine> outcome = restoreVirtualMachineThroughJobQueue(vmId, newTemplateId);
5648+
5649+
try {
5650+
outcome.get();
5651+
} catch (final InterruptedException e) {
5652+
throw new RuntimeException("Operation is interrupted", e);
5653+
} catch (final java.util.concurrent.ExecutionException e) {
5654+
throw new RuntimeException("Execution exception", e);
5655+
}
5656+
5657+
final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
5658+
if (jobResult != null) {
5659+
if (jobResult instanceof ResourceUnavailableException) {
5660+
throw (ResourceUnavailableException)jobResult;
5661+
} else if (jobResult instanceof ConcurrentOperationException) {
5662+
throw (ConcurrentOperationException)jobResult;
5663+
} else if (jobResult instanceof RuntimeException) {
5664+
throw (RuntimeException)jobResult;
5665+
} else if (jobResult instanceof Throwable) {
5666+
throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
5667+
} else if (jobResult instanceof HashMap) {
5668+
HashMap<Long, String> passwordMap = (HashMap<Long, String>)jobResult;
5669+
UserVmVO userVm = _userVmDao.findById(vmId);
5670+
userVm.setPassword(passwordMap.get(vmId));
5671+
return userVm;
5672+
}
5673+
}
5674+
throw new RuntimeException("Unexpected job execution result");
5675+
}
5676+
}
5677+
5678+
private UserVm orchestrateRestoreVirtualMachine(final long vmId, final Long newTemplateId) throws ResourceUnavailableException, InsufficientCapacityException {
5679+
s_logger.debug("Restoring vm " + vmId + " with new templateId " + newTemplateId);
5680+
final CallContext context = CallContext.current();
5681+
final Account account = context.getCallingAccount();
5682+
return _userVmService.restoreVirtualMachine(account, vmId, newTemplateId);
5683+
}
5684+
5685+
public Outcome<VirtualMachine> restoreVirtualMachineThroughJobQueue(final long vmId, final Long newTemplateId) {
5686+
5687+
final CallContext context = CallContext.current();
5688+
final User user = context.getCallingUser();
5689+
final Account account = context.getCallingAccount();
5690+
5691+
final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
5692+
VirtualMachine.Type.Instance, vmId,
5693+
VmWorkRestore.class.getName());
5694+
5695+
VmWorkJobVO workJob = null;
5696+
if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
5697+
assert pendingWorkJobs.size() == 1;
5698+
workJob = pendingWorkJobs.get(0);
5699+
} else {
5700+
5701+
workJob = new VmWorkJobVO(context.getContextId());
5702+
5703+
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
5704+
workJob.setCmd(VmWorkRestore.class.getName());
5705+
5706+
workJob.setAccountId(account.getId());
5707+
workJob.setUserId(user.getId());
5708+
workJob.setVmType(VirtualMachine.Type.Instance);
5709+
workJob.setVmInstanceId(vmId);
5710+
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
5711+
5712+
final VmWorkRestore workInfo = new VmWorkRestore(user.getId(), account.getId(), vmId,
5713+
VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, newTemplateId);
5714+
workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
5715+
5716+
_jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vmId);
5717+
}
5718+
AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
5719+
5720+
return new VmJobVirtualMachineOutcome(workJob, vmId);
5721+
}
5722+
5723+
@ReflectionUse
5724+
private Pair<JobInfo.Status, String> orchestrateRestoreVirtualMachine(final VmWorkRestore work) throws Exception {
5725+
final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
5726+
if (vm == null) {
5727+
s_logger.info("Unable to find vm " + work.getVmId());
5728+
}
5729+
assert vm != null;
5730+
UserVm uservm = orchestrateRestoreVirtualMachine(vm.getId(), work.getTemplateId());
5731+
HashMap<Long, String> passwordMap = new HashMap<Long, String>();
5732+
passwordMap.put(uservm.getId(), uservm.getPassword());
5733+
return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(passwordMap));
5734+
}
5735+
56325736
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.vm;
18+
19+
public class VmWorkRestore extends VmWork {
20+
private static final long serialVersionUID = 195901782359759635L;
21+
22+
private Long templateId;
23+
24+
public VmWorkRestore(long userId, long accountId, long vmId, String handlerName, Long templateId) {
25+
super(userId, accountId, vmId, handlerName);
26+
27+
this.templateId = templateId;
28+
}
29+
30+
public Long getTemplateId() {
31+
return templateId;
32+
}
33+
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6614,11 +6614,15 @@ public UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException,
66146614
}
66156615

66166616
public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException {
6617+
return _itMgr.restoreVirtualMachine(vm.getId(), newTemplateId);
6618+
}
66176619

6620+
@Override
6621+
public UserVm restoreVirtualMachine(final Account caller, final long vmId, final Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException {
66186622
Long userId = caller.getId();
6619-
Account owner = _accountDao.findById(vm.getAccountId());
66206623
_userDao.findById(userId);
6621-
long vmId = vm.getId();
6624+
UserVmVO vm = _vmDao.findById(vmId);
6625+
Account owner = _accountDao.findById(vm.getAccountId());
66226626
boolean needRestart = false;
66236627

66246628
// Input validation

0 commit comments

Comments
 (0)