Merge branch 'refactor/libvirt_resource' of https://github.com/schubergphilis/cloudstack

This closes #233
This commit is contained in:
wilderrodrigues 2015-05-13 11:23:12 +02:00
commit 45c0fa2faa
82 changed files with 10117 additions and 3021 deletions

View File

@ -53,9 +53,9 @@ public class SnapshotCommand extends Command {
* is the value of that field If you have better ideas on how to
* get it, you are welcome.
*/
public SnapshotCommand(StoragePool pool, String secondaryStorageUrl, String snapshotUuid, String snapshotName, Long dcId, Long accountId, Long volumeId) {
// this.primaryStoragePoolNameLabel = pool.getUuid();
//this.primaryPool = new StorageFilerTO(pool);
public SnapshotCommand(final StoragePool pool, final String secondaryStorageUrl, final String snapshotUuid, final String snapshotName, final Long dcId, final Long accountId, final Long volumeId) {
primaryStoragePoolNameLabel = pool.getUuid();
primaryPool = new StorageFilerTO(pool);
this.snapshotUuid = snapshotUuid;
this.secondaryStorageUrl = secondaryStorageUrl;
this.dcId = dcId;
@ -112,7 +112,7 @@ public class SnapshotCommand extends Command {
return volumePath;
}
public void setVolumePath(String path) {
public void setVolumePath(final String path) {
volumePath = path;
}

View File

@ -19,81 +19,16 @@
package com.cloud.resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
public abstract class CommandWrapper<T extends Command, A extends Answer, R extends ServerResource> {
private static final Logger s_logger = Logger.getLogger(CommandWrapper.class);
/**
* @param T is the command to be used.
* @param R is the resource base to be used.
* @return A and the Answer from the command.
*/
public abstract A execute(T command, R serverResource);
/**
* Common method so we added it here.
*
* @param cmd
* @param proxyVmId
* @param proxyVmName
* @param proxyManagementIp
* @param cmdPort
* @return
*/
protected Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) {
String result = null;
final StringBuffer sb = new StringBuffer();
sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus");
boolean success = true;
try {
final URL url = new URL(sb.toString());
final URLConnection conn = url.openConnection();
// setting TIMEOUTs to avoid possible waiting until death situations
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
final InputStream is = conn.getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.defaultCharset()));
final StringBuilder sb2 = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb2.append(line + "\n");
}
result = sb2.toString();
} catch (final IOException e) {
success = false;
} finally {
try {
is.close();
} catch (final IOException e) {
s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp);
success = false;
}
}
} catch (final IOException e) {
s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp);
success = false;
}
return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result);
}
}

View File

@ -19,14 +19,93 @@
package com.cloud.resource;
import java.util.Hashtable;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
public abstract class RequestWrapper {
@SuppressWarnings("rawtypes")
protected Hashtable<Class<? extends ServerResource>, Hashtable<Class<? extends Command>, CommandWrapper>> resources = new Hashtable<Class<? extends ServerResource>, Hashtable<Class<? extends Command>, CommandWrapper>>();
/**
* @param command to be executed.
* @return an Answer for the executed command.
*/
public abstract Answer execute(Command command, ServerResource serverResource);
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Hashtable<Class<? extends Command>, CommandWrapper> retrieveResource(final Command command, final Class<? extends ServerResource> resourceClass) {
Class<? extends ServerResource> keepResourceClass = resourceClass;
Hashtable<Class<? extends Command>, CommandWrapper> resource = resources.get(keepResourceClass);
while (resource == null) {
try {
final Class<? extends ServerResource> keepResourceClass2 = (Class<? extends ServerResource>) keepResourceClass.getSuperclass();
resource = resources.get(keepResourceClass2);
keepResourceClass = keepResourceClass2;
} catch (final ClassCastException e) {
throw new NullPointerException("No key found for '" + command.getClass() + "' in the Map!");
}
}
return resource;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected CommandWrapper<Command, Answer, ServerResource> retrieveCommands(final Class<? extends Command> commandClass,
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands) {
Class<? extends Command> keepCommandClass = commandClass;
CommandWrapper<Command, Answer, ServerResource> commandWrapper = resourceCommands.get(keepCommandClass);
while (commandWrapper == null) {
try {
final Class<? extends Command> commandClass2 = (Class<? extends Command>) keepCommandClass.getSuperclass();
if (commandClass2 == null) {
throw new NullPointerException("All the COMMAND hierarchy tree has been visited but no compliant key has been found for '" + commandClass + "'.");
}
commandWrapper = resourceCommands.get(commandClass2);
keepCommandClass = commandClass2;
} catch (final NullPointerException e) {
// Will now traverse all the resource hierarchy. Returning null
// is not a problem.
// It is all being nicely checked and in case we do not have a
// resource, an Unsupported answer will be thrown by the base
// class.
return null;
}
}
return commandWrapper;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected CommandWrapper<Command, Answer, ServerResource> retryWhenAllFails(final Command command, final Class<? extends ServerResource> resourceClass,
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands) {
Class<? extends ServerResource> keepResourceClass = resourceClass;
CommandWrapper<Command, Answer, ServerResource> commandWrapper = resourceCommands.get(command.getClass());
while (commandWrapper == null) {
// Could not find the command in the given resource, will traverse
// the family tree.
try {
final Class<? extends ServerResource> resourceClass2 = (Class<? extends ServerResource>) keepResourceClass.getSuperclass();
if (resourceClass2 == null) {
throw new NullPointerException("All the SERVER-RESOURCE hierarchy tree has been visited but no compliant key has been found for '" + command.getClass() + "'.");
}
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands2 = retrieveResource(command,
(Class<? extends ServerResource>) keepResourceClass.getSuperclass());
keepResourceClass = resourceClass2;
commandWrapper = retrieveCommands(command.getClass(), resourceCommands2);
} catch (final NullPointerException e) {
throw e;
}
}
return commandWrapper;
}
}

View File

@ -19,15 +19,14 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.DiskTO;
public final class AttachCommand extends Command implements StorageSubSystemCommand {
public final class AttachCommand extends StorageSubSystemCommand {
private DiskTO disk;
private String vmName;
private boolean inSeq = false;
private boolean inSeq;
public AttachCommand(DiskTO disk, String vmName) {
public AttachCommand(final DiskTO disk, final String vmName) {
super();
this.disk = disk;
this.vmName = vmName;
@ -42,7 +41,7 @@ public final class AttachCommand extends Command implements StorageSubSystemComm
return disk;
}
public void setDisk(DiskTO disk) {
public void setDisk(final DiskTO disk) {
this.disk = disk;
}
@ -50,12 +49,12 @@ public final class AttachCommand extends Command implements StorageSubSystemComm
return vmName;
}
public void setVmName(String vmName) {
public void setVmName(final String vmName) {
this.vmName = vmName;
}
@Override
public void setExecuteInSequence(boolean inSeq) {
public void setExecuteInSequence(final boolean inSeq) {
this.inSeq = inSeq;
}
}

View File

@ -19,17 +19,16 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
public final class AttachPrimaryDataStoreCmd extends Command implements StorageSubSystemCommand {
public final class AttachPrimaryDataStoreCmd extends StorageSubSystemCommand {
@Override
public void setExecuteInSequence(boolean inSeq) {
public void setExecuteInSequence(final boolean inSeq) {
}
private final String dataStore;
public AttachPrimaryDataStoreCmd(String uri) {
public AttachPrimaryDataStoreCmd(final String uri) {
super();
dataStore = uri;
}

View File

@ -22,10 +22,9 @@ package org.apache.cloudstack.storage.command;
import java.util.HashMap;
import java.util.Map;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.DataTO;
public final class CopyCommand extends Command implements StorageSubSystemCommand {
public final class CopyCommand extends StorageSubSystemCommand {
private DataTO srcTO;
private DataTO destTO;
private DataTO cacheTO;
@ -33,28 +32,28 @@ public final class CopyCommand extends Command implements StorageSubSystemComman
private Map<String, String> options = new HashMap<String, String>();
private Map<String, String> options2 = new HashMap<String, String>();
public CopyCommand(DataTO srcData, DataTO destData, int timeout, boolean executeInSequence) {
public CopyCommand(final DataTO srcData, final DataTO destData, final int timeout, final boolean executeInSequence) {
super();
this.srcTO = srcData;
this.destTO = destData;
this.setWait(timeout);
srcTO = srcData;
destTO = destData;
setWait(timeout);
this.executeInSequence = executeInSequence;
}
public DataTO getDestTO() {
return this.destTO;
return destTO;
}
public void setSrcTO(DataTO srcTO) {
public void setSrcTO(final DataTO srcTO) {
this.srcTO = srcTO;
}
public void setDestTO(DataTO destTO) {
public void setDestTO(final DataTO destTO) {
this.destTO = destTO;
}
public DataTO getSrcTO() {
return this.srcTO;
return srcTO;
}
@Override
@ -66,15 +65,15 @@ public final class CopyCommand extends Command implements StorageSubSystemComman
return cacheTO;
}
public void setCacheTO(DataTO cacheTO) {
public void setCacheTO(final DataTO cacheTO) {
this.cacheTO = cacheTO;
}
public int getWaitInMillSeconds() {
return this.getWait() * 1000;
return getWait() * 1000;
}
public void setOptions(Map<String, String> options) {
public void setOptions(final Map<String, String> options) {
this.options = options;
}
@ -82,7 +81,7 @@ public final class CopyCommand extends Command implements StorageSubSystemComman
return options;
}
public void setOptions2(Map<String, String> options2) {
public void setOptions2(final Map<String, String> options2) {
this.options2 = options2;
}
@ -91,7 +90,7 @@ public final class CopyCommand extends Command implements StorageSubSystemComman
}
@Override
public void setExecuteInSequence(boolean inSeq) {
this.executeInSequence = inSeq;
public void setExecuteInSequence(final boolean inSeq) {
executeInSequence = inSeq;
}
}

View File

@ -19,13 +19,12 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.DataTO;
public final class CreateObjectCommand extends Command implements StorageSubSystemCommand {
public final class CreateObjectCommand extends StorageSubSystemCommand {
private DataTO data;
public CreateObjectCommand(DataTO obj) {
public CreateObjectCommand(final DataTO obj) {
super();
data = obj;
}
@ -44,7 +43,7 @@ public final class CreateObjectCommand extends Command implements StorageSubSyst
}
@Override
public void setExecuteInSequence(boolean inSeq) {
public void setExecuteInSequence(final boolean inSeq) {
}
}

View File

@ -19,18 +19,17 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
public final class CreatePrimaryDataStoreCmd extends Command implements StorageSubSystemCommand {
public final class CreatePrimaryDataStoreCmd extends StorageSubSystemCommand {
private final String dataStore;
public CreatePrimaryDataStoreCmd(String uri) {
public CreatePrimaryDataStoreCmd(final String uri) {
super();
this.dataStore = uri;
dataStore = uri;
}
public String getDataStore() {
return this.dataStore;
return dataStore;
}
@Override
@ -39,7 +38,7 @@ public final class CreatePrimaryDataStoreCmd extends Command implements StorageS
}
@Override
public void setExecuteInSequence(boolean inSeq) {
public void setExecuteInSequence(final boolean inSeq) {
}
}

View File

@ -19,13 +19,12 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.DataTO;
public final class DeleteCommand extends Command implements StorageSubSystemCommand {
public final class DeleteCommand extends StorageSubSystemCommand {
private DataTO data;
public DeleteCommand(DataTO data) {
public DeleteCommand(final DataTO data) {
super();
this.data = data;
}
@ -44,7 +43,7 @@ public final class DeleteCommand extends Command implements StorageSubSystemComm
}
@Override
public void setExecuteInSequence(boolean inSeq) {
public void setExecuteInSequence(final boolean inSeq) {
}
}

View File

@ -19,10 +19,9 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.DiskTO;
public class DettachCommand extends Command implements StorageSubSystemCommand {
public class DettachCommand extends StorageSubSystemCommand {
private DiskTO disk;
private String vmName;
private boolean _managed;
@ -30,7 +29,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand {
private String _storageHost;
private int _storagePort;
public DettachCommand(DiskTO disk, String vmName) {
public DettachCommand(final DiskTO disk, final String vmName) {
super();
this.disk = disk;
this.vmName = vmName;
@ -45,7 +44,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand {
return disk;
}
public void setDisk(DiskTO disk) {
public void setDisk(final DiskTO disk) {
this.disk = disk;
}
@ -53,11 +52,11 @@ public class DettachCommand extends Command implements StorageSubSystemCommand {
return vmName;
}
public void setVmName(String vmName) {
public void setVmName(final String vmName) {
this.vmName = vmName;
}
public void setManaged(boolean managed) {
public void setManaged(final boolean managed) {
_managed = managed;
}
@ -65,7 +64,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand {
return _managed;
}
public void set_iScsiName(String iScsiName) {
public void set_iScsiName(final String iScsiName) {
_iScsiName = iScsiName;
}
@ -73,7 +72,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand {
return _iScsiName;
}
public void setStorageHost(String storageHost) {
public void setStorageHost(final String storageHost) {
_storageHost = storageHost;
}
@ -81,7 +80,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand {
return _storageHost;
}
public void setStoragePort(int storagePort) {
public void setStoragePort(final int storagePort) {
_storagePort = storagePort;
}
@ -90,7 +89,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand {
}
@Override
public void setExecuteInSequence(boolean inSeq) {
public void setExecuteInSequence(final boolean inSeq) {
}
}

View File

@ -19,13 +19,12 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.DataTO;
public class ForgetObjectCmd extends Command implements StorageSubSystemCommand {
private DataTO dataTO;
public class ForgetObjectCmd extends StorageSubSystemCommand {
private final DataTO dataTO;
public ForgetObjectCmd(DataTO data) {
public ForgetObjectCmd(final DataTO data) {
dataTO = data;
}
@ -39,7 +38,7 @@ public class ForgetObjectCmd extends Command implements StorageSubSystemCommand
}
@Override
public void setExecuteInSequence(boolean inSeq) {
public void setExecuteInSequence(final boolean inSeq) {
}
}

View File

@ -19,13 +19,12 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.DataTO;
public class IntroduceObjectCmd extends Command implements StorageSubSystemCommand {
private DataTO dataTO;
public class IntroduceObjectCmd extends StorageSubSystemCommand {
private final DataTO dataTO;
public IntroduceObjectCmd(DataTO dataTO) {
public IntroduceObjectCmd(final DataTO dataTO) {
this.dataTO = dataTO;
}
@ -39,7 +38,7 @@ public class IntroduceObjectCmd extends Command implements StorageSubSystemComma
}
@Override
public void setExecuteInSequence(boolean inSeq) {
public void setExecuteInSequence(final boolean inSeq) {
}
}

View File

@ -19,18 +19,16 @@
package org.apache.cloudstack.storage.command;
import com.cloud.agent.api.Command;
import java.util.Map;
public final class SnapshotAndCopyCommand extends Command implements StorageSubSystemCommand {
private String _uuidOfSourceVdi;
private Map<String, String> _sourceDetails;
private Map<String, String> _destDetails;
public final class SnapshotAndCopyCommand extends StorageSubSystemCommand {
private final String _uuidOfSourceVdi;
private final Map<String, String> _sourceDetails;
private final Map<String, String> _destDetails;
private boolean _executeInSequence = true;
public SnapshotAndCopyCommand(String uuidOfSourceVdi, Map<String, String> sourceDetails, Map<String, String> destDetails) {
public SnapshotAndCopyCommand(final String uuidOfSourceVdi, final Map<String, String> sourceDetails, final Map<String, String> destDetails) {
_uuidOfSourceVdi = uuidOfSourceVdi;
_sourceDetails = sourceDetails;
_destDetails = destDetails;
@ -49,7 +47,7 @@ public final class SnapshotAndCopyCommand extends Command implements StorageSubS
}
@Override
public void setExecuteInSequence(boolean executeInSequence) {
public void setExecuteInSequence(final boolean executeInSequence) {
_executeInSequence = executeInSequence;
}

View File

@ -19,6 +19,8 @@
package org.apache.cloudstack.storage.command;
public interface StorageSubSystemCommand {
void setExecuteInSequence(boolean inSeq);
}
import com.cloud.agent.api.Command;
public abstract class StorageSubSystemCommand extends Command {
public abstract void setExecuteInSequence(boolean inSeq);
}

View File

@ -31,4 +31,7 @@
<property name="name" value="KVMInvestigator" />
</bean>
<bean id="libvirtUtilitiesHelper"
class="com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper" />
</beans>

View File

@ -0,0 +1,38 @@
package com.cloud.hypervisor.kvm.resource;
import java.util.concurrent.Callable;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
public class MigrateKVMAsync implements Callable<Domain> {
private final LibvirtComputingResource libvirtComputingResource;
private Domain dm = null;
private Connect dconn = null;
private String dxml = "";
private String vmName = "";
private String destIp = "";
public MigrateKVMAsync(final LibvirtComputingResource libvirtComputingResource, final Domain dm, final Connect dconn, final String dxml, final String vmName, final String destIp) {
this.libvirtComputingResource = libvirtComputingResource;
this.dm = dm;
this.dconn = dconn;
this.dxml = dxml;
this.vmName = vmName;
this.destIp = destIp;
}
@Override
public Domain call() throws LibvirtException {
// set compression flag for migration if libvirt version supports it
if (dconn.getLibVirVersion() < 1003000) {
return dm.migrate(dconn, 1 << 0, dxml, vmName, "tcp:" + destIp, libvirtComputingResource.getMigrateSpeed());
} else {
return dm.migrate(dconn, 1 << 0|1 << 11, dxml, vmName, "tcp:" + destIp, libvirtComputingResource.getMigrateSpeed());
}
}
}

View File

@ -0,0 +1,52 @@
//
// 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.net.URISyntaxException;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtAttachIsoCommandWrapper extends CommandWrapper<AttachIsoCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final AttachIsoCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName());
libvirtComputingResource.attachOrDetachISO(conn, command.getVmName(), command.getIsoPath(), command.isAttach());
} catch (final LibvirtException e) {
return new Answer(command, false, e.toString());
} catch (final URISyntaxException e) {
return new Answer(command, false, e.toString());
} catch (final InternalErrorException e) {
return new Answer(command, false, e.toString());
}
return new Answer(command);
}
}

View File

@ -0,0 +1,58 @@
//
// 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.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachVolumeAnswer;
import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.resource.CommandWrapper;
public final class LibvirtAttachVolumeCommandWrapper extends CommandWrapper<AttachVolumeCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final AttachVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName());
final KVMStoragePool primary = libvirtComputingResource.getStoragePoolMgr().getStoragePool(command.getPooltype(), command.getPoolUuid());
final KVMPhysicalDisk disk = primary.getPhysicalDisk(command.getVolumePath());
libvirtComputingResource.attachOrDetachDisk(conn, command.getAttach(), command.getVmName(), disk,
command.getDeviceId().intValue(), command.getBytesReadRate(), command.getBytesWriteRate(), command.getIopsReadRate(), command.getIopsWriteRate(),
command.getCacheMode());
} catch (final LibvirtException e) {
return new AttachVolumeAnswer(command, e.toString());
} catch (final InternalErrorException e) {
return new AttachVolumeAnswer(command, e.toString());
}
return new AttachVolumeAnswer(command, command.getDeviceId(), command.getVolumePath());
}
}

View File

@ -0,0 +1,204 @@
//
// 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.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.MessageFormat;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.DomainInfo.DomainState;
import org.libvirt.DomainSnapshot;
import org.libvirt.LibvirtException;
import com.ceph.rados.IoCTX;
import com.ceph.rados.Rados;
import com.ceph.rados.RadosException;
import com.ceph.rbd.Rbd;
import com.ceph.rbd.RbdException;
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.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
public final class LibvirtBackupSnapshotCommandWrapper extends CommandWrapper<BackupSnapshotCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtBackupSnapshotCommandWrapper.class);
@Override
public Answer execute(final BackupSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) {
final Long dcId = command.getDataCenterId();
final Long accountId = command.getAccountId();
final Long volumeId = command.getVolumeId();
final String secondaryStoragePoolUrl = command.getSecondaryStorageUrl();
final String snapshotName = command.getSnapshotName();
String snapshotDestPath = null;
String snapshotRelPath = null;
final String vmName = command.getVmName();
KVMStoragePool secondaryStoragePool = null;
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
final String ssPmountPath = secondaryStoragePool.getLocalPath();
snapshotRelPath = File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel());
final KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(command.getVolumePath());
final String manageSnapshotPath = libvirtComputingResource.manageSnapshotPath();
final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout();
/**
* RBD snapshots can't be copied using qemu-img, so we have to use
* the Java bindings for librbd here.
*
* These bindings will read the snapshot and write the contents to
* the secondary storage directly
*
* It will stop doing so if the amount of time spend is longer then
* cmds.timeout
*/
if (primaryPool.getType() == StoragePoolType.RBD) {
try {
final Rados r = new Rados(primaryPool.getAuthUserName());
r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort());
r.confSet("key", primaryPool.getAuthSecret());
r.confSet("client_mount_timeout", "30");
r.connect();
s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir());
final Rbd rbd = new Rbd(io);
final RbdImage image = rbd.open(snapshotDisk.getName(), snapshotName);
final File fh = new File(snapshotDestPath);
try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fh));) {
final int chunkSize = 4194304;
long offset = 0;
s_logger.debug("Backuping up RBD snapshot " + snapshotName + " to " + snapshotDestPath);
while (true) {
final byte[] buf = new byte[chunkSize];
final int bytes = image.read(offset, buf, chunkSize);
if (bytes <= 0) {
break;
}
bos.write(buf, 0, bytes);
offset += bytes;
}
s_logger.debug("Completed backing up RBD snapshot " + snapshotName + " to " + snapshotDestPath + ". Bytes written: " + offset);
}catch(final IOException ex)
{
s_logger.error("BackupSnapshotAnswer:Exception:"+ ex.getMessage());
}
r.ioCtxDestroy(io);
} catch (final RadosException e) {
s_logger.error("A RADOS operation failed. The error was: " + e.getMessage());
return new BackupSnapshotAnswer(command, false, e.toString(), null, true);
} catch (final RbdException e) {
s_logger.error("A RBD operation on " + snapshotDisk.getName() + " failed. The error was: " + e.getMessage());
return new BackupSnapshotAnswer(command, false, e.toString(), null, true);
}
} else {
final Script scriptCommand = new Script(manageSnapshotPath, cmdsTimeout, s_logger);
scriptCommand.add("-b", snapshotDisk.getPath());
scriptCommand.add("-n", snapshotName);
scriptCommand.add("-p", snapshotDestPath);
scriptCommand.add("-t", snapshotName);
final String result = scriptCommand.execute();
if (result != null) {
s_logger.debug("Failed to backup snaptshot: " + result);
return new BackupSnapshotAnswer(command, false, result, null, true);
}
}
/* Delete the snapshot on primary */
DomainState state = null;
Domain vm = null;
if (vmName != null) {
try {
vm = libvirtComputingResource.getDomain(conn, command.getVmName());
state = vm.getInfo().state;
} catch (final LibvirtException e) {
s_logger.trace("Ignoring libvirt error.", e);
}
}
final KVMStoragePool primaryStorage = storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPool().getUuid());
if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) {
final MessageFormat snapshotXML = new MessageFormat(" <domainsnapshot>" + " <name>{0}</name>" + " <domain>"
+ " <uuid>{1}</uuid>" + " </domain>" + " </domainsnapshot>");
final String vmUuid = vm.getUUIDString();
final Object[] args = new Object[] {snapshotName, vmUuid};
final String snapshot = snapshotXML.format(args);
s_logger.debug(snapshot);
final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
snap.delete(0);
/*
* libvirt on RHEL6 doesn't handle resume event emitted from
* qemu
*/
vm = libvirtComputingResource.getDomain(conn, command.getVmName());
state = vm.getInfo().state;
if (state == DomainState.VIR_DOMAIN_PAUSED) {
vm.resume();
}
} else {
final Script scriptCommand = new Script(manageSnapshotPath, cmdsTimeout, s_logger);
scriptCommand.add("-d", snapshotDisk.getPath());
scriptCommand.add("-n", snapshotName);
final String result = scriptCommand.execute();
if (result != null) {
s_logger.debug("Failed to backup snapshot: " + result);
return new BackupSnapshotAnswer(command, false, "Failed to backup snapshot: " + result, null, true);
}
}
} catch (final LibvirtException e) {
return new BackupSnapshotAnswer(command, false, e.toString(), null, true);
} catch (final CloudRuntimeException e) {
return new BackupSnapshotAnswer(command, false, e.toString(), null, true);
} finally {
if (secondaryStoragePool != null) {
storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
}
}
return new BackupSnapshotAnswer(command, true, null, snapshotRelPath + File.separator + snapshotName, true);
}
}

View File

@ -0,0 +1,41 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.ServerResource;
public class LibvirtCheckConsoleProxyLoadCommandWrapper extends LibvirtConsoleProxyLoadCommandWrapper<CheckConsoleProxyLoadCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final Command command, final ServerResource serverResource) {
final CheckConsoleProxyLoadCommand cmd = (CheckConsoleProxyLoadCommand) command;
final long proxyVmId = cmd.getProxyVmId();
final String proxyVmName = cmd.getProxyVmName();
final String proxyManagementIp = cmd.getProxyManagementIp();
final int proxyCmdPort = cmd.getProxyCmdPort();
return executeProxyLoadScan(cmd, proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort);
}
}

View File

@ -0,0 +1,34 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckHealthAnswer;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtCheckHealthCommandWrapper extends CommandWrapper<CheckHealthCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final CheckHealthCommand command, final LibvirtComputingResource libvirtComputingResource) {
return new CheckHealthAnswer(command, true);
}
}

View File

@ -0,0 +1,57 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckNetworkAnswer;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.network.PhysicalNetworkSetupInfo;
import com.cloud.resource.CommandWrapper;
public final class LibvirtCheckNetworkCommandWrapper extends CommandWrapper<CheckNetworkCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final CheckNetworkCommand command, final LibvirtComputingResource libvirtComputingResource) {
final List<PhysicalNetworkSetupInfo> phyNics = command.getPhysicalNetworkInfoList();
String errMsg = null;
for (final PhysicalNetworkSetupInfo nic : phyNics) {
if (!libvirtComputingResource.checkNetwork(nic.getGuestNetworkName())) {
errMsg = "Can not find network: " + nic.getGuestNetworkName();
break;
} else if (!libvirtComputingResource.checkNetwork(nic.getPrivateNetworkName())) {
errMsg = "Can not find network: " + nic.getPrivateNetworkName();
break;
} else if (!libvirtComputingResource.checkNetwork(nic.getPublicNetworkName())) {
errMsg = "Can not find network: " + nic.getPublicNetworkName();
break;
}
}
if (errMsg != null) {
return new CheckNetworkAnswer(command, false, errMsg);
} else {
return new CheckNetworkAnswer(command, true, null);
}
}
}

View File

@ -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:");
}
}
}

View File

@ -0,0 +1,56 @@
//
// 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.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtCheckSshCommandWrapper extends CommandWrapper<CheckSshCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.class);
@Override
public Answer execute(final CheckSshCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String vmName = command.getName();
final String privateIp = command.getIp();
final int cmdPort = command.getPort();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
}
final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource();
if (!virtRouterResource.connect(privateIp, cmdPort)) {
return new CheckSshAnswer(command, "Can not ping System vm " + vmName + " because of a connection failure");
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Ping command port succeeded for vm " + vmName);
}
return new CheckSshAnswer(command);
}
}

View File

@ -0,0 +1,51 @@
//
// 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.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.vm.VirtualMachine.PowerState;
public final class LibvirtCheckVirtualMachineCommandWrapper extends CommandWrapper<CheckVirtualMachineCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final CheckVirtualMachineCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName());
final PowerState state = libvirtComputingResource.getVmState(conn, command.getVmName());
Integer vncPort = null;
if (state == PowerState.PowerOn) {
vncPort = libvirtComputingResource.getVncPort(conn, command.getVmName());
}
return new CheckVirtualMachineAnswer(command, state, vncPort);
} catch (final LibvirtException e) {
return new CheckVirtualMachineAnswer(command, e.getMessage());
}
}
}

View File

@ -0,0 +1,34 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtCleanupNetworkRulesCommandWrapper extends CommandWrapper<CleanupNetworkRulesCmd, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final CleanupNetworkRulesCmd command, final LibvirtComputingResource libvirtComputingResource) {
final boolean result = libvirtComputingResource.cleanupRules();
return new Answer(command, result, "");
}
}

View File

@ -0,0 +1,78 @@
//
// 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.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ServerResource;
public abstract class LibvirtConsoleProxyLoadCommandWrapper<T extends Command, A extends Answer, R extends ServerResource> extends CommandWrapper<Command, Answer, ServerResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtConsoleProxyLoadCommandWrapper.class);
public Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) {
String result = null;
final StringBuffer sb = new StringBuffer();
sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus");
boolean success = true;
try {
final URL url = new URL(sb.toString());
final URLConnection conn = url.openConnection();
final InputStream is = conn.getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
final StringBuilder sb2 = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb2.append(line + "\n");
}
result = sb2.toString();
} catch (final IOException e) {
success = false;
} finally {
try {
is.close();
} catch (final IOException e) {
s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp);
success = false;
}
}
} catch (final IOException e) {
s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp);
success = false;
}
return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result);
}
}

View File

@ -0,0 +1,98 @@
//
// 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.io.File;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.CopyVolumeAnswer;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.exception.CloudRuntimeException;
public final class LibvirtCopyVolumeCommandWrapper extends CommandWrapper<CopyVolumeCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final CopyVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
/**
* This method is only used for copying files from Primary Storage TO
* Secondary Storage
*
* It COULD also do it the other way around, but the code in the
* ManagementServerImpl shows that it always sets copyToSecondary to
* true
*/
final boolean copyToSecondary = command.toSecondaryStorage();
String volumePath = command.getVolumePath();
final StorageFilerTO pool = command.getPool();
final String secondaryStorageUrl = command.getSecondaryStorageURL();
KVMStoragePool secondaryStoragePool = null;
KVMStoragePool primaryPool = null;
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
try {
try {
primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid());
} catch (final CloudRuntimeException e) {
if (e.getMessage().contains("not found")) {
primaryPool = storagePoolMgr.createStoragePool(pool.getUuid(), pool.getHost(), pool.getPort(), pool.getPath(), pool.getUserInfo(), pool.getType());
} else {
return new CopyVolumeAnswer(command, false, e.getMessage(), null, null);
}
}
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final String volumeName = libvirtUtilitiesHelper.generatereUUIDName();
if (copyToSecondary) {
final String destVolumeName = volumeName + ".qcow2";
final KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(command.getVolumePath());
final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl);
secondaryStoragePool.createFolder(volumeDestPath);
storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumeDestPath);
storagePoolMgr.copyPhysicalDisk(volume, destVolumeName, secondaryStoragePool, 0);
return new CopyVolumeAnswer(command, true, null, null, volumeName);
} else {
volumePath = "/volumes/" + command.getVolumeId() + File.separator;
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumePath);
final KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(command.getVolumePath() + ".qcow2");
storagePoolMgr.copyPhysicalDisk(volume, volumeName, primaryPool, 0);
return new CopyVolumeAnswer(command, true, null, null, volumeName);
}
} catch (final CloudRuntimeException e) {
return new CopyVolumeAnswer(command, false, e.toString(), null, null);
} finally {
if (secondaryStoragePool != null) {
storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
}
}
}
}

View File

@ -0,0 +1,83 @@
//
// 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.storage.CreateAnswer;
import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DiskProfile;
public final class LibvirtCreateCommandWrapper extends CommandWrapper<CreateCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtCreateCommandWrapper.class);
@Override
public Answer execute(final CreateCommand command, final LibvirtComputingResource libvirtComputingResource) {
final StorageFilerTO pool = command.getPool();
final DiskProfile dskch = command.getDiskCharacteristics();
KVMPhysicalDisk baseVol = null;
KVMStoragePool primaryPool = null;
KVMPhysicalDisk vol = null;
long disksize;
try {
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid());
disksize = dskch.getSize();
if (command.getTemplateUrl() != null) {
if (primaryPool.getType() == StoragePoolType.CLVM) {
vol = libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primaryPool, dskch.getPath());
} else {
baseVol = primaryPool.getPhysicalDisk(command.getTemplateUrl());
vol = storagePoolMgr.createDiskFromTemplate(baseVol,
dskch.getPath(), dskch.getProvisioningType(), primaryPool, 0);
}
if (vol == null) {
return new Answer(command, false, " Can't create storage volume on storage pool");
}
} else {
vol = primaryPool.createPhysicalDisk(dskch.getPath(), dskch.getProvisioningType(), dskch.getSize());
}
final VolumeTO volume =
new VolumeTO(command.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), pool.getPath(), vol.getName(), vol.getName(), disksize, null);
volume.setBytesReadRate(dskch.getBytesReadRate());
volume.setBytesWriteRate(dskch.getBytesWriteRate());
volume.setIopsReadRate(dskch.getIopsReadRate());
volume.setIopsWriteRate(dskch.getIopsWriteRate());
volume.setCacheMode(dskch.getCacheMode());
return new CreateAnswer(command, volume);
} catch (final CloudRuntimeException e) {
s_logger.debug("Failed to create volume: " + e.toString());
return new CreateAnswer(command, e);
}
}
}

View File

@ -0,0 +1,113 @@
//
// 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.io.File;
import java.io.IOException;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.template.Processor;
import com.cloud.storage.template.Processor.FormatInfo;
import com.cloud.storage.template.TemplateLocation;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
public final class LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper extends CommandWrapper<CreatePrivateTemplateFromSnapshotCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.class);
@Override
public Answer execute(final CreatePrivateTemplateFromSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
final String templateInstallFolder = "template/tmpl/" + templateFolder;
final String tmplName = libvirtUtilitiesHelper.generatereUUIDName();
final String tmplFileName = tmplName + ".qcow2";
KVMStoragePool secondaryPool = null;
KVMStoragePool snapshotPool = null;
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
try {
String snapshotPath = command.getSnapshotUuid();
final int index = snapshotPath.lastIndexOf("/");
snapshotPath = snapshotPath.substring(0, index);
snapshotPool = storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
secondaryPool = storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl());
final KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(command.getSnapshotName());
final String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
final StorageLayer storage = libvirtComputingResource.getStorage();
storage.mkdirs(templatePath);
final String tmplPath = templateInstallFolder + File.separator + tmplFileName;
final String createTmplPath = libvirtComputingResource.createTmplPath();
final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout();
final Script scriptCommand = new Script(createTmplPath, cmdsTimeout, s_logger);
scriptCommand.add("-t", templatePath);
scriptCommand.add("-n", tmplFileName);
scriptCommand.add("-f", snapshot.getPath());
scriptCommand.execute();
final Processor qcow2Processor = libvirtUtilitiesHelper.buildQCOW2Processor(storage);
final FormatInfo info = qcow2Processor.process(templatePath, null, tmplName);
final TemplateLocation loc = libvirtUtilitiesHelper.buildTemplateLocation(storage, templatePath);
loc.create(1, true, tmplName);
loc.addFormat(info);
loc.save();
return new CreatePrivateTemplateAnswer(command, true, "", tmplPath, info.virtualSize, info.size, tmplName, info.format);
} catch (final ConfigurationException e) {
return new CreatePrivateTemplateAnswer(command, false, e.getMessage());
} catch (final InternalErrorException e) {
return new CreatePrivateTemplateAnswer(command, false, e.getMessage());
} catch (final IOException e) {
return new CreatePrivateTemplateAnswer(command, false, e.getMessage());
} catch (final CloudRuntimeException e) {
return new CreatePrivateTemplateAnswer(command, false, e.getMessage());
} finally {
if (secondaryPool != null) {
storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid());
}
if (snapshotPool != null) {
storagePoolMgr.deleteStoragePool(snapshotPool.getType(), snapshotPool.getUuid());
}
}
}
}

View File

@ -0,0 +1,176 @@
//
// 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.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.utils.qemu.QemuImg;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.cloudstack.utils.qemu.QemuImgException;
import org.apache.cloudstack.utils.qemu.QemuImgFile;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.template.Processor;
import com.cloud.storage.template.Processor.FormatInfo;
import com.cloud.storage.template.QCOW2Processor;
import com.cloud.storage.template.TemplateLocation;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
public final class LibvirtCreatePrivateTemplateFromVolumeCommandWrapper extends CommandWrapper<CreatePrivateTemplateFromVolumeCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.class);
@Override
public Answer execute(final CreatePrivateTemplateFromVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String secondaryStorageURL = command.getSecondaryStorageUrl();
KVMStoragePool secondaryStorage = null;
KVMStoragePool primary = null;
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
try {
final String templateFolder = command.getAccountId() + File.separator + command.getTemplateId() + File.separator;
final String templateInstallFolder = "/template/tmpl/" + templateFolder;
secondaryStorage = storagePoolMgr.getStoragePoolByURI(secondaryStorageURL);
try {
primary = storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel());
} catch (final CloudRuntimeException e) {
if (e.getMessage().contains("not found")) {
primary =
storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(),
command.getPool().getUserInfo(), command.getPool().getType());
} else {
return new CreatePrivateTemplateAnswer(command, false, e.getMessage());
}
}
final KVMPhysicalDisk disk = primary.getPhysicalDisk(command.getVolumePath());
final String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateInstallFolder;
final StorageLayer storage = libvirtComputingResource.getStorage();
storage.mkdirs(tmpltPath);
if (primary.getType() != StoragePoolType.RBD) {
final String createTmplPath = libvirtComputingResource.createTmplPath();
final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout();
final Script scriptCommand = new Script(createTmplPath, cmdsTimeout, s_logger);
scriptCommand.add("-f", disk.getPath());
scriptCommand.add("-t", tmpltPath);
scriptCommand.add("-n", command.getUniqueName() + ".qcow2");
final String result = scriptCommand.execute();
if (result != null) {
s_logger.debug("failed to create template: " + result);
return new CreatePrivateTemplateAnswer(command, false, result);
}
} else {
s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + command.getUniqueName());
final QemuImgFile srcFile =
new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), primary.getSourcePort(), primary.getAuthUserName(),
primary.getAuthSecret(), disk.getPath()));
srcFile.setFormat(PhysicalDiskFormat.RAW);
final QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + command.getUniqueName() + ".qcow2");
destFile.setFormat(PhysicalDiskFormat.QCOW2);
final QemuImg q = new QemuImg(0);
try {
q.convert(srcFile, destFile);
} catch (final QemuImgException e) {
s_logger.error("Failed to create new template while converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " +
e.getMessage());
}
final File templateProp = new File(tmpltPath + "/template.properties");
if (!templateProp.exists()) {
templateProp.createNewFile();
}
String templateContent = "filename=" + command.getUniqueName() + ".qcow2" + System.getProperty("line.separator");
final DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy");
final Date date = new Date();
templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");
try(FileOutputStream templFo = new FileOutputStream(templateProp);) {
templFo.write(templateContent.getBytes());
templFo.flush();
}catch(final IOException ex)
{
s_logger.error("CreatePrivateTemplateAnswer:Exception:"+ex.getMessage());
}
}
final Map<String, Object> params = new HashMap<String, Object>();
params.put(StorageLayer.InstanceConfigKey, storage);
final Processor qcow2Processor = new QCOW2Processor();
qcow2Processor.configure("QCOW2 Processor", params);
final FormatInfo info = qcow2Processor.process(tmpltPath, null, command.getUniqueName());
final TemplateLocation loc = new TemplateLocation(storage, tmpltPath);
loc.create(1, true, command.getUniqueName());
loc.addFormat(info);
loc.save();
return new CreatePrivateTemplateAnswer(command, true, null, templateInstallFolder + command.getUniqueName() + ".qcow2", info.virtualSize, info.size,
command.getUniqueName(), ImageFormat.QCOW2);
} catch (final InternalErrorException e) {
return new CreatePrivateTemplateAnswer(command, false, e.toString());
} catch (final IOException e) {
return new CreatePrivateTemplateAnswer(command, false, e.toString());
} catch (final ConfigurationException e) {
return new CreatePrivateTemplateAnswer(command, false, e.toString());
} catch (final CloudRuntimeException e) {
return new CreatePrivateTemplateAnswer(command, false, e.toString());
} finally {
if (secondaryStorage != null) {
storagePoolMgr.deleteStoragePool(secondaryStorage.getType(), secondaryStorage.getUuid());
}
}
}
}

View File

@ -0,0 +1,33 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtCreateStoragePoolCommandWrapper extends CommandWrapper<CreateStoragePoolCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final CreateStoragePoolCommand command, final LibvirtComputingResource libvirtComputingResource) {
return new Answer(command, true, "success");
}
}

View File

@ -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 java.util.UUID;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.exception.CloudRuntimeException;
public final class LibvirtCreateVolumeFromSnapshotCommandWrapper extends CommandWrapper<CreateVolumeFromSnapshotCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final CreateVolumeFromSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
String snapshotPath = command.getSnapshotUuid();
final int index = snapshotPath.lastIndexOf("/");
snapshotPath = snapshotPath.substring(0, index);
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
final KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
final KVMPhysicalDisk snapshot = secondaryPool.getPhysicalDisk(command.getSnapshotName());
final String primaryUuid = command.getPrimaryStoragePoolNameLabel();
final StorageFilerTO pool = command.getPool();
final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getType(), primaryUuid);
final String volUuid = UUID.randomUUID().toString();
final KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool, 0);
if (disk == null) {
throw new NullPointerException("Disk was not successfully copied to the new storage.");
}
return new CreateVolumeFromSnapshotAnswer(command, true, "", disk.getName());
} catch (final CloudRuntimeException e) {
return new CreateVolumeFromSnapshotAnswer(command, false, e.toString(), null);
} catch (final Exception e) {
return new CreateVolumeFromSnapshotAnswer(command, false, e.toString(), null);
}
}
}

View File

@ -0,0 +1,43 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.exception.CloudRuntimeException;
public final class LibvirtDeleteStoragePoolCommandWrapper extends CommandWrapper<DeleteStoragePoolCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final DeleteStoragePoolCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
StorageFilerTO pool = command.getPool();
KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
storagePoolMgr.deleteStoragePool(pool.getType(), pool.getUuid());
return new Answer(command);
} catch (final CloudRuntimeException e) {
return new Answer(command, false, e.toString());
}
}
}

View File

@ -0,0 +1,50 @@
//
// 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.storage.DestroyCommand;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.exception.CloudRuntimeException;
public final class LibvirtDestroyCommandWrapper extends CommandWrapper<DestroyCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtDestroyCommandWrapper.class);
@Override
public Answer execute(final DestroyCommand command, final LibvirtComputingResource libvirtComputingResource) {
final VolumeTO vol = command.getVolume();
try {
KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
final KVMStoragePool pool = storagePoolMgr.getStoragePool(vol.getPoolType(), vol.getPoolUuid());
pool.deletePhysicalDisk(vol.getPath(), null);
return new Answer(command, true, "Success");
} catch (final CloudRuntimeException e) {
s_logger.debug("Failed to delete volume: " + e.toString());
return new Answer(command, false, e.toString());
}
}
}

View File

@ -0,0 +1,67 @@
//
// 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 org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.FenceAnswer;
import com.cloud.agent.api.FenceCommand;
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 LibvirtFenceCommandWrapper extends CommandWrapper<FenceCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtFenceCommandWrapper.class);
@Override
public Answer execute(final FenceCommand command, final LibvirtComputingResource libvirtComputingResource) {
final ExecutorService executors = Executors.newSingleThreadExecutor();
final KVMHAMonitor monitor = libvirtComputingResource.getMonitor();
final List<NfsStoragePool> pools = monitor.getStoragePools();
final KVMHAChecker ha = new KVMHAChecker(pools, command.getHostIp());
final Future<Boolean> future = executors.submit(ha);
try {
final Boolean result = future.get();
if (result) {
return new FenceAnswer(command, false, "Heart is still beating...");
} else {
return new FenceAnswer(command);
}
} catch (final InterruptedException e) {
s_logger.warn("Unable to fence", e);
return new FenceAnswer(command, false, e.getMessage());
} catch (final ExecutionException e) {
s_logger.warn("Unable to fence", e);
return new FenceAnswer(command, false, e.getMessage());
}
}
}

View File

@ -0,0 +1,80 @@
//
// 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.GetHostStatsAnswer;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.HostStatsEntry;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.Pair;
import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.Script;
public final class LibvirtGetHostStatsCommandWrapper extends CommandWrapper<GetHostStatsCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtGetHostStatsCommandWrapper.class);
@Override
public Answer execute(final GetHostStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
final Script cpuScript = new Script("/bin/bash", s_logger);
cpuScript.add("-c");
cpuScript.add("idle=$(top -b -n 1| awk -F, '/^[%]*[Cc]pu/{$0=$4; gsub(/[^0-9.,]+/,\"\"); print }'); echo $idle");
final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
String result = cpuScript.execute(parser);
if (result != null) {
s_logger.debug("Unable to get the host CPU state: " + result);
return new Answer(command, false, result);
}
final double cpuUtil = 100.0D - Double.parseDouble(parser.getLine());
long freeMem = 0;
final Script memScript = new Script("/bin/bash", s_logger);
memScript.add("-c");
memScript.add("freeMem=$(free|grep cache:|awk '{print $4}');echo $freeMem");
final OutputInterpreter.OneLineParser Memparser = new OutputInterpreter.OneLineParser();
result = memScript.execute(Memparser);
if (result != null) {
s_logger.debug("Unable to get the host Mem state: " + result);
return new Answer(command, false, result);
}
freeMem = Long.parseLong(Memparser.getLine());
final Script totalMem = new Script("/bin/bash", s_logger);
totalMem.add("-c");
totalMem.add("free|grep Mem:|awk '{print $2}'");
final OutputInterpreter.OneLineParser totMemparser = new OutputInterpreter.OneLineParser();
result = totalMem.execute(totMemparser);
if (result != null) {
s_logger.debug("Unable to get the host Mem state: " + result);
return new Answer(command, false, result);
}
final long totMem = Long.parseLong(totMemparser.getLine());
final Pair<Double, Double> nicStats = libvirtComputingResource.getNicStats(libvirtComputingResource.getPublicBridgeName());
final HostStatsEntry hostStats = new HostStatsEntry(command.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", totMem, freeMem, 0, 0);
return new GetHostStatsAnswer(command, hostStats);
}
}

View File

@ -0,0 +1,43 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.exception.CloudRuntimeException;
public final class LibvirtGetStorageStatsCommandWrapper extends CommandWrapper<GetStorageStatsCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final GetStorageStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
final KVMStoragePool sp = storagePoolMgr.getStoragePool(command.getPooltype(), command.getStorageId(), true);
return new GetStorageStatsAnswer(command, sp.getCapacity(), sp.getUsed());
} catch (final CloudRuntimeException e) {
return new GetStorageStatsAnswer(command, e.toString());
}
}
}

View File

@ -0,0 +1,62 @@
//
// 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.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.GetVmDiskStatsAnswer;
import com.cloud.agent.api.GetVmDiskStatsCommand;
import com.cloud.agent.api.VmDiskStatsEntry;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtGetVmDiskStatsCommandWrapper extends CommandWrapper<GetVmDiskStatsCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtGetVmDiskStatsCommandWrapper.class);
@Override
public Answer execute(final GetVmDiskStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
final List<String> vmNames = command.getVmNames();
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
try {
final HashMap<String, List<VmDiskStatsEntry>> vmDiskStatsNameMap = new HashMap<String, List<VmDiskStatsEntry>>();
final Connect conn = libvirtUtilitiesHelper.getConnection();
for (final String vmName : vmNames) {
final List<VmDiskStatsEntry> statEntry = libvirtComputingResource.getVmDiskStat(conn, vmName);
if (statEntry == null) {
continue;
}
vmDiskStatsNameMap.put(vmName, statEntry);
}
return new GetVmDiskStatsAnswer(command, "", command.getHostName(), vmDiskStatsNameMap);
} catch (final LibvirtException e) {
s_logger.debug("Can't get vm disk stats: " + e.toString());
return new GetVmDiskStatsAnswer(command, null, null, null);
}
}
}

View File

@ -0,0 +1,63 @@
//
// 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.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.GetVmStatsAnswer;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.VmStatsEntry;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtGetVmStatsCommandWrapper extends CommandWrapper<GetVmStatsCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtGetVmStatsCommandWrapper.class);
@Override
public Answer execute(final GetVmStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
final List<String> vmNames = command.getVmNames();
try {
final HashMap<String, VmStatsEntry> vmStatsNameMap = new HashMap<String, VmStatsEntry>();
for (final String vmName : vmNames) {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
final VmStatsEntry statEntry = libvirtComputingResource.getVmStat(conn, vmName);
if (statEntry == null) {
continue;
}
vmStatsNameMap.put(vmName, statEntry);
}
return new GetVmStatsAnswer(command, vmStatsNameMap);
} catch (final LibvirtException e) {
s_logger.debug("Can't get vm stats: " + e.toString());
return new GetVmStatsAnswer(command, null);
}
}
}

View File

@ -0,0 +1,45 @@
//
// 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.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtGetVncPortCommandWrapper extends CommandWrapper<GetVncPortCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final GetVncPortCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(command.getName());
final Integer vncPort = libvirtComputingResource.getVncPort(conn, command.getName());
return new GetVncPortAnswer(command, libvirtComputingResource.getPrivateIp(), 5900 + vncPort);
} catch (final LibvirtException e) {
return new GetVncPortAnswer(command, e.toString());
}
}
}

View File

@ -0,0 +1,34 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtMaintainCommandWrapper extends CommandWrapper<MaintainCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final MaintainCommand command, final LibvirtComputingResource libvirtComputingResource) {
return new MaintainAnswer(command);
}
}

View File

@ -0,0 +1,167 @@
//
// 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.io.File;
import java.text.MessageFormat;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.DomainInfo.DomainState;
import org.libvirt.DomainSnapshot;
import org.libvirt.LibvirtException;
import com.ceph.rados.IoCTX;
import com.ceph.rados.Rados;
import com.ceph.rbd.Rbd;
import com.ceph.rbd.RbdImage;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ManageSnapshotAnswer;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.utils.script.Script;
public final class LibvirtManageSnapshotCommandWrapper extends CommandWrapper<ManageSnapshotCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtManageSnapshotCommandWrapper.class);
@Override
public Answer execute(final ManageSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String snapshotName = command.getSnapshotName();
final String snapshotPath = command.getSnapshotPath();
final String vmName = command.getVmName();
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
DomainState state = null;
Domain vm = null;
if (vmName != null) {
try {
vm = libvirtComputingResource.getDomain(conn, command.getVmName());
state = vm.getInfo().state;
} catch (final LibvirtException e) {
s_logger.trace("Ignoring libvirt error.", e);
}
}
KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
StorageFilerTO pool = command.getPool();
final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid());
final KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(command.getVolumePath());
if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) {
final MessageFormat snapshotXML = new MessageFormat(" <domainsnapshot>" + " <name>{0}</name>" + " <domain>"
+ " <uuid>{1}</uuid>" + " </domain>" + " </domainsnapshot>");
final String vmUuid = vm.getUUIDString();
final Object[] args = new Object[] {snapshotName, vmUuid};
final String snapshot = snapshotXML.format(args);
s_logger.debug(snapshot);
if (command.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
vm.snapshotCreateXML(snapshot);
} else {
final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
snap.delete(0);
}
/*
* libvirt on RHEL6 doesn't handle resume event emitted from
* qemu
*/
vm = libvirtComputingResource.getDomain(conn, command.getVmName());
state = vm.getInfo().state;
if (state == DomainState.VIR_DOMAIN_PAUSED) {
vm.resume();
}
} else {
/**
* For RBD we can't use libvirt to do our snapshotting or any Bash scripts.
* libvirt also wants to store the memory contents of the Virtual Machine,
* but that's not possible with RBD since there is no way to store the memory
* contents in RBD.
*
* So we rely on the Java bindings for RBD to create our snapshot
*
* This snapshot might not be 100% consistent due to writes still being in the
* memory of the Virtual Machine, but if the VM runs a kernel which supports
* barriers properly (>2.6.32) this won't be any different then pulling the power
* cord out of a running machine.
*/
if (primaryPool.getType() == StoragePoolType.RBD) {
try {
final Rados r = new Rados(primaryPool.getAuthUserName());
r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort());
r.confSet("key", primaryPool.getAuthSecret());
r.confSet("client_mount_timeout", "30");
r.connect();
s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir());
final Rbd rbd = new Rbd(io);
final RbdImage image = rbd.open(disk.getName());
if (command.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
s_logger.debug("Attempting to create RBD snapshot " + disk.getName() + "@" + snapshotName);
image.snapCreate(snapshotName);
} else {
s_logger.debug("Attempting to remove RBD snapshot " + disk.getName() + "@" + snapshotName);
image.snapRemove(snapshotName);
}
rbd.close(image);
r.ioCtxDestroy(io);
} catch (final Exception e) {
s_logger.error("A RBD snapshot operation on " + disk.getName() + " failed. The error was: " + e.getMessage());
}
} else {
/* VM is not running, create a snapshot by ourself */
final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout();
final String manageSnapshotPath = libvirtComputingResource.manageSnapshotPath();
final Script scriptCommand = new Script(manageSnapshotPath, cmdsTimeout, s_logger);
if (command.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
scriptCommand.add("-c", disk.getPath());
} else {
scriptCommand.add("-d", snapshotPath);
}
scriptCommand.add("-n", snapshotName);
final String result = scriptCommand.execute();
if (result != null) {
s_logger.debug("Failed to manage snapshot: " + result);
return new ManageSnapshotAnswer(command, false, "Failed to manage snapshot: " + result);
}
}
}
return new ManageSnapshotAnswer(command, command.getSnapshotId(), disk.getPath() + File.separator + snapshotName, true, null);
} catch (final LibvirtException e) {
s_logger.debug("Failed to manage snapshot: " + e.toString());
return new ManageSnapshotAnswer(command, false, "Failed to manage snapshot: " + e.toString());
}
}
}

View File

