mirror of https://github.com/apache/cloudstack.git
Refactoring the LibvirtComputingResource
- Adding LibvirtCheckOnHostCommandWrapper and LibvirtOvsCreateTunnelCommandWrapper - 4 unit tests added - KVM hypervisor plugin with 16.2% coverage
This commit is contained in:
parent
6748a73b82
commit
3c8b217262
|
|
@ -85,7 +85,6 @@ import com.ceph.rbd.RbdImage;
|
|||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.BackupSnapshotAnswer;
|
||||
import com.cloud.agent.api.BackupSnapshotCommand;
|
||||
import com.cloud.agent.api.CheckOnHostCommand;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
||||
|
|
@ -98,8 +97,6 @@ import com.cloud.agent.api.ManageSnapshotAnswer;
|
|||
import com.cloud.agent.api.ManageSnapshotCommand;
|
||||
import com.cloud.agent.api.NetworkUsageAnswer;
|
||||
import com.cloud.agent.api.NetworkUsageCommand;
|
||||
import com.cloud.agent.api.OvsCreateTunnelAnswer;
|
||||
import com.cloud.agent.api.OvsCreateTunnelCommand;
|
||||
import com.cloud.agent.api.PingCommand;
|
||||
import com.cloud.agent.api.PingRoutingCommand;
|
||||
import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
|
||||
|
|
@ -430,6 +427,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
return _ovsTunnelPath;
|
||||
}
|
||||
|
||||
public KVMHAMonitor getMonitor() {
|
||||
return _monitor;
|
||||
}
|
||||
|
||||
private static final class KeyValueInterpreter extends OutputInterpreter {
|
||||
private final Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
|
|
@ -1309,10 +1310,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
|
||||
} else if (cmd instanceof PvlanSetupCommand) {
|
||||
return execute((PvlanSetupCommand)cmd);
|
||||
} else if (cmd instanceof CheckOnHostCommand) {
|
||||
return execute((CheckOnHostCommand)cmd);
|
||||
} else if (cmd instanceof OvsCreateTunnelCommand) {
|
||||
return execute((OvsCreateTunnelCommand)cmd);
|
||||
} else {
|
||||
s_logger.warn("Unsupported command ");
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
|
|
@ -1398,39 +1395,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
return true;
|
||||
}
|
||||
|
||||
private OvsCreateTunnelAnswer execute(final OvsCreateTunnelCommand cmd) {
|
||||
final String bridge = cmd.getNetworkName();
|
||||
try {
|
||||
if (!findOrCreateTunnelNetwork(bridge)) {
|
||||
s_logger.debug("Error during bridge setup");
|
||||
return new OvsCreateTunnelAnswer(cmd, false,
|
||||
"Cannot create network", bridge);
|
||||
}
|
||||
|
||||
configureTunnelNetwork(cmd.getNetworkId(), cmd.getFrom(),
|
||||
cmd.getNetworkName());
|
||||
final Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
|
||||
command.add("create_tunnel");
|
||||
command.add("--bridge", bridge);
|
||||
command.add("--remote_ip", cmd.getRemoteIp());
|
||||
command.add("--key", cmd.getKey().toString());
|
||||
command.add("--src_host", cmd.getFrom().toString());
|
||||
command.add("--dst_host", cmd.getTo().toString());
|
||||
|
||||
final String result = command.execute();
|
||||
if (result != null) {
|
||||
return new OvsCreateTunnelAnswer(cmd, true, result, null,
|
||||
bridge);
|
||||
} else {
|
||||
return new OvsCreateTunnelAnswer(cmd, false, result, bridge);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
s_logger.debug("Error during tunnel setup");
|
||||
s_logger.warn("Caught execption when creating ovs tunnel", e);
|
||||
return new OvsCreateTunnelAnswer(cmd, false, e.getMessage(), bridge);
|
||||
}
|
||||
}
|
||||
|
||||
private CopyVolumeAnswer execute(final CopyVolumeCommand cmd) {
|
||||
/**
|
||||
This method is only used for copying files from Primary Storage TO Secondary Storage
|
||||
|
|
@ -1508,26 +1472,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
|
||||
}
|
||||
|
||||
protected Answer execute(final CheckOnHostCommand cmd) {
|
||||
final ExecutorService executors = Executors.newSingleThreadExecutor();
|
||||
final List<NfsStoragePool> pools = _monitor.getStoragePools();
|
||||
final KVMHAChecker ha = new KVMHAChecker(pools, cmd.getHost().getPrivateNetwork().getIp());
|
||||
final Future<Boolean> future = executors.submit(ha);
|
||||
try {
|
||||
final Boolean result = future.get();
|
||||
if (result) {
|
||||
return new Answer(cmd, false, "Heart is still beating...");
|
||||
} else {
|
||||
return new Answer(cmd);
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
return new Answer(cmd, false, "can't get status of host:");
|
||||
} catch (final ExecutionException e) {
|
||||
return new Answer(cmd, false, "can't get status of host:");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Storage.StorageResourceType getStorageResourceType() {
|
||||
return Storage.StorageResourceType.STORAGE_POOL;
|
||||
}
|
||||
|
|
@ -3795,28 +3739,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
return parser.getEmulator();
|
||||
}
|
||||
|
||||
private String getGuestType(final Connect conn, final String vmName) {
|
||||
final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
|
||||
Domain dm = null;
|
||||
try {
|
||||
dm = conn.domainLookupByName(vmName);
|
||||
final String xmlDesc = dm.getXMLDesc(0);
|
||||
parser.parseDomainXML(xmlDesc);
|
||||
return parser.getDescription();
|
||||
} catch (final LibvirtException e) {
|
||||
s_logger.trace("Ignoring libvirt error.", e);
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (dm != null) {
|
||||
dm.free();
|
||||
}
|
||||
} catch (final LibvirtException l) {
|
||||
s_logger.trace("Ignoring libvirt error.", l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isGuestPVEnabled(final String guestOSName) {
|
||||
if (guestOSName == null) {
|
||||
return false;
|
||||
|
|
@ -4304,13 +4226,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
@Override
|
||||
public void setName(final String name) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfigParams(final Map<String, Object> params) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -4328,7 +4248,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
@Override
|
||||
public void setRunLevel(final int level) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public HypervisorType getHypervisorType(){
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// 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.hypervisor.kvm.resource.wrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.CheckOnHostCommand;
|
||||
import com.cloud.agent.api.to.HostTO;
|
||||
import com.cloud.agent.api.to.NetworkTO;
|
||||
import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool;
|
||||
import com.cloud.hypervisor.kvm.resource.KVMHAChecker;
|
||||
import com.cloud.hypervisor.kvm.resource.KVMHAMonitor;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||
import com.cloud.resource.CommandWrapper;
|
||||
|
||||
public final class LibvirtCheckOnHostCommandWrapper extends CommandWrapper<CheckOnHostCommand, Answer, LibvirtComputingResource> {
|
||||
|
||||
@Override
|
||||
public Answer execute(final CheckOnHostCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||
final ExecutorService executors = Executors.newSingleThreadExecutor();
|
||||
final KVMHAMonitor monitor = libvirtComputingResource.getMonitor();
|
||||
|
||||
final List<NfsStoragePool> pools = monitor.getStoragePools();
|
||||
HostTO host = command.getHost();
|
||||
NetworkTO privateNetwork = host.getPrivateNetwork();
|
||||
final KVMHAChecker ha = new KVMHAChecker(pools, privateNetwork.getIp());
|
||||
|
||||
final Future<Boolean> future = executors.submit(ha);
|
||||
try {
|
||||
final Boolean result = future.get();
|
||||
if (result) {
|
||||
return new Answer(command, false, "Heart is still beating...");
|
||||
} else {
|
||||
return new Answer(command);
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
return new Answer(command, false, "can't get status of host:");
|
||||
} catch (final ExecutionException e) {
|
||||
return new Answer(command, false, "can't get status of host:");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.hypervisor.kvm.resource.wrapper;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.OvsCreateTunnelAnswer;
|
||||
import com.cloud.agent.api.OvsCreateTunnelCommand;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||
import com.cloud.resource.CommandWrapper;
|
||||
import com.cloud.utils.script.Script;
|
||||
|
||||
public final class LibvirtOvsCreateTunnelCommandWrapper extends CommandWrapper<OvsCreateTunnelCommand, Answer, LibvirtComputingResource> {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(LibvirtOvsCreateTunnelCommandWrapper.class);
|
||||
|
||||
@Override
|
||||
public Answer execute(final OvsCreateTunnelCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||
final String bridge = command.getNetworkName();
|
||||
try {
|
||||
if (!libvirtComputingResource.findOrCreateTunnelNetwork(bridge)) {
|
||||
s_logger.debug("Error during bridge setup");
|
||||
return new OvsCreateTunnelAnswer(command, false,
|
||||
"Cannot create network", bridge);
|
||||
}
|
||||
|
||||
libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
|
||||
command.getNetworkName());
|
||||
|
||||
final Script scriptCommand = new Script(libvirtComputingResource.getOvsTunnelPath(), libvirtComputingResource.getTimeout(), s_logger);
|
||||
scriptCommand.add("create_tunnel");
|
||||
scriptCommand.add("--bridge", bridge);
|
||||
scriptCommand.add("--remote_ip", command.getRemoteIp());
|
||||
scriptCommand.add("--key", command.getKey().toString());
|
||||
scriptCommand.add("--src_host", command.getFrom().toString());
|
||||
scriptCommand.add("--dst_host", command.getTo().toString());
|
||||
|
||||
final String result = scriptCommand.execute();
|
||||
if (result != null) {
|
||||
return new OvsCreateTunnelAnswer(command, true, result, null,
|
||||
bridge);
|
||||
} else {
|
||||
return new OvsCreateTunnelAnswer(command, false, result, bridge);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
s_logger.warn("Caught execption when creating ovs tunnel", e);
|
||||
return new OvsCreateTunnelAnswer(command, false, e.getMessage(), bridge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ import com.cloud.agent.api.AttachIsoCommand;
|
|||
import com.cloud.agent.api.AttachVolumeCommand;
|
||||
import com.cloud.agent.api.CheckHealthCommand;
|
||||
import com.cloud.agent.api.CheckNetworkCommand;
|
||||
import com.cloud.agent.api.CheckOnHostCommand;
|
||||
import com.cloud.agent.api.CheckVirtualMachineCommand;
|
||||
import com.cloud.agent.api.CleanupNetworkRulesCmd;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
|
@ -41,6 +42,7 @@ import com.cloud.agent.api.ModifySshKeysCommand;
|
|||
import com.cloud.agent.api.ModifyStoragePoolCommand;
|
||||
import com.cloud.agent.api.NetworkRulesSystemVmCommand;
|
||||
import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
|
||||
import com.cloud.agent.api.OvsCreateTunnelCommand;
|
||||
import com.cloud.agent.api.OvsDestroyBridgeCommand;
|
||||
import com.cloud.agent.api.OvsDestroyTunnelCommand;
|
||||
import com.cloud.agent.api.OvsFetchInterfaceCommand;
|
||||
|
|
@ -120,6 +122,8 @@ public class LibvirtRequestWrapper extends RequestWrapper {
|
|||
linbvirtCommands.put(CheckSshCommand.class, new LibvirtCheckSshCommandWrapper());
|
||||
linbvirtCommands.put(CheckNetworkCommand.class, new LibvirtCheckNetworkCommandWrapper());
|
||||
linbvirtCommands.put(OvsDestroyTunnelCommand.class, new LibvirtOvsDestroyTunnelCommandWrapper());
|
||||
linbvirtCommands.put(CheckOnHostCommand.class, new LibvirtCheckOnHostCommandWrapper());
|
||||
linbvirtCommands.put(OvsCreateTunnelCommand.class, new LibvirtOvsCreateTunnelCommandWrapper());
|
||||
|
||||
resources.put(LibvirtComputingResource.class, linbvirtCommands);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ import com.cloud.agent.api.AttachIsoCommand;
|
|||
import com.cloud.agent.api.AttachVolumeCommand;
|
||||
import com.cloud.agent.api.CheckHealthCommand;
|
||||
import com.cloud.agent.api.CheckNetworkCommand;
|
||||
import com.cloud.agent.api.CheckOnHostCommand;
|
||||
import com.cloud.agent.api.CheckVirtualMachineCommand;
|
||||
import com.cloud.agent.api.CleanupNetworkRulesCmd;
|
||||
import com.cloud.agent.api.CreateStoragePoolCommand;
|
||||
|
|
@ -83,6 +84,7 @@ import com.cloud.agent.api.ModifySshKeysCommand;
|
|||
import com.cloud.agent.api.ModifyStoragePoolCommand;
|
||||
import com.cloud.agent.api.NetworkRulesSystemVmCommand;
|
||||
import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
|
||||
import com.cloud.agent.api.OvsCreateTunnelCommand;
|
||||
import com.cloud.agent.api.OvsDestroyBridgeCommand;
|
||||
import com.cloud.agent.api.OvsDestroyTunnelCommand;
|
||||
import com.cloud.agent.api.OvsFetchInterfaceCommand;
|
||||
|
|
@ -2542,4 +2544,114 @@ public class LibvirtComputingResourceTest {
|
|||
|
||||
verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckOnHostCommand() {
|
||||
final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);;
|
||||
|
||||
final CheckOnHostCommand command = new CheckOnHostCommand(host);
|
||||
|
||||
final KVMHAMonitor monitor = Mockito.mock(KVMHAMonitor.class);
|
||||
|
||||
when(libvirtComputingResource.getMonitor()).thenReturn(monitor);
|
||||
|
||||
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||
assertNotNull(wrapper);
|
||||
|
||||
final Answer answer = wrapper.execute(command, libvirtComputingResource);
|
||||
assertTrue(answer.getResult());
|
||||
|
||||
verify(libvirtComputingResource, times(1)).getMonitor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOvsCreateTunnelCommand() {
|
||||
final String remoteIp = "172.16.16.16";
|
||||
final Integer key = 1;
|
||||
final Long from = 1l;
|
||||
final Long to = 2l;
|
||||
final long networkId = 1l;
|
||||
final String fromIp = "172.15.15.15";
|
||||
final String networkName = "eth";
|
||||
final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
|
||||
|
||||
final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
|
||||
|
||||
final String bridge = command.getNetworkName();
|
||||
|
||||
when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(true);
|
||||
when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
|
||||
command.getNetworkName())).thenReturn(true);
|
||||
|
||||
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||
assertNotNull(wrapper);
|
||||
|
||||
final Answer answer = wrapper.execute(command, libvirtComputingResource);
|
||||
assertTrue(answer.getResult());
|
||||
|
||||
verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
|
||||
verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
|
||||
command.getNetworkName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOvsCreateTunnelCommandFailure1() {
|
||||
final String remoteIp = "172.16.16.16";
|
||||
final Integer key = 1;
|
||||
final Long from = 1l;
|
||||
final Long to = 2l;
|
||||
final long networkId = 1l;
|
||||
final String fromIp = "172.15.15.15";
|
||||
final String networkName = "eth";
|
||||
final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
|
||||
|
||||
final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
|
||||
|
||||
final String bridge = command.getNetworkName();
|
||||
|
||||
when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(false);
|
||||
when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
|
||||
command.getNetworkName())).thenReturn(true);
|
||||
|
||||
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||
assertNotNull(wrapper);
|
||||
|
||||
final Answer answer = wrapper.execute(command, libvirtComputingResource);
|
||||
assertFalse(answer.getResult());
|
||||
|
||||
verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
|
||||
verify(libvirtComputingResource, times(0)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
|
||||
command.getNetworkName());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testOvsCreateTunnelCommandFailure2() {
|
||||
final String remoteIp = "172.16.16.16";
|
||||
final Integer key = 1;
|
||||
final Long from = 1l;
|
||||
final Long to = 2l;
|
||||
final long networkId = 1l;
|
||||
final String fromIp = "172.15.15.15";
|
||||
final String networkName = "eth";
|
||||
final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
|
||||
|
||||
final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
|
||||
|
||||
final String bridge = command.getNetworkName();
|
||||
|
||||
when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(true);
|
||||
when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
|
||||
command.getNetworkName())).thenThrow(Exception.class);
|
||||
|
||||
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||
assertNotNull(wrapper);
|
||||
|
||||
final Answer answer = wrapper.execute(command, libvirtComputingResource);
|
||||
assertFalse(answer.getResult());
|
||||
|
||||
verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
|
||||
verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
|
||||
command.getNetworkName());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue