Skip to content

Commit 88333b3

Browse files
committed
persist kvm domain when unmanaged from CS
1 parent 9184170 commit 88333b3

File tree

5 files changed

+212
-22
lines changed

5 files changed

+212
-22
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package com.cloud.agent.api;
21+
22+
public class UnmanageInstanceAnswer extends Answer {
23+
24+
public UnmanageInstanceAnswer(UnmanageInstanceCommand cmd, boolean success, String details) {
25+
super(cmd, success, details);
26+
}
27+
28+
public UnmanageInstanceAnswer(UnmanageInstanceCommand cmd, Exception e) {
29+
super(cmd, e);
30+
}
31+
32+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package com.cloud.agent.api;
21+
22+
import com.cloud.agent.api.to.VirtualMachineTO;
23+
24+
/**
25+
*/
26+
public class UnmanageInstanceCommand extends Command {
27+
VirtualMachineTO vm;
28+
boolean executeInSequence = false;
29+
30+
public VirtualMachineTO getVirtualMachine() {
31+
return vm;
32+
}
33+
34+
@Override
35+
public boolean executeInSequence() {
36+
//VR start doesn't go through queue
37+
if (vm.getName() != null && vm.getName().startsWith("r-")) {
38+
return false;
39+
}
40+
return executeInSequence;
41+
}
42+
43+
protected UnmanageInstanceCommand() {
44+
}
45+
46+
public UnmanageInstanceCommand(VirtualMachineTO vm, boolean executeInSequence) {
47+
this.vm = vm;
48+
this.executeInSequence = executeInSequence;
49+
}
50+
}

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

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import javax.naming.ConfigurationException;
5050
import javax.persistence.EntityExistsException;
5151

52-
5352
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
5453
import org.apache.cloudstack.annotation.AnnotationService;
5554
import org.apache.cloudstack.annotation.dao.AnnotationDao;
@@ -150,6 +149,8 @@
150149
import com.cloud.agent.api.StopCommand;
151150
import com.cloud.agent.api.UnPlugNicAnswer;
152151
import com.cloud.agent.api.UnPlugNicCommand;
152+
import com.cloud.agent.api.UnmanageInstanceAnswer;
153+
import com.cloud.agent.api.UnmanageInstanceCommand;
153154
import com.cloud.agent.api.UnregisterVMCommand;
154155
import com.cloud.agent.api.VmDiskStatsEntry;
155156
import com.cloud.agent.api.VmNetworkStatsEntry;
@@ -297,8 +298,8 @@
297298
import com.cloud.vm.VirtualMachine.State;
298299
import com.cloud.vm.dao.NicDao;
299300
import com.cloud.vm.dao.UserVmDao;
300-
import com.cloud.vm.dao.VMInstanceDetailsDao;
301301
import com.cloud.vm.dao.VMInstanceDao;
302+
import com.cloud.vm.dao.VMInstanceDetailsDao;
302303
import com.cloud.vm.snapshot.VMSnapshotManager;
303304
import com.cloud.vm.snapshot.VMSnapshotVO;
304305
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
@@ -2014,31 +2015,43 @@ public boolean unmanage(String vmUuid) {
20142015
throw new ConcurrentOperationException(msg);
20152016
}
20162017

2017-
Boolean result = Transaction.execute(new TransactionCallback<Boolean>() {
2018-
@Override
2019-
public Boolean doInTransaction(TransactionStatus status) {
2018+
boolean isCmdAnswerSuccess = true;
2019+
// define domain for kvm host
2020+
if (HypervisorType.KVM.equals(vm.getHypervisorType())) {
2021+
final UnmanageInstanceCommand unmanageInstanceCommand = new UnmanageInstanceCommand(getVmTO(vm.getId()), false);
2022+
try {
2023+
Answer answer = _agentMgr.send(vm.getHostId(), unmanageInstanceCommand);
2024+
isCmdAnswerSuccess = (answer instanceof UnmanageInstanceAnswer && answer.getResult());
2025+
} catch (Exception ex) {
2026+
isCmdAnswerSuccess = false;
2027+
}
2028+
}
20202029

2021-
logger.debug("Unmanaging VM {}", vm);
2030+
if (isCmdAnswerSuccess) {
2031+
logger.debug("Unmanaging VM {}", vm);
2032+
Boolean result = Transaction.execute(new TransactionCallback<Boolean>() {
2033+
@Override
2034+
public Boolean doInTransaction(TransactionStatus status) {
2035+
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
2036+
final VirtualMachineGuru guru = getVmGuru(vm);
20222037

2023-
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
2024-
final VirtualMachineGuru guru = getVmGuru(vm);
2038+
try {
2039+
unmanageVMSnapshots(vm);
2040+
unmanageVMNics(profile, vm);
2041+
unmanageVMVolumes(vm);
20252042

2026-
try {
2027-
unmanageVMSnapshots(vm);
2028-
unmanageVMNics(profile, vm);
2029-
unmanageVMVolumes(vm);
2043+
guru.finalizeUnmanage(vm);
2044+
} catch (Exception e) {
2045+
logger.error("Error while unmanaging VM {}", vm, e);
2046+
return false;
2047+
}
20302048

2031-
guru.finalizeUnmanage(vm);
2032-
} catch (Exception e) {
2033-
logger.error("Error while unmanaging VM {}", vm, e);
2034-
return false;
2049+
return true;
20352050
}
2036-
2037-
return true;
2038-
}
2039-
});
2040-
2041-
return BooleanUtils.isTrue(result);
2051+
});
2052+
return BooleanUtils.isTrue(result);
2053+
}
2054+
return false;
20422055
}
20432056

20442057
/**

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,6 +2205,14 @@ public String startVM(final Connect conn, final String vmName, final String doma
22052205
return null;
22062206
}
22072207

2208+
public void defineVMDomain(final Connect conn, final String domainXML) throws LibvirtException {
2209+
try {
2210+
conn.domainDefineXML(domainXML);
2211+
} catch (final LibvirtException ex) {
2212+
throw ex;
2213+
}
2214+
}
2215+
22082216
@Override
22092217
public boolean stop() {
22102218
try {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package com.cloud.hypervisor.kvm.resource.wrapper;
21+
22+
import org.libvirt.Connect;
23+
import org.libvirt.LibvirtException;
24+
25+
import com.cloud.agent.api.Answer;
26+
import com.cloud.agent.api.UnmanageInstanceAnswer;
27+
import com.cloud.agent.api.UnmanageInstanceCommand;
28+
import com.cloud.agent.api.to.NicTO;
29+
import com.cloud.agent.api.to.VirtualMachineTO;
30+
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
31+
import com.cloud.hypervisor.kvm.resource.LibvirtKvmAgentHook;
32+
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef;
33+
import com.cloud.resource.CommandWrapper;
34+
import com.cloud.resource.ResourceWrapper;
35+
import com.cloud.vm.VirtualMachine;
36+
37+
@ResourceWrapper(handles = UnmanageInstanceCommand.class)
38+
public final class LibvirtUnmanageInstanceCommandWrapper extends CommandWrapper<UnmanageInstanceCommand, Answer, LibvirtComputingResource> {
39+
40+
41+
@Override
42+
public Answer execute(final UnmanageInstanceCommand command, final LibvirtComputingResource libvirtComputingResource) {
43+
final VirtualMachineTO vmSpec = command.getVirtualMachine();
44+
LibvirtVMDef vm = null;
45+
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
46+
Connect conn = null;
47+
try {
48+
49+
vm = libvirtComputingResource.createVMFromSpec(vmSpec);
50+
conn = libvirtUtilitiesHelper.getConnectionByType(vm.getHvsType());
51+
52+
final NicTO[] nics = vmSpec.getNics();
53+
54+
for (final NicTO nic : nics) {
55+
if (vmSpec.getType() != VirtualMachine.Type.User) {
56+
nic.setPxeDisable(true);
57+
}
58+
}
59+
60+
String vmInitialSpecification = vm.toString();
61+
String vmFinalSpecification = performXmlTransformHook(vmInitialSpecification, libvirtComputingResource);
62+
libvirtComputingResource.defineVMDomain(conn, vmFinalSpecification);
63+
64+
return new UnmanageInstanceAnswer(command, true, "Successfully unmanaged");
65+
} catch (final LibvirtException ex) {
66+
logger.warn("LibvirtException ", ex);
67+
return new UnmanageInstanceAnswer(command, false, ex.getMessage());
68+
}
69+
}
70+
71+
private String performXmlTransformHook(String vmInitialSpecification, final LibvirtComputingResource libvirtComputingResource) {
72+
String vmFinalSpecification;
73+
try {
74+
// if transformer fails, everything must go as it's just skipped.
75+
LibvirtKvmAgentHook t = libvirtComputingResource.getTransformer();
76+
vmFinalSpecification = (String) t.handle(vmInitialSpecification);
77+
if (null == vmFinalSpecification) {
78+
logger.warn("Libvirt XML transformer returned NULL, will use XML specification unchanged.");
79+
vmFinalSpecification = vmInitialSpecification;
80+
}
81+
} catch(Exception e) {
82+
logger.warn("Exception occurred when handling LibVirt XML transformer hook: {}", e);
83+
vmFinalSpecification = vmInitialSpecification;
84+
}
85+
return vmFinalSpecification;
86+
}
87+
}

0 commit comments

Comments
 (0)