@ -0,0 +1,183 @@
//
// 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.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.DomainInfo.DomainState;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.MigrateAnswer;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.MigrateKVMAsync;
import com.cloud.hypervisor.kvm.resource.VifDriver;
import com.cloud.resource.CommandWrapper;
public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtMigrateCommandWrapper.class);
@Override
public Answer execute(final MigrateCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String vmName = command.getVmName();
String result = null;
List<InterfaceDef> ifaces = null;
List<DiskDef> disks = null;
Domain dm = null;
Connect dconn = null;
Domain destDomain = null;
Connect conn = null;
String xmlDesc = null;
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
ifaces = libvirtComputingResource.getInterfaces(conn, vmName);
disks = libvirtComputingResource.getDisks(conn, vmName);
dm = conn.domainLookupByName(vmName);
/*
We replace the private IP address with the address of the destination host.
This is because the VNC listens on the private IP address of the hypervisor,
but that address is ofcourse different on the target host.
MigrateCommand.getDestinationIp() returns the private IP address of the target
hypervisor. So it's safe to use.
The Domain.migrate method from libvirt supports passing a different XML
description for the instance to be used on the target host.
This is supported by libvirt-java from version 0.50.0
*/
xmlDesc = dm.getXMLDesc(0).replace(libvirtComputingResource.getPrivateIp(), command.getDestinationIp());
dconn = new Connect("qemu+tcp://" + command.getDestinationIp() + "/system");
//run migration in thread so we can monitor it
s_logger.info("Live migration of instance " + vmName + " initiated");
final ExecutorService executor = Executors.newFixedThreadPool(1);
final Callable<Domain> worker = new MigrateKVMAsync(libvirtComputingResource, dm, dconn, xmlDesc, vmName, command.getDestinationIp());
final Future<Domain> migrateThread = executor.submit(worker);
executor.shutdown();
long sleeptime = 0;
while (!executor.isTerminated()) {
Thread.sleep(100);
sleeptime += 100;
if (sleeptime == 1000) { // wait 1s before attempting to set downtime on migration, since I don't know of a VIR_DOMAIN_MIGRATING state
final int migrateDowntime = libvirtComputingResource.getMigrateDowntime();
if (migrateDowntime > 0 ) {
try {
final int setDowntime = dm.migrateSetMaxDowntime(migrateDowntime);
if (setDowntime == 0 ) {
s_logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(migrateDowntime) + "ms");
}
} catch (final LibvirtException e) {
s_logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage());
}
}
}
if (sleeptime % 1000 == 0) {
s_logger.info("Waiting for migration of " + vmName + " to complete, waited " + sleeptime + "ms");
}
// pause vm if we meet the vm.migrate.pauseafter threshold and not already paused
final int migratePauseAfter = libvirtComputingResource.getMigratePauseAfter();
if (migratePauseAfter > 0 && sleeptime > migratePauseAfter && dm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING ) {
s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + migratePauseAfter+ "ms to complete migration");
try {
dm.suspend();
} catch (final LibvirtException e) {
// pause could be racy if it attempts to pause right when vm is finished, simply warn
s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage());
}
}
}
s_logger.info("Migration thread for " + vmName + " is done");
destDomain = migrateThread.get(10, TimeUnit.SECONDS);
if (destDomain != null) {
for (final DiskDef disk : disks) {
libvirtComputingResource.cleanupDisk(disk);
}
}
} catch (final LibvirtException e) {
s_logger.debug("Can't migrate domain: " + e.getMessage());
result = e.getMessage();
} catch (final InterruptedException e) {
s_logger.debug("Interrupted while migrating domain: " + e.getMessage());
result = e.getMessage();
} catch (final ExecutionException e) {
s_logger.debug("Failed to execute while migrating domain: " + e.getMessage());
result = e.getMessage();
} catch (final TimeoutException e) {
s_logger.debug("Timed out while migrating domain: " + e.getMessage());
result = e.getMessage();
} finally {
try {
if (dm != null) {
if (dm.isPersistent() == 1) {
dm.undefine();
}
dm.free();
}
if (dconn != null) {
dconn.close();
}
if (destDomain != null) {
destDomain.free();
}
} catch (final LibvirtException e) {
s_logger.trace("Ignoring libvirt error.", e);
}
}
if (result != null) {
} else {
libvirtComputingResource.destroyNetworkRulesForVM(conn, vmName);
for (final InterfaceDef iface : ifaces) {
// We don't know which "traffic type" is associated with
// each interface at this point, so inform all vif drivers
final List<VifDriver> allVifDrivers = libvirtComputingResource.getAllVifDrivers();
for (final VifDriver vifDriver : allVifDrivers) {
vifDriver.unplug(iface);
}
}
}
return new MigrateAnswer(command, result == null, result, null);
}
}

View File

@ -0,0 +1,119 @@
//
// 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.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ModifySshKeysCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.script.Script;
public final class LibvirtModifySshKeysCommandWrapper extends CommandWrapper<ModifySshKeysCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtModifySshKeysCommandWrapper.class);
@Override
public Answer execute(final ModifySshKeysCommand command, final LibvirtComputingResource libvirtComputingResource) {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final String sshkeyspath = libvirtUtilitiesHelper.retrieveSshKeysPath();
final String sshpubkeypath = libvirtUtilitiesHelper.retrieveSshPubKeyPath();
final String sshprvkeypath = libvirtUtilitiesHelper.retrieveSshPrvKeyPath();
final File sshKeysDir = new File(sshkeyspath);
String result = null;
if (!sshKeysDir.exists()) {
// Change permissions for the 700
final Script script = new Script("mkdir", libvirtComputingResource.getTimeout(), s_logger);
script.add("-m", "700");
script.add(sshkeyspath);
script.execute();
if (!sshKeysDir.exists()) {
s_logger.debug("failed to create directory " + sshkeyspath);
}
}
final File pubKeyFile = new File(sshpubkeypath);
if (!pubKeyFile.exists()) {
try {
pubKeyFile.createNewFile();
} catch (final IOException e) {
result = "Failed to create file: " + e.toString();
s_logger.debug(result);
}
}
if (pubKeyFile.exists()) {
try (FileOutputStream pubkStream = new FileOutputStream(pubKeyFile)) {
pubkStream.write(command.getPubKey().getBytes());
} catch (final FileNotFoundException e) {
result = "File" + sshpubkeypath + "is not found:"
+ e.toString();
s_logger.debug(result);
} catch (final IOException e) {
result = "Write file " + sshpubkeypath + ":" + e.toString();
s_logger.debug(result);
}
}
final File prvKeyFile = new File(sshprvkeypath);
if (!prvKeyFile.exists()) {
try {
prvKeyFile.createNewFile();
} catch (final IOException e) {
result = "Failed to create file: " + e.toString();
s_logger.debug(result);
}
}
if (prvKeyFile.exists()) {
final String prvKey = command.getPrvKey();
try (FileOutputStream prvKStream = new FileOutputStream(prvKeyFile);){
if ( prvKStream != null) {
prvKStream.write(prvKey.getBytes());
}
} catch (final FileNotFoundException e) {
result = "File" + sshprvkeypath + "is not found:" + e.toString();
s_logger.debug(result);
} catch (final IOException e) {
result = "Write file " + sshprvkeypath + ":" + e.toString();
s_logger.debug(result);
}
final Script script = new Script("chmod", libvirtComputingResource.getTimeout(), s_logger);
script.add("600", sshprvkeypath);
script.execute();
}
if (result != null) {
return new Answer(command, false, result);
} else {
return new Answer(command, true, null);
}
}
}

View File

@ -0,0 +1,51 @@
//
// 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.HashMap;
import java.util.Map;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ModifyStoragePoolAnswer;
import com.cloud.agent.api.ModifyStoragePoolCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.template.TemplateProp;
public final class LibvirtModifyStoragePoolCommandWrapper extends CommandWrapper<ModifyStoragePoolCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final ModifyStoragePoolCommand command, final LibvirtComputingResource libvirtComputingResource) {
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
final KVMStoragePool storagepool =
storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
.getUserInfo(), command.getPool().getType());
if (storagepool == null) {
return new Answer(command, false, " Failed to create storage pool");
}
final Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
final ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(command, storagepool.getCapacity(), storagepool.getAvailable(), tInfo);
return answer;
}
}

View File

@ -0,0 +1,35 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtNetworkElementCommandWrapper extends CommandWrapper<NetworkElementCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final NetworkElementCommand command, final LibvirtComputingResource libvirtComputingResource) {
final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource();
return virtRouterResource.executeRequest(command);
}
}

View File

@ -0,0 +1,49 @@
//
// 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 org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.NetworkRulesSystemVmCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtNetworkRulesSystemVmCommandWrapper extends CommandWrapper<NetworkRulesSystemVmCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.class);
@Override
public Answer execute(final NetworkRulesSystemVmCommand command, final LibvirtComputingResource libvirtComputingResource) {
boolean success = false;
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName());
success = libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, command.getVmName());
} catch (final LibvirtException e) {
s_logger.trace("Ignoring libvirt error.", e);
}
return new Answer(command, success, "");
}
}

View File

@ -0,0 +1,49 @@
//
// 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 org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtNetworkRulesVmSecondaryIpCommandWrapper extends CommandWrapper<NetworkRulesVmSecondaryIpCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.class);
@Override
public Answer execute(final NetworkRulesVmSecondaryIpCommand command, final LibvirtComputingResource libvirtComputingResource) {
boolean result = false;
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName());
result = libvirtComputingResource.configureNetworkRulesVMSecondaryIP(conn, command.getVmName(), command.getVmSecIp(), command.getAction());
} catch (final LibvirtException e) {
s_logger.debug("Could not configure VM secondary IP! => " + e.getLocalizedMessage());
}
return new Answer(command, result, "");
}
}

View File

@ -0,0 +1,57 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.NetworkUsageAnswer;
import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtNetworkUsageCommandWrapper extends CommandWrapper<NetworkUsageCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final NetworkUsageCommand command, final LibvirtComputingResource libvirtComputingResource) {
if (command.isForVpc()) {
if (command.getOption() != null && command.getOption().equals("create")) {
final String result = libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR());
final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, result, 0L, 0L);
return answer;
} else if (command.getOption() != null && (command.getOption().equals("get") || command.getOption().equals("vpn"))) {
final long[] stats = libvirtComputingResource.getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption());
final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, "", stats[0], stats[1]);
return answer;
} else {
final String result = libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR());
final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, result, 0L, 0L);
return answer;
}
} else {
if (command.getOption() != null && command.getOption().equals("create")) {
final String result = libvirtComputingResource.networkUsage(command.getPrivateIP(), "create", null);
final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, result, 0L, 0L);
return answer;
}
final long [] stats = libvirtComputingResource.getNetworkStats(command.getPrivateIP());
final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, "", stats[0], stats[1]);
return answer;
}
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,43 @@
//
// 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.OvsDestroyBridgeCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtOvsDestroyBridgeCommandWrapper extends CommandWrapper<OvsDestroyBridgeCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsDestroyBridgeCommandWrapper.class);
@Override
public Answer execute(final OvsDestroyBridgeCommand command, final LibvirtComputingResource libvirtComputingResource) {
final boolean result = libvirtComputingResource.destroyTunnelNetwork(command.getBridgeName());
if (!result) {
s_logger.debug("Error trying to destroy OVS Bridge!");
}
return new Answer(command, result, null);
}
}

View File

@ -0,0 +1,58 @@
//
// 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.OvsDestroyTunnelCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.script.Script;
public final class LibvirtOvsDestroyTunnelCommandWrapper extends CommandWrapper<OvsDestroyTunnelCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsDestroyTunnelCommandWrapper.class);
@Override
public Answer execute(final OvsDestroyTunnelCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
if (!libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())) {
s_logger.warn("Unable to find tunnel network for GRE key:"
+ command.getBridgeName());
return new Answer(command, false, "No network found");
}
final Script scriptCommand = new Script(libvirtComputingResource.getOvsTunnelPath(), libvirtComputingResource.getTimeout(), s_logger);
scriptCommand.add("destroy_tunnel");
scriptCommand.add("--bridge", command.getBridgeName());
scriptCommand.add("--iface_name", command.getInPortName());
final String result = scriptCommand.execute();
if (result == null) {
return new Answer(command, true, result);
} else {
return new Answer(command, false, result);
}
} catch (final Exception e) {
s_logger.warn("caught execption when destroy ovs tunnel", e);
return new Answer(command, false, e.getMessage());
}
}
}

View File

@ -0,0 +1,53 @@
//
// 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.OvsFetchInterfaceAnswer;
import com.cloud.agent.api.OvsFetchInterfaceCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.script.Script;
public final class LibvirtOvsFetchInterfaceCommandWrapper extends CommandWrapper<OvsFetchInterfaceCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsFetchInterfaceCommandWrapper.class);
@Override
public Answer execute(final OvsFetchInterfaceCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String label = command.getLabel();
s_logger.debug("Will look for network with name-label:" + label);
try {
final String ipadd = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'");
final String mask = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f4");
final String mac = Script.runSimpleBashScript("ifconfig " + label + " | grep HWaddr | awk -F \" \" '{print $5}'");
return new OvsFetchInterfaceAnswer(command, true, "Interface " + label
+ " retrieved successfully", ipadd, mask, mac);
} catch (final Exception e) {
s_logger.warn("Caught execption when fetching interface", e);
return new OvsFetchInterfaceAnswer(command, false, "EXCEPTION:"
+ e.getMessage());
}
}
}

View File

@ -0,0 +1,47 @@
//
// 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.OvsSetupBridgeCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtOvsSetupBridgeCommandWrapper extends CommandWrapper<OvsSetupBridgeCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsSetupBridgeCommandWrapper.class);
@Override
public Answer execute(final OvsSetupBridgeCommand command, final LibvirtComputingResource libvirtComputingResource) {
final boolean findResult = libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName());
final boolean configResult = libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
command.getBridgeName());
final boolean finalResult = findResult && configResult;
if (!finalResult) {
s_logger.debug("::FAILURE:: OVS Bridge was NOT configured properly!");
}
return new Answer(command, finalResult, null);
}
}

View File

@ -0,0 +1,53 @@
//
// 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.OvsVpcPhysicalTopologyConfigCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.script.Script;
public final class LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper extends CommandWrapper<OvsVpcPhysicalTopologyConfigCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.class);
@Override
public Answer execute(final OvsVpcPhysicalTopologyConfigCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
final Script scriptCommand = new Script(libvirtComputingResource.getOvsTunnelPath(), libvirtComputingResource.getTimeout(), s_logger);
scriptCommand.add("configure_ovs_bridge_for_network_topology");
scriptCommand.add("--bridge", command.getBridgeName());
scriptCommand.add("--config", command.getVpcConfigInJson());
final String result = scriptCommand.execute();
if (result.equalsIgnoreCase("SUCCESS")) {
return new Answer(command, true, result);
} else {
return new Answer(command, false, result);
}
} catch (final Exception e) {
s_logger.warn("caught exception while updating host with latest routing polcies", e);
return new Answer(command, false, e.getMessage());
}
}
}

View File

@ -0,0 +1,53 @@
//
// 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.OvsVpcRoutingPolicyConfigCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.script.Script;
public final class LibvirtOvsVpcRoutingPolicyConfigCommandWrapper extends CommandWrapper<OvsVpcRoutingPolicyConfigCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.class);
@Override
public Answer execute(final OvsVpcRoutingPolicyConfigCommand command, final LibvirtComputingResource libvirtComputingResource) {
try {
final Script scriptCommand = new Script(libvirtComputingResource.getOvsTunnelPath(), libvirtComputingResource.getTimeout(), s_logger);
scriptCommand.add("configure_ovs_bridge_for_routing_policies");
scriptCommand.add("--bridge", command.getBridgeName());
scriptCommand.add("--config", command.getVpcConfigInJson());
final String result = scriptCommand.execute();
if (result.equalsIgnoreCase("SUCCESS")) {
return new Answer(command, true, result);
} else {
return new Answer(command, false, result);
}
} catch (final Exception e) {
s_logger.warn("caught exception while updating host with latest VPC topology", e);
return new Answer(command, false, e.getMessage());
}
}
}

View File

@ -0,0 +1,65 @@
//
// 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.PingTestCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.script.Script;
public final class LibvirtPingTestCommandWrapper extends CommandWrapper<PingTestCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtPingTestCommandWrapper.class);
@Override
public Answer execute(final PingTestCommand command, final LibvirtComputingResource libvirtComputingResource) {
String result = null;
final String computingHostIp = command.getComputingHostIp(); // TODO, split the command into 2 types
if (computingHostIp != null) {
result = doPingTest(libvirtComputingResource, computingHostIp);
} else if (command.getRouterIp() != null && command.getPrivateIp() != null) {
result = doPingTest(libvirtComputingResource, command.getRouterIp(), command.getPrivateIp());
} else {
return new Answer(command, false, "routerip and private ip is null");
}
if (result != null) {
return new Answer(command, false, result);
}
return new Answer(command);
}
protected String doPingTest(final LibvirtComputingResource libvirtComputingResource, final String computingHostIp) {
final Script command = new Script(libvirtComputingResource.getPingTestPath(), 10000, s_logger);
command.add("-h", computingHostIp);
return command.execute();
}
protected String doPingTest(final LibvirtComputingResource libvirtComputingResource, final String domRIp, final String vmIp) {
final Script command = new Script(libvirtComputingResource.getPingTestPath(), 10000, s_logger);
command.add("-i", domRIp);
command.add("-p", vmIp);
return command.execute();
}
}

View File

@ -0,0 +1,85 @@
//
// 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 org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.PlugNicAnswer;
import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.VifDriver;
import com.cloud.resource.CommandWrapper;
public final class LibvirtPlugNicCommandWrapper extends CommandWrapper<PlugNicCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtPlugNicCommandWrapper.class);
@Override
public Answer execute(final PlugNicCommand command, final LibvirtComputingResource libvirtComputingResource) {
final NicTO nic = command.getNic();
final String vmName = command.getVmName();
Domain vm = null;
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
vm = libvirtComputingResource.getDomain(conn, vmName);
final List<InterfaceDef> pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName);
Integer nicnum = 0;
for (final InterfaceDef pluggedNic : pluggedNics) {
if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
s_logger.debug("found existing nic for mac " + pluggedNic.getMacAddress() + " at index " + nicnum);
return new PlugNicAnswer(command, true, "success");
}
nicnum++;
}
VifDriver vifDriver = libvirtComputingResource.getVifDriver(nic.getType());
InterfaceDef interfaceDef = vifDriver.plug(nic, "Other PV", "");
vm.attachDevice(interfaceDef.toString());
return new PlugNicAnswer(command, true, "success");
} catch (final LibvirtException e) {
final String msg = " Plug Nic failed due to " + e.toString();
s_logger.warn(msg, e);
return new PlugNicAnswer(command, false, msg);
} catch (final InternalErrorException e) {
final String msg = " Plug Nic failed due to " + e.toString();
s_logger.warn(msg, e);
return new PlugNicAnswer(command, false, msg);
} finally {
if (vm != null) {
try {
vm.free();
} catch (final LibvirtException l) {
s_logger.trace("Ignoring libvirt error.", l);
}
}
}
}
}

View File

@ -0,0 +1,91 @@
//
// 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.net.URISyntaxException;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.Volume;
public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapper<PrepareForMigrationCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtPrepareForMigrationCommandWrapper.class);
@Override
public Answer execute(final PrepareForMigrationCommand command, final LibvirtComputingResource libvirtComputingResource) {
final VirtualMachineTO vm = command.getVirtualMachine();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Preparing host for migrating " + vm);
}
final NicTO[] nics = vm.getNics();
boolean skipDisconnect = false;
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vm.getName());
for (final NicTO nic : nics) {
libvirtComputingResource.getVifDriver(nic.getType()).plug(nic, null, "");
}
/* setup disks, e.g for iso */
final DiskTO[] volumes = vm.getDisks();
for (final DiskTO volume : volumes) {
if (volume.getType() == Volume.Type.ISO) {
libvirtComputingResource.getVolumePath(conn, volume);
}
}
skipDisconnect = true;
if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vm)) {
return new PrepareForMigrationAnswer(command, "failed to connect physical disks to host");
}
return new PrepareForMigrationAnswer(command);
} catch (final LibvirtException e) {
return new PrepareForMigrationAnswer(command, e.toString());
} catch (final InternalErrorException e) {
return new PrepareForMigrationAnswer(command, e.toString());
} catch (final URISyntaxException e) {
return new PrepareForMigrationAnswer(command, e.toString());
} finally {
if (!skipDisconnect) {
storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vm);
}
}
}
}

View File

@ -0,0 +1,88 @@
//
// 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.UUID;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.exception.CloudRuntimeException;
public final class LibvirtPrimaryStorageDownloadCommandWrapper extends CommandWrapper<PrimaryStorageDownloadCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final PrimaryStorageDownloadCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String tmplturl = command.getUrl();
final int index = tmplturl.lastIndexOf("/");
final String mountpoint = tmplturl.substring(0, index);
String tmpltname = null;
if (index < tmplturl.length() - 1) {
tmpltname = tmplturl.substring(index + 1);
}
KVMPhysicalDisk tmplVol = null;
KVMStoragePool secondaryPool = null;
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
try {
secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint);
/* Get template vol */
if (tmpltname == null) {
secondaryPool.refresh();
final List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
if (disks == null || disks.isEmpty()) {
return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + secondaryPool.getUuid());
}
for (final KVMPhysicalDisk disk : disks) {
if (disk.getName().endsWith("qcow2")) {
tmplVol = disk;
break;
}
}
if (tmplVol == null) {
return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
}
} else {
tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
}
/* Copy volume to primary storage */
final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid());
final KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0);
return new PrimaryStorageDownloadAnswer(primaryVol.getName(), primaryVol.getSize());
} catch (final CloudRuntimeException e) {
return new PrimaryStorageDownloadAnswer(e.toString());
} finally {
if (secondaryPool != null) {
storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid());
}
}
}
}

View File

@ -0,0 +1,105 @@
//
// 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 org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.script.Script;
public final class LibvirtPvlanSetupCommandWrapper extends CommandWrapper<PvlanSetupCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtPvlanSetupCommandWrapper.class);
@Override
public Answer execute(final PvlanSetupCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String primaryPvlan = command.getPrimary();
final String isolatedPvlan = command.getIsolated();
final String op = command.getOp();
final String dhcpName = command.getDhcpName();
final String dhcpMac = command.getDhcpMac();
final String dhcpIp = command.getDhcpIp();
final String vmMac = command.getVmMac();
boolean add = true;
String opr = "-A";
if (op.equals("delete")) {
opr = "-D";
add = false;
}
String result = null;
try {
final String guestBridgeName = libvirtComputingResource.getGuestBridgeName();
final int timeout = libvirtComputingResource.getTimeout();
if (command.getType() == PvlanSetupCommand.Type.DHCP) {
final String ovsPvlanDhcpHostPath = libvirtComputingResource.getOvsPvlanDhcpHostPath();
final Script script = new Script(ovsPvlanDhcpHostPath, timeout, s_logger);
if (add) {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(dhcpName);
final List<InterfaceDef> ifaces = libvirtComputingResource.getInterfaces(conn, dhcpName);
final InterfaceDef guestNic = ifaces.get(0);
script.add(opr, "-b", guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName, "-d", dhcpIp, "-m", dhcpMac, "-I",
guestNic.getDevName());
} else {
script.add(opr, "-b", guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName, "-d", dhcpIp, "-m", dhcpMac);
}
result = script.execute();
if (result != null) {
s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac);
return new Answer(command, false, result);
} else {
s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac);
}
} else if (command.getType() == PvlanSetupCommand.Type.VM) {
final String ovsPvlanVmPath = libvirtComputingResource.getOvsPvlanVmPath();
final Script script = new Script(ovsPvlanVmPath, timeout, s_logger);
script.add(opr, "-b", guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-v", vmMac);
result = script.execute();
if (result != null) {
s_logger.warn("Failed to program pvlan for vm with mac " + vmMac);
return new Answer(command, false, result);
} else {
s_logger.info("Programmed pvlan for vm with mac " + vmMac);
}
}
} catch (final LibvirtException e) {
s_logger.error("Error whislt executing OVS Setup command! ==> " + e.getMessage());
return new Answer(command, false, e.getMessage());
}
return new Answer(command, true, result);
}
}

View File

@ -0,0 +1,34 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtReadyCommandWrapper extends CommandWrapper<ReadyCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final ReadyCommand command, final LibvirtComputingResource libvirtComputingResource) {
return new ReadyAnswer(command);
}
}

View File

@ -0,0 +1,59 @@
//
// 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 org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtRebootCommandWrapper extends CommandWrapper<RebootCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtRebootCommandWrapper.class);
@Override
public Answer execute(final RebootCommand command, final LibvirtComputingResource libvirtComputingResource) {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
try {
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName());
final String result = libvirtComputingResource.rebootVM(conn, command.getVmName());
if (result == null) {
Integer vncPort = null;
try {
vncPort = libvirtComputingResource.getVncPort(conn, command.getVmName());
} catch (final LibvirtException e) {
s_logger.trace("Ignoring libvirt error.", e);
}
libvirtComputingResource.getRuleLogsForVms();
return new RebootAnswer(command, null, vncPort);
} else {
return new RebootAnswer(command, result, false);
}
} catch (final LibvirtException e) {
return new RebootAnswer(command, e.getMessage(), false);
}
}
}

View File

@ -0,0 +1,47 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.RebootRouterCommand;
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtRebootRouterCommandWrapper extends CommandWrapper<RebootRouterCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final RebootRouterCommand command, final LibvirtComputingResource libvirtComputingResource) {
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
final RebootCommand rebootCommand = new RebootCommand(command.getVmName());
final Answer answer = wrapper.execute(rebootCommand, libvirtComputingResource);
final VirtualRoutingResource virtualRouterResource = libvirtComputingResource.getVirtRouterResource();
if (virtualRouterResource.connect(command.getPrivateIpAddress())) {
libvirtComputingResource.networkUsage(command.getPrivateIpAddress(), "create", null);
return answer;
} else {
return new Answer(command, false, "Failed to connect to virtual router " + command.getVmName());
}
}
}

View File

@ -0,0 +1,184 @@
//
// 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.Hashtable;
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.agent.api.BackupSnapshotCommand;
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;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.FenceCommand;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.agent.api.GetVmDiskStatsCommand;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.api.MigrateCommand;
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.NetworkUsageCommand;
import com.cloud.agent.api.OvsCreateTunnelCommand;
import com.cloud.agent.api.OvsDestroyBridgeCommand;
import com.cloud.agent.api.OvsDestroyTunnelCommand;
import com.cloud.agent.api.OvsFetchInterfaceCommand;
import com.cloud.agent.api.OvsSetupBridgeCommand;
import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
import com.cloud.agent.api.PingTestCommand;
import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.RebootRouterCommand;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.UnPlugNicCommand;
import com.cloud.agent.api.UpgradeSnapshotCommand;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.storage.ResizeVolumeCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.RequestWrapper;
import com.cloud.resource.ServerResource;
public class LibvirtRequestWrapper extends RequestWrapper {
private static LibvirtRequestWrapper instance;
static {
instance = new LibvirtRequestWrapper();
}
private LibvirtRequestWrapper() {
init();
}
@SuppressWarnings("rawtypes")
private void init() {
// LibvirtComputingResource commands
final Hashtable<Class<? extends Command>, CommandWrapper> linbvirtCommands = new Hashtable<Class<? extends Command>, CommandWrapper>();
linbvirtCommands.put(StopCommand.class, new LibvirtStopCommandWrapper());
linbvirtCommands.put(GetVmStatsCommand.class, new LibvirtGetVmStatsCommandWrapper());
linbvirtCommands.put(GetVmDiskStatsCommand.class, new LibvirtGetVmDiskStatsCommandWrapper());
linbvirtCommands.put(RebootRouterCommand.class, new LibvirtRebootRouterCommandWrapper());
linbvirtCommands.put(RebootCommand.class, new LibvirtRebootCommandWrapper());
linbvirtCommands.put(GetHostStatsCommand.class, new LibvirtGetHostStatsCommandWrapper());
linbvirtCommands.put(CheckHealthCommand.class, new LibvirtCheckHealthCommandWrapper());
linbvirtCommands.put(PrepareForMigrationCommand.class, new LibvirtPrepareForMigrationCommandWrapper());
linbvirtCommands.put(MigrateCommand.class, new LibvirtMigrateCommandWrapper());
linbvirtCommands.put(PingTestCommand.class, new LibvirtPingTestCommandWrapper());
linbvirtCommands.put(CheckVirtualMachineCommand.class, new LibvirtCheckVirtualMachineCommandWrapper());
linbvirtCommands.put(ReadyCommand.class, new LibvirtReadyCommandWrapper());
linbvirtCommands.put(AttachIsoCommand.class, new LibvirtAttachIsoCommandWrapper());
linbvirtCommands.put(AttachVolumeCommand.class, new LibvirtAttachVolumeCommandWrapper());
linbvirtCommands.put(WatchConsoleProxyLoadCommand.class, new LibvirtWatchConsoleProxyLoadCommandWrapper());
linbvirtCommands.put(CheckConsoleProxyLoadCommand.class, new LibvirtCheckConsoleProxyLoadCommandWrapper());
linbvirtCommands.put(GetVncPortCommand.class, new LibvirtGetVncPortCommandWrapper());
linbvirtCommands.put(ModifySshKeysCommand.class, new LibvirtModifySshKeysCommandWrapper());
linbvirtCommands.put(MaintainCommand.class, new LibvirtMaintainCommandWrapper());
linbvirtCommands.put(CreateCommand.class, new LibvirtCreateCommandWrapper());
linbvirtCommands.put(DestroyCommand.class, new LibvirtDestroyCommandWrapper());
linbvirtCommands.put(PrimaryStorageDownloadCommand.class, new LibvirtPrimaryStorageDownloadCommandWrapper());
linbvirtCommands.put(GetStorageStatsCommand.class, new LibvirtGetStorageStatsCommandWrapper());
linbvirtCommands.put(UpgradeSnapshotCommand.class, new LibvirtUpgradeSnapshotCommandWrapper());
linbvirtCommands.put(DeleteStoragePoolCommand.class, new LibvirtDeleteStoragePoolCommandWrapper());
linbvirtCommands.put(OvsSetupBridgeCommand.class, new LibvirtOvsSetupBridgeCommandWrapper());
linbvirtCommands.put(OvsDestroyBridgeCommand.class, new LibvirtOvsDestroyBridgeCommandWrapper());
linbvirtCommands.put(OvsFetchInterfaceCommand.class, new LibvirtOvsFetchInterfaceCommandWrapper());
linbvirtCommands.put(OvsVpcPhysicalTopologyConfigCommand.class, new LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper());
linbvirtCommands.put(OvsVpcRoutingPolicyConfigCommand.class, new LibvirtOvsVpcRoutingPolicyConfigCommandWrapper());
linbvirtCommands.put(CreateStoragePoolCommand.class, new LibvirtCreateStoragePoolCommandWrapper());
linbvirtCommands.put(ModifyStoragePoolCommand.class, new LibvirtModifyStoragePoolCommandWrapper());
linbvirtCommands.put(CleanupNetworkRulesCmd.class, new LibvirtCleanupNetworkRulesCommandWrapper());
linbvirtCommands.put(NetworkRulesVmSecondaryIpCommand.class, new LibvirtNetworkRulesVmSecondaryIpCommandWrapper());
linbvirtCommands.put(NetworkRulesSystemVmCommand.class, new LibvirtNetworkRulesSystemVmCommandWrapper());
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());
linbvirtCommands.put(CreateVolumeFromSnapshotCommand.class, new LibvirtCreateVolumeFromSnapshotCommandWrapper());
linbvirtCommands.put(FenceCommand.class, new LibvirtFenceCommandWrapper());
linbvirtCommands.put(SecurityGroupRulesCmd.class, new LibvirtSecurityGroupRulesCommandWrapper());
linbvirtCommands.put(PlugNicCommand.class, new LibvirtPlugNicCommandWrapper());
linbvirtCommands.put(UnPlugNicCommand.class, new LibvirtUnPlugNicCommandWrapper());
linbvirtCommands.put(NetworkUsageCommand.class, new LibvirtNetworkUsageCommandWrapper());
linbvirtCommands.put(CreatePrivateTemplateFromVolumeCommand.class, new LibvirtCreatePrivateTemplateFromVolumeCommandWrapper());
linbvirtCommands.put(ManageSnapshotCommand.class, new LibvirtManageSnapshotCommandWrapper());
linbvirtCommands.put(BackupSnapshotCommand.class, new LibvirtBackupSnapshotCommandWrapper());
linbvirtCommands.put(CreatePrivateTemplateFromSnapshotCommand.class, new LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper());
linbvirtCommands.put(CopyVolumeCommand.class, new LibvirtCopyVolumeCommandWrapper());
linbvirtCommands.put(PvlanSetupCommand.class, new LibvirtPvlanSetupCommandWrapper());
linbvirtCommands.put(ResizeVolumeCommand.class, new LibvirtResizeVolumeCommandWrapper());
linbvirtCommands.put(NetworkElementCommand.class, new LibvirtNetworkElementCommandWrapper());
linbvirtCommands.put(StorageSubSystemCommand.class, new LibvirtStorageSubSystemCommandWrapper());
linbvirtCommands.put(StartCommand.class, new LibvirtStartCommandWrapper());
resources.put(LibvirtComputingResource.class, linbvirtCommands);
}
public static LibvirtRequestWrapper getInstance() {
return instance;
}
@SuppressWarnings({"rawtypes" })
@Override
public Answer execute(final Command command, final ServerResource serverResource) {
final Class<? extends ServerResource> resourceClass = serverResource.getClass();
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands = retrieveResource(command, resourceClass);
CommandWrapper<Command, Answer, ServerResource> commandWrapper = retrieveCommands(command.getClass(), resourceCommands);
while (commandWrapper == null) {
//Could not find the command in the given resource, will traverse the family tree.
commandWrapper = retryWhenAllFails(command, resourceClass, resourceCommands);
}
return commandWrapper.execute(command, serverResource);
}
}

View File

@ -0,0 +1,136 @@
//
// 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.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import org.libvirt.StorageVol;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.ResizeVolumeAnswer;
import com.cloud.agent.api.storage.ResizeVolumeCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
/*
* Uses a local script now, eventually support for virStorageVolResize() will maybe work on qcow2 and lvm and we can do this in libvirt calls
*/
public final class LibvirtResizeVolumeCommandWrapper extends CommandWrapper<ResizeVolumeCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtResizeVolumeCommandWrapper.class);
@Override
public Answer execute(final ResizeVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String volid = command.getPath();
final long newSize = command.getNewSize();
final long currentSize = command.getCurrentSize();
final String vmInstanceName = command.getInstanceName();
final boolean shrinkOk = command.getShrinkOk();
final StorageFilerTO spool = command.getPool();
final String notifyOnlyType = "NOTIFYONLY";
if ( currentSize == newSize) {
// nothing to do
s_logger.info("No need to resize volume: current size " + currentSize + " is same as new size " + newSize);
return new ResizeVolumeAnswer(command, true, "success", currentSize);
}
try {
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
KVMStoragePool pool = storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid());
final KVMPhysicalDisk vol = pool.getPhysicalDisk(volid);
final String path = vol.getPath();
String type = libvirtComputingResource.getResizeScriptType(pool, vol);
if (pool.getType() != StoragePoolType.RBD) {
if (type.equals("QCOW2") && shrinkOk) {
return new ResizeVolumeAnswer(command, false, "Unable to shrink volumes of type " + type);
}
} else {
s_logger.debug("Volume " + path + " is on a RBD storage pool. No need to query for additional information.");
}
s_logger.debug("Resizing volume: " + path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk);
/* libvirt doesn't support resizing (C)LVM devices, and corrupts QCOW2 in some scenarios, so we have to do these via Bash script */
if (pool.getType() != StoragePoolType.CLVM && vol.getFormat() != PhysicalDiskFormat.QCOW2) {
s_logger.debug("Volume " + path + " can be resized by libvirt. Asking libvirt to resize the volume.");
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnection();
final StorageVol v = conn.storageVolLookupByPath(path);
int flags = 0;
if (conn.getLibVirVersion() > 1001000 && vol.getFormat() == PhysicalDiskFormat.RAW && pool.getType() != StoragePoolType.RBD) {
flags = 1;
}
if (shrinkOk) {
flags = 4;
}
v.resize(newSize, flags);
type = notifyOnlyType;
} catch (final LibvirtException e) {
return new ResizeVolumeAnswer(command, false, e.toString());
}
}
s_logger.debug("Invoking resize script to handle type " + type);
final Script resizecmd = new Script(libvirtComputingResource.getResizeVolumePath(), libvirtComputingResource.getCmdsTimeout(), s_logger);
resizecmd.add("-s", String.valueOf(newSize));
resizecmd.add("-c", String.valueOf(currentSize));
resizecmd.add("-p", path);
resizecmd.add("-t", type);
resizecmd.add("-r", String.valueOf(shrinkOk));
resizecmd.add("-v", vmInstanceName);
final String result = resizecmd.execute();
if (result != null) {
if(type.equals(notifyOnlyType)) {
return new ResizeVolumeAnswer(command, true, "Resize succeeded, but need reboot to notify guest");
} else {
return new ResizeVolumeAnswer(command, false, result);
}
}
/* fetch new size as seen from libvirt, don't want to assume anything */
pool = storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid());
pool.refresh();
final long finalSize = pool.getPhysicalDisk(volid).getVirtualSize();
s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize);
return new ResizeVolumeAnswer(command, true, "success", finalSize);
} catch (final CloudRuntimeException e) {
final String error = "Failed to resize volume: " + e.getMessage();
s_logger.debug(error);
return new ResizeVolumeAnswer(command, false, error);
}
}
}

View File

@ -0,0 +1,67 @@
//
// 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 org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.SecurityGroupRuleAnswer;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.resource.CommandWrapper;
public final class LibvirtSecurityGroupRulesCommandWrapper extends CommandWrapper<SecurityGroupRulesCmd, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtSecurityGroupRulesCommandWrapper.class);
@Override
public Answer execute(final SecurityGroupRulesCmd command, final LibvirtComputingResource libvirtComputingResource) {
String vif = null;
String brname = null;
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName());
final List<InterfaceDef> nics = libvirtComputingResource.getInterfaces(conn, command.getVmName());
vif = nics.get(0).getDevName();
brname = nics.get(0).getBrName();
} catch (final LibvirtException e) {
return new SecurityGroupRuleAnswer(command, false, e.toString());
}
final boolean result = libvirtComputingResource.addNetworkRules(command.getVmName(), Long.toString(command.getVmId()), command.getGuestIp(), command.getSignature(),
Long.toString(command.getSeqNum()), command.getGuestMac(), command.stringifyRules(), vif, brname, command.getSecIpsString());
if (!result) {
s_logger.warn("Failed to program network rules for vm " + command.getVmName());
return new SecurityGroupRuleAnswer(command, false, "programming network rules failed");
} else {
s_logger.debug("Programmed network rules for vm " + command.getVmName() + " guestIp=" + command.getGuestIp() + ",ingress numrules="
+ command.getIngressRuleSet().length + ",egress numrules=" + command.getEgressRuleSet().length);
return new SecurityGroupRuleAnswer(command);
}
}
}

View File

@ -0,0 +1,151 @@
//
// 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.net.URISyntaxException;
import java.util.List;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.DomainInfo.DomainState;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.network.Networks.IsolationType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.resource.CommandWrapper;
import com.cloud.vm.VirtualMachine;
public final class LibvirtStartCommandWrapper extends CommandWrapper<StartCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtStartCommandWrapper.class);
@Override
public Answer execute(final StartCommand command, final LibvirtComputingResource libvirtComputingResource) {
final VirtualMachineTO vmSpec = command.getVirtualMachine();
vmSpec.setVncAddr(command.getHostIp());
final String vmName = vmSpec.getName();
LibvirtVMDef vm = null;
DomainState state = DomainState.VIR_DOMAIN_SHUTOFF;
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
Connect conn = null;
try {
final NicTO[] nics = vmSpec.getNics();
for (final NicTO nic : nics) {
if (vmSpec.getType() != VirtualMachine.Type.User) {
nic.setPxeDisable(true);
}
}
vm = libvirtComputingResource.createVMFromSpec(vmSpec);
conn = libvirtUtilitiesHelper.getConnectionByType(vm.getHvsType());
libvirtComputingResource.createVbd(conn, vmSpec, vmName, vm);
if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)) {
return new StartAnswer(command, "Failed to connect physical disks to host");
}
libvirtComputingResource.createVifs(vmSpec, vm);
s_logger.debug("starting " + vmName + ": " + vm.toString());
libvirtComputingResource.startVM(conn, vmName, vm.toString());
for (final NicTO nic : nics) {
if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) {
if (vmSpec.getType() != VirtualMachine.Type.User) {
libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, vmName);
break;
} else {
final List<String> nicSecIps = nic.getNicSecIps();
String secIpsStr;
final StringBuilder sb = new StringBuilder();
if (nicSecIps != null) {
for (final String ip : nicSecIps) {
sb.append(ip).append(":");
}
secIpsStr = sb.toString();
} else {
secIpsStr = "0:";
}
libvirtComputingResource.defaultNetworkRules(conn, vmName, nic, vmSpec.getId(), secIpsStr);
}
}
}
// pass cmdline info to system vms
if (vmSpec.getType() != VirtualMachine.Type.User) {
//wait and try passCmdLine for 5 minutes at most for CLOUDSTACK-2823
String controlIp = null;
for (final NicTO nic : nics) {
if (nic.getType() == TrafficType.Control) {
controlIp = nic.getIp();
break;
}
}
for (int count = 0; count < 30; count++) {
libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs());
//check router is up?
final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource();
final boolean result = virtRouterResource.connect(controlIp, 1, 5000);
if (result) {
break;
}
}
}
state = DomainState.VIR_DOMAIN_RUNNING;
return new StartAnswer(command);
} catch (final LibvirtException e) {
s_logger.warn("LibvirtException ", e);
if (conn != null) {
libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
}
return new StartAnswer(command, e.getMessage());
} catch (final InternalErrorException e) {
s_logger.warn("InternalErrorException ", e);
if (conn != null) {
libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
}
return new StartAnswer(command, e.getMessage());
} catch (final URISyntaxException e) {
s_logger.warn("URISyntaxException ", e);
if (conn != null) {
libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
}
return new StartAnswer(command, e.getMessage());
} finally {
if (state != DomainState.VIR_DOMAIN_RUNNING) {
storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vmSpec);
}
}
}
}

View File

@ -0,0 +1,87 @@
//
// 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 org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.DomainInfo.DomainState;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.VifDriver;
import com.cloud.resource.CommandWrapper;
public final class LibvirtStopCommandWrapper extends CommandWrapper<StopCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtStopCommandWrapper.class);
@Override
public Answer execute(final StopCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String vmName = command.getVmName();
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
if (command.checkBeforeCleanup()) {
try {
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
final Domain vm = conn.domainLookupByName(command.getVmName());
if (vm != null && vm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING) {
return new StopAnswer(command, "vm is still running on host", false);
}
} catch (final Exception e) {
s_logger.debug("Failed to get vm status in case of checkboforecleanup is true", e);
}
}
try {
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
final List<DiskDef> disks = libvirtComputingResource.getDisks(conn, vmName);
final List<InterfaceDef> ifaces = libvirtComputingResource.getInterfaces(conn, vmName);
libvirtComputingResource.destroyNetworkRulesForVM(conn, vmName);
final String result = libvirtComputingResource.stopVM(conn, vmName);
if (result == null) {
for (final DiskDef disk : disks) {
libvirtComputingResource.cleanupDisk(disk);
}
for (final InterfaceDef iface : ifaces) {
// We don't know which "traffic type" is associated with
// each interface at this point, so inform all vif drivers
for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) {
vifDriver.unplug(iface);
}
}
}
return new StopAnswer(command, result, true);
} catch (final LibvirtException e) {
return new StopAnswer(command, e.getMessage(), false);
}
}
}

View File

@ -0,0 +1,36 @@
//
// 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.cloudstack.storage.command.StorageSubSystemCommand;
import com.cloud.agent.api.Answer;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.resource.StorageSubsystemCommandHandler;
public final class LibvirtStorageSubSystemCommandWrapper extends CommandWrapper<StorageSubSystemCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final StorageSubSystemCommand command, final LibvirtComputingResource libvirtComputingResource) {
final StorageSubsystemCommandHandler handler = libvirtComputingResource.getStorageHandler();
return handler.handleStorageCommands(command);
}
}

View File

@ -0,0 +1,80 @@
//
// 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 org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.UnPlugNicAnswer;
import com.cloud.agent.api.UnPlugNicCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.VifDriver;
import com.cloud.resource.CommandWrapper;
public final class LibvirtUnPlugNicCommandWrapper extends CommandWrapper<UnPlugNicCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtUnPlugNicCommandWrapper.class);
@Override
public Answer execute(final UnPlugNicCommand command, final LibvirtComputingResource libvirtComputingResource) {
final NicTO nic = command.getNic();
final String vmName = command.getVmName();
Domain vm = null;
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
vm = libvirtComputingResource.getDomain(conn, vmName);
final List<InterfaceDef> pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName);
for (final InterfaceDef pluggedNic : pluggedNics) {
if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
vm.detachDevice(pluggedNic.toString());
// We don't know which "traffic type" is associated with
// each interface at this point, so inform all vif drivers
for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) {
vifDriver.unplug(pluggedNic);
}
return new UnPlugNicAnswer(command, true, "success");
}
}
return new UnPlugNicAnswer(command, true, "success");
} catch (final LibvirtException e) {
final String msg = " Unplug Nic failed due to " + e.toString();
s_logger.warn(msg, e);
return new UnPlugNicAnswer(command, false, msg);
} finally {
if (vm != null) {
try {
vm.free();
} catch (final LibvirtException l) {
s_logger.trace("Ignoring libvirt error.", l);
}
}
}
}
}

View File

@ -0,0 +1,33 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.UpgradeSnapshotCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtUpgradeSnapshotCommandWrapper extends CommandWrapper<UpgradeSnapshotCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final UpgradeSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) {
return new Answer(command, true, "success");
}
}

View File

@ -0,0 +1,85 @@
// 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.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.naming.ConfigurationException;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.template.Processor;
import com.cloud.storage.template.QCOW2Processor;
import com.cloud.storage.template.TemplateLocation;
/**
* This class is used to wrap the calls to several static methods. By doing so, we make easier to mock this class
* and the methods wrapped here.
*
* Please do not instantiate this class directly, but inject it using the {@code @Inject} annotation.
*/
public class LibvirtUtilitiesHelper {
public Connect getConnectionByVmName(final String vmName) throws LibvirtException {
return LibvirtConnection.getConnectionByVmName(vmName);
}
public Connect getConnection() throws LibvirtException {
return LibvirtConnection.getConnection();
}
public TemplateLocation buildTemplateLocation(final StorageLayer storage, final String templatePath) {
final TemplateLocation location = new TemplateLocation(storage, templatePath);
return location;
}
public Processor buildQCOW2Processor(final StorageLayer storage) throws ConfigurationException {
final Map<String, Object> params = new HashMap<String, Object>();
params.put(StorageLayer.InstanceConfigKey, storage);
final Processor qcow2Processor = new QCOW2Processor();
qcow2Processor.configure("QCOW2 Processor", params);
return qcow2Processor;
}
public String generatereUUIDName() {
return UUID.randomUUID().toString();
}
public Connect getConnectionByType(final String hvsType) throws LibvirtException {
return LibvirtConnection.getConnectionByType(hvsType);
}
public String retrieveSshKeysPath() {
return LibvirtComputingResource.SSHKEYSPATH;
}
public String retrieveSshPubKeyPath() {
return LibvirtComputingResource.SSHPUBKEYPATH;
}
public String retrieveSshPrvKeyPath() {
return LibvirtComputingResource.SSHPRVKEYPATH;
}
}

View File

@ -0,0 +1,41 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.ServerResource;
public class LibvirtWatchConsoleProxyLoadCommandWrapper extends LibvirtConsoleProxyLoadCommandWrapper<WatchConsoleProxyLoadCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final Command command, final ServerResource serverResource) {
final WatchConsoleProxyLoadCommand cmd = (WatchConsoleProxyLoadCommand) command;
final long proxyVmId = cmd.getProxyVmId();
final String proxyVmName = cmd.getProxyVmName();
final String proxyManagementIp = cmd.getProxyManagementIp();
final int proxyCmdPort = cmd.getProxyCmdPort();
return executeProxyLoadScan(cmd, proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort);
}
}

View File

@ -20,18 +20,21 @@
package com.cloud.hypervisor.xenserver.resource.wrapper;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ServerResource;
public final class CitrixCheckConsoleProxyLoadCommandWrapper extends CommandWrapper<CheckConsoleProxyLoadCommand, Answer, CitrixResourceBase> {
public final class CitrixCheckConsoleProxyLoadCommandWrapper extends CitrixConsoleProxyLoadCommandWrapper<CheckConsoleProxyLoadCommand, Answer, CitrixResourceBase> {
@Override
public Answer execute(final CheckConsoleProxyLoadCommand command, final CitrixResourceBase citrixResourceBase) {
final long proxyVmId = command.getProxyVmId();
final String proxyVmName = command.getProxyVmName();
final String proxyManagementIp = command.getProxyManagementIp();
final int cmdPort = command.getProxyCmdPort();
public Answer execute(final Command command, final ServerResource serverResource) {
final CheckConsoleProxyLoadCommand cmd = (CheckConsoleProxyLoadCommand) command;
final long proxyVmId = cmd.getProxyVmId();
final String proxyVmName = cmd.getProxyVmName();
final String proxyManagementIp = cmd.getProxyManagementIp();
final int cmdPort = cmd.getProxyCmdPort();
return executeProxyLoadScan(command, proxyVmId, proxyVmName, proxyManagementIp, cmdPort);
}

View File

@ -0,0 +1,83 @@
//
// 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.xenserver.resource.wrapper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ServerResource;
public abstract class CitrixConsoleProxyLoadCommandWrapper<T extends Command, A extends Answer, R extends ServerResource> extends CommandWrapper<Command, Answer, ServerResource> {
private static final Logger s_logger = Logger.getLogger(CitrixConsoleProxyLoadCommandWrapper.class);
protected Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) {
String result = null;
final StringBuffer sb = new StringBuffer();
sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus");
boolean success = true;
try {
final URL url = new URL(sb.toString());
final URLConnection conn = url.openConnection();
// setting TIMEOUTs to avoid possible waiting until death situations
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
final InputStream is = conn.getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.defaultCharset()));
final StringBuilder sb2 = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb2.append(line + "\n");
}
result = sb2.toString();
} catch (final IOException e) {
success = false;
} finally {
try {
is.close();
} catch (final IOException e) {
s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp);
success = false;
}
}
} catch (final IOException e) {
s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp);
success = false;
}
return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result);
}
}

View File

@ -107,12 +107,7 @@ public class CitrixRequestWrapper extends RequestWrapper {
instance = new CitrixRequestWrapper();
}
@SuppressWarnings("rawtypes")
private final Hashtable<Class<? extends ServerResource>, Hashtable<Class<? extends Command>, CommandWrapper>> resources;
@SuppressWarnings("rawtypes")
private CitrixRequestWrapper() {
resources = new Hashtable<Class<? extends ServerResource>, Hashtable<Class<? extends Command>, CommandWrapper>>();
init();
}
@ -232,73 +227,4 @@ public class CitrixRequestWrapper extends RequestWrapper {
return commandWrapper.execute(command, serverResource);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Hashtable<Class<? extends Command>, CommandWrapper> retrieveResource(final Command command, final Class<? extends ServerResource> resourceClass) {
Class<? extends ServerResource> keepResourceClass = resourceClass;
Hashtable<Class<? extends Command>, CommandWrapper> resource = resources.get(keepResourceClass);
while (resource == null) {
try {
final Class<? extends ServerResource> keepResourceClass2 = (Class<? extends ServerResource>) keepResourceClass.getSuperclass();
resource = resources.get(keepResourceClass2);
keepResourceClass = keepResourceClass2;
} catch (final ClassCastException e) {
throw new NullPointerException("No key found for '" + command.getClass() + "' in the Map!");
}
}
return resource;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected CommandWrapper<Command, Answer, ServerResource> retrieveCommands(final Class<? extends Command> commandClass,
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands) {
Class<? extends Command> keepCommandClass = commandClass;
CommandWrapper<Command, Answer, ServerResource> commandWrapper = resourceCommands.get(keepCommandClass);
while (commandWrapper == null) {
try {
final Class<? extends Command> commandClass2 = (Class<? extends Command>) keepCommandClass.getSuperclass();
if (commandClass2 == null) {
throw new NullPointerException("All the COMMAND hierarchy tree has been visited but no compliant key has been found for '" + commandClass +"'.");
}
commandWrapper = resourceCommands.get(commandClass2);
keepCommandClass = commandClass2;
} catch (final NullPointerException e) {
// Will now traverse all the resource hierarchy. Returning null is not a problem.
// It is all being nicely checked and in case we do not have a resource, an Unsupported answer will be thrown by the base class.
return null;
}
}
return commandWrapper;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected CommandWrapper<Command, Answer, ServerResource> retryWhenAllFails(final Command command, final Class<? extends ServerResource> resourceClass,
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands) {
Class<? extends ServerResource> keepResourceClass = resourceClass;
CommandWrapper<Command, Answer, ServerResource> commandWrapper = resourceCommands.get(command.getClass());
while (commandWrapper == null) {
//Could not find the command in the given resource, will traverse the family tree.
try {
final Class<? extends ServerResource> resourceClass2 = (Class<? extends ServerResource>) keepResourceClass.getSuperclass();
if (resourceClass2 == null) {
throw new NullPointerException("All the SERVER-RESOURCE hierarchy tree has been visited but no compliant key has been found for '" + command.getClass() +"'.");
}
final Hashtable<Class<? extends Command>, CommandWrapper> resourceCommands2 = retrieveResource(command, (Class<? extends ServerResource>) keepResourceClass.getSuperclass());
keepResourceClass = resourceClass2;
commandWrapper = retrieveCommands(command.getClass(), resourceCommands2);
} catch (final NullPointerException e) {
throw e;
}
}
return commandWrapper;
}
}

View File

@ -20,18 +20,21 @@
package com.cloud.hypervisor.xenserver.resource.wrapper;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ServerResource;
public final class CitrixWatchConsoleProxyLoadCommandWrapper extends CommandWrapper<WatchConsoleProxyLoadCommand, Answer, CitrixResourceBase> {
public final class CitrixWatchConsoleProxyLoadCommandWrapper extends CitrixConsoleProxyLoadCommandWrapper<WatchConsoleProxyLoadCommand, Answer, CitrixResourceBase> {
@Override
public Answer execute(final WatchConsoleProxyLoadCommand command, final CitrixResourceBase citrixResourceBase) {
final long proxyVmId = command.getProxyVmId();
final String proxyVmName = command.getProxyVmName();
final String proxyManagementIp = command.getProxyManagementIp();
final int cmdPort = command.getProxyCmdPort();
public Answer execute(final Command command, final ServerResource serverResource) {
final WatchConsoleProxyLoadCommand cmd = (WatchConsoleProxyLoadCommand) command;
final long proxyVmId = cmd.getProxyVmId();
final String proxyVmName = cmd.getProxyVmName();
final String proxyManagementIp = cmd.getProxyManagementIp();
final int cmdPort = cmd.getProxyCmdPort();
return executeProxyLoadScan(command, proxyVmId, proxyVmName, proxyManagementIp, cmdPort);
}

View File

@ -42,7 +42,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.cloud.agent.api.Answer;
@ -136,7 +135,6 @@ import com.xensource.xenapi.Types.BadServerResponse;
import com.xensource.xenapi.Types.XenAPIException;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Connection.class, Host.Record.class })
public class CitrixRequestWrapperTest {
@Mock
@ -279,7 +277,7 @@ public class CitrixRequestWrapperTest {
}
@Test
public void testStopCommandCommand() {
public void testStopCommand() {
final StopCommand stopCommand = new StopCommand("Test", false, false);
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();