blob: d7c2c214f22134466c19613a3b8e3ef458968249 [file] [log] [blame]
// 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.ovm3.resources;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.UUID;
import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
import org.apache.cloudstack.storage.command.AttachAnswer;
import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
import org.apache.cloudstack.storage.command.CreateObjectCommand;
import org.apache.cloudstack.storage.command.DeleteCommand;
import org.apache.cloudstack.storage.command.DettachCommand;
import org.apache.cloudstack.storage.command.ForgetObjectCmd;
import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
import org.apache.cloudstack.storage.command.ResignatureAnswer;
import org.apache.cloudstack.storage.command.ResignatureCommand;
import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
import org.apache.cloudstack.storage.command.SyncVolumePathCommand;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.storage.CopyVolumeAnswer;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.CreateAnswer;
import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.NfsTO;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
import com.cloud.hypervisor.ovm3.objects.Connection;
import com.cloud.hypervisor.ovm3.objects.Linux;
import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
import com.cloud.hypervisor.ovm3.objects.OvmObject;
import com.cloud.hypervisor.ovm3.objects.StoragePlugin;
import com.cloud.hypervisor.ovm3.objects.StoragePlugin.FileProperties;
import com.cloud.hypervisor.ovm3.objects.Xen;
import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3StoragePool;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Volume;
import com.cloud.storage.resource.StorageProcessor;
import com.cloud.vm.DiskProfile;
/**
* Storage related bits
*/
public class Ovm3StorageProcessor implements StorageProcessor {
protected Logger logger = LogManager.getLogger(getClass());
private Connection c;
private OvmObject ovmObject = new OvmObject();
private Ovm3StoragePool pool;
private Ovm3Configuration config;
public Ovm3StorageProcessor(Connection conn, Ovm3Configuration ovm3config,
Ovm3StoragePool ovm3pool) {
c = conn;
config = ovm3config;
pool = ovm3pool;
}
public final Answer execute(final CopyCommand cmd) {
logger.debug("execute: "+ cmd.getClass());
DataTO srcData = cmd.getSrcTO();
DataStoreTO srcStore = srcData.getDataStore();
DataTO destData = cmd.getDestTO();
DataStoreTO destStore = destData.getDataStore();
String msg = "Not implemented yet";
try {
/* target and source are NFS and TEMPLATE */
if ((srcStore instanceof NfsTO)
&& (srcData.getObjectType() == DataObjectType.TEMPLATE)
&& (destData.getObjectType() == DataObjectType.TEMPLATE)) {
return copyTemplateToPrimaryStorage(cmd);
/* we assume the cache for templates is local */
} else if ((srcData.getObjectType() == DataObjectType.TEMPLATE)
&& (destData.getObjectType() == DataObjectType.VOLUME)) {
if (srcStore.getUrl().equals(destStore.getUrl())) {
return cloneVolumeFromBaseTemplate(cmd);
} else {
msg = "Primary to Primary doesn't match";
logger.debug(msg);
}
} else if ((srcData.getObjectType() == DataObjectType.SNAPSHOT)
&& (destData.getObjectType() == DataObjectType.SNAPSHOT)) {
return backupSnapshot(cmd);
} else if ((srcData.getObjectType() == DataObjectType.SNAPSHOT)
&& (destData.getObjectType() == DataObjectType.TEMPLATE)) {
return createTemplateFromSnapshot(cmd);
} else if ((srcData.getObjectType() == DataObjectType.SNAPSHOT)
&& (destData.getObjectType() == DataObjectType.VOLUME)) {
return createVolumeFromSnapshot(cmd);
} else {
msg = "Unable to do stuff for " + srcStore.getClass() + ":"
+ srcData.getObjectType() + " to "
+ destStore.getClass() + ":" + destData.getObjectType();
logger.debug(msg);
}
} catch (Exception e) {
msg = "Catch Exception " + e.getClass().getName()
+ " for template due to " + e.toString();
logger.warn(msg, e);
return new CopyCmdAnswer(msg);
}
logger.warn(msg + " " + cmd.getClass());
return new CopyCmdAnswer(msg);
}
public Answer execute(DeleteCommand cmd) {
DataTO data = cmd.getData();
String msg;
logger.debug("Deleting object: " + data.getObjectType());
if (data.getObjectType() == DataObjectType.VOLUME) {
return deleteVolume(cmd);
} else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
return deleteSnapshot(cmd);
} else if (data.getObjectType() == DataObjectType.TEMPLATE) {
msg = "Template deletion is not implemented yet.";
logger.info(msg);
} else {
msg = data.getObjectType() + " deletion is not implemented yet.";
logger.info(msg);
}
return new Answer(cmd, false, msg);
}
public CreateAnswer execute(CreateCommand cmd) {
logger.debug("execute: "+ cmd.getClass());
StorageFilerTO primaryStorage = cmd.getPool();
DiskProfile disk = cmd.getDiskCharacteristics();
/* disk should have a uuid */
// should also be replaced with getVirtualDiskPath ?
String fileName = UUID.randomUUID().toString() + ".raw";
String dst = primaryStorage.getPath() + "/"
+ primaryStorage.getUuid() + "/" + fileName;
try {
StoragePlugin store = new StoragePlugin(c);
if (cmd.getTemplateUrl() != null) {
logger.debug("CreateCommand " + cmd.getTemplateUrl() + " "
+ dst);
Linux host = new Linux(c);
host.copyFile(cmd.getTemplateUrl(), dst);
} else {
/* this is a dup with the createVolume ? */
logger.debug("CreateCommand " + dst);
store.storagePluginCreate(primaryStorage.getUuid(),
primaryStorage.getHost(), dst, disk.getSize(), false);
}
FileProperties fp = store.storagePluginGetFileInfo(
primaryStorage.getUuid(), primaryStorage.getHost(), dst);
VolumeTO volume = new VolumeTO(cmd.getVolumeId(), disk.getType(),
primaryStorage.getType(), primaryStorage.getUuid(),
primaryStorage.getPath(), fileName, fp.getName(),
fp.getSize(), null);
return new CreateAnswer(cmd, volume);
} catch (Exception e) {
logger.debug("CreateCommand failed", e);
return new CreateAnswer(cmd, e.getMessage());
}
}
/**
* src is Nfs and Template from secondary storage to primary
*/
@Override
public CopyCmdAnswer copyTemplateToPrimaryStorage(CopyCommand cmd) {
logger.debug("execute copyTemplateToPrimaryStorage: "+ cmd.getClass());
DataTO srcData = cmd.getSrcTO();
DataStoreTO srcStore = srcData.getDataStore();
DataTO destData = cmd.getDestTO();
NfsTO srcImageStore = (NfsTO) srcStore;
TemplateObjectTO destTemplate = (TemplateObjectTO) destData;
try {
String secPoolUuid = pool.setupSecondaryStorage(srcImageStore.getUrl());
String primaryPoolUuid = destData.getDataStore().getUuid();
String destPath = config.getAgentOvmRepoPath() + "/"
+ ovmObject.deDash(primaryPoolUuid) + "/"
+ config.getTemplateDir();
String sourcePath = config.getAgentSecStoragePath()
+ "/" + secPoolUuid;
Linux host = new Linux(c);
String destUuid = destTemplate.getUuid();
/*
* Would love to add dynamic formats (tolower), to also support
* VHD and QCOW2, although Ovm3.2 does not have tapdisk2 anymore
* so we can forget about that.
*/
/* TODO: add checksumming */
String srcFile = sourcePath + "/"
+ srcData.getPath();
if (srcData.getPath().endsWith("/")) {
srcFile = sourcePath + "/" + srcData.getPath()
+ "/" + destUuid + ".raw";
}
String destFile = destPath + "/" + destUuid + ".raw";
logger.debug("CopyFrom: " + srcData.getObjectType() + ","
+ srcFile + " to " + destData.getObjectType() + ","
+ destFile);
host.copyFile(srcFile, destFile);
TemplateObjectTO newVol = new TemplateObjectTO();
newVol.setUuid(destUuid);
// was destfile
newVol.setPath(destUuid);
newVol.setFormat(ImageFormat.RAW);
return new CopyCmdAnswer(newVol);
} catch (Ovm3ResourceException e) {
String msg = "Error while copying template to primary storage: " + e.getMessage();
logger.info(msg);
return new CopyCmdAnswer(msg);
}
}
/**
* Only copies in case of dest is NfsTO, xenserver also unmounts secstorage
*/
@Override
public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
logger.debug("execute copyVolumeFromPrimaryToSecondary: "+ cmd.getClass());
return new Answer(cmd);
}
/**
* dest is VolumeObject, src is a template
*/
@Override
public CopyCmdAnswer cloneVolumeFromBaseTemplate(CopyCommand cmd) {
logger.debug("execute cloneVolumeFromBaseTemplate: "+ cmd.getClass());
try {
// src
DataTO srcData = cmd.getSrcTO();
TemplateObjectTO src = (TemplateObjectTO) srcData;
String srcFile = getVirtualDiskPath(src.getUuid(), src.getDataStore().getUuid());
srcFile = srcFile.replace(config.getVirtualDiskDir(), config.getTemplateDir());
DataTO destData = cmd.getDestTO();
VolumeObjectTO dest = (VolumeObjectTO) destData;
String destFile = getVirtualDiskPath(dest.getUuid(), dest.getDataStore().getUuid());
Linux host = new Linux(c);
logger.debug("CopyFrom: " + srcData.getObjectType() + ","
+ srcFile + " to " + destData.getObjectType() + ","
+ destFile);
host.copyFile(srcFile, destFile);
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setUuid(dest.getUuid());
// was destfile
newVol.setPath(dest.getUuid());
newVol.setFormat(ImageFormat.RAW);
return new CopyCmdAnswer(newVol);
} catch (Ovm3ResourceException e) {
String msg = "Error cloneVolumeFromBaseTemplate: " + e.getMessage();
logger.info(msg);
return new CopyCmdAnswer(msg);
}
}
/**
* createprivatetemplate, also needs template.properties
*/
@Override
public Answer createTemplateFromVolume(CopyCommand cmd) {
logger.debug("execute createTemplateFromVolume: "+ cmd.getClass());
return new Answer(cmd);
}
/**
* Volume to Volume from NfsTO
*/
@Override
public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
logger.debug("execute copyVolumeFromImageCacheToPrimary: "+ cmd.getClass());
return new Answer(cmd);
}
/**
* Copies from secondary to secondary
*/
@Override
public Answer createTemplateFromSnapshot(CopyCommand cmd) {
logger.debug("execute createTemplateFromSnapshot: "+ cmd.getClass());
try {
// src.getPath contains the uuid of the snapshot.
DataTO srcData = cmd.getSrcTO();
SnapshotObjectTO srcSnap = (SnapshotObjectTO) srcData;
String secPoolUuid = pool.setupSecondaryStorage(srcData.getDataStore().getUrl());
String srcFile = config.getAgentSecStoragePath()
+ "/" + secPoolUuid + "/"
+ srcSnap.getPath();
// dest
DataTO destData = cmd.getDestTO();
TemplateObjectTO destTemplate = (TemplateObjectTO) destData;
String secPoolUuidTemplate = pool.setupSecondaryStorage(destData.getDataStore().getUrl());
String destDir = config.getAgentSecStoragePath()
+ "/" + secPoolUuidTemplate + "/"
+ destTemplate.getPath();
String destFile = destDir + "/"
+ destTemplate.getUuid() + ".raw";
CloudstackPlugin csp = new CloudstackPlugin(c);
csp.ovsMkdirs(destDir);
Linux host = new Linux(c);
host.copyFile(srcFile, destFile);
TemplateObjectTO newVol = new TemplateObjectTO();
newVol.setUuid(destTemplate.getUuid());
newVol.setPath(destTemplate.getUuid());
newVol.setFormat(ImageFormat.RAW);
return new CopyCmdAnswer(newVol);
} catch (Ovm3ResourceException e) {
String msg = "Error backupSnapshot: " + e.getMessage();
logger.info(msg);
return new CopyCmdAnswer(msg);
}
}
/**
* use the cache, or the normal nfs, also delete the leftovers for us
* also contains object store storage in xenserver.
*/
@Override
public CopyCmdAnswer backupSnapshot(CopyCommand cmd) {
logger.debug("execute backupSnapshot: "+ cmd.getClass());
try {
DataTO srcData = cmd.getSrcTO();
DataTO destData = cmd.getDestTO();
SnapshotObjectTO src = (SnapshotObjectTO) srcData;
SnapshotObjectTO dest = (SnapshotObjectTO) destData;
// src.getPath contains the uuid of the snapshot.
String srcFile = getVirtualDiskPath(src.getPath(), src.getDataStore().getUuid());
// destination
String storeUrl = dest.getDataStore().getUrl();
String secPoolUuid = pool.setupSecondaryStorage(storeUrl);
String destDir = config.getAgentSecStoragePath()
+ "/" + secPoolUuid + "/"
+ dest.getPath();
String destFile = destDir + "/" + src.getPath();
destFile = destFile.concat(".raw");
// copy
Linux host = new Linux(c);
CloudstackPlugin csp = new CloudstackPlugin(c);
csp.ovsMkdirs(destDir);
logger.debug("CopyFrom: " + srcData.getObjectType() + ","
+ srcFile + " to " + destData.getObjectType() + ","
+ destFile);
host.copyFile(srcFile, destFile);
StoragePlugin sp = new StoragePlugin(c);
sp.storagePluginDestroy(secPoolUuid, srcFile);
SnapshotObjectTO newSnap = new SnapshotObjectTO();
// newSnap.setPath(destFile);
// damnit frickin crap, no reference whatsoever... could use parent ?
newSnap.setPath(dest.getPath() + "/" + src.getPath() + ".raw");
newSnap.setParentSnapshotPath(null);
return new CopyCmdAnswer(newSnap);
} catch (Ovm3ResourceException e) {
String msg = "Error backupSnapshot: " + e.getMessage();
logger.info(msg);
return new CopyCmdAnswer(msg);
}
}
public Answer execute(CreateObjectCommand cmd) {
logger.debug("execute: "+ cmd.getClass());
DataTO data = cmd.getData();
if (data.getObjectType() == DataObjectType.VOLUME) {
return createVolume(cmd);
} else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
return createSnapshot(cmd);
} else if (data.getObjectType() == DataObjectType.TEMPLATE) {
logger.debug("Template object creation not supported.");
}
return new CreateObjectAnswer(data.getObjectType()
+ " object creation not supported");
}
/**
* Attach an iso
*/
@Override
public AttachAnswer attachIso(AttachCommand cmd) {
logger.debug("execute attachIso: "+ cmd.getClass());
String vmName = cmd.getVmName();
DiskTO disk = cmd.getDisk();
return attachDetach(cmd, vmName, disk, true);
}
/**
* Detach an iso
*/
@Override
public AttachAnswer dettachIso(DettachCommand cmd) {
logger.debug("execute dettachIso: "+ cmd.getClass());
String vmName = cmd.getVmName();
DiskTO disk = cmd.getDisk();
return attachDetach(cmd, vmName, disk, false);
}
/**
* Iso specific path return.
* @param disk
* @return
* @throws Ovm3ResourceException
*/
private String getIsoPath(DiskTO disk) throws Ovm3ResourceException {
TemplateObjectTO isoTO = (TemplateObjectTO) disk.getData();
DataStoreTO store = isoTO.getDataStore();
NfsTO nfsStore = (NfsTO) store;
String secPoolUuid = pool.setupSecondaryStorage(nfsStore.getUrl());
return config.getAgentSecStoragePath() + "/"
+ secPoolUuid + "/" + isoTO.getPath();
}
/**
* Returns the disk path
* @param diskUuid
* @return
* @throws Ovm3ResourceException
*/
public String getVirtualDiskPath(String diskUuid, String storeUuid) throws Ovm3ResourceException {
String d = config.getAgentOvmRepoPath() +
"/" +
ovmObject.deDash(storeUuid) +
"/" +
config.getVirtualDiskDir() +
"/" +
diskUuid;
if (!d.endsWith(".raw")) {
d = d.concat(".raw");
}
return d;
}
public String getVirtualDiskPath(DiskTO disk, String storeUuid) throws Ovm3ResourceException {
return getVirtualDiskPath(disk.getPath(), storeUuid);
}
/**
* Generic disk attach/detach.
* @param cmd
* @param vmName
* @param disk
* @param isAttach
* @return
*/
private AttachAnswer attachDetach(Command cmd, String vmName, DiskTO disk,
boolean isAttach) {
Xen xen = new Xen(c);
String doThis = (isAttach) ? "Attach" : "Dettach";
logger.debug(doThis + " volume type " + disk.getType() + " " + vmName);
String msg = "";
String path = "";
try {
Xen.Vm vm = xen.getVmConfig(vmName);
/* check running */
if (vm == null) {
msg = doThis + " can't find VM " + vmName;
logger.debug(msg);
return new AttachAnswer(msg);
}
if (disk.getType() == Volume.Type.ISO) {
path = getIsoPath(disk);
} else if (disk.getType() == Volume.Type.DATADISK) {
path = getVirtualDiskPath(disk, vm.getPrimaryPoolUuid());
}
if ("".equals(path)) {
msg = doThis + " can't do anything with an empty path.";
logger.debug(msg);
return new AttachAnswer(msg);
}
if (isAttach) {
if (disk.getType() == Volume.Type.ISO) {
vm.addIso(path);
} else {
vm.addDataDisk(path);
}
} else {
if (!vm.removeDisk(path)) {
msg = doThis + " failed for " + vmName + disk.getType()
+ " was not attached " + path;
logger.debug(msg);
return new AttachAnswer(msg);
}
}
xen.configureVm(ovmObject.deDash(vm.getPrimaryPoolUuid()),
vm.getVmUuid());
return new AttachAnswer(disk);
} catch (Ovm3ResourceException e) {
msg = doThis + " failed for " + vmName + " " + e.getMessage();
logger.warn(msg, e);
return new AttachAnswer(msg);
}
}
/**
* Attach a volume
*/
@Override
public AttachAnswer attachVolume(AttachCommand cmd) {
logger.debug("execute attachVolume: "+ cmd.getClass());
String vmName = cmd.getVmName();
DiskTO disk = cmd.getDisk();
return attachDetach(cmd, vmName, disk, true);
}
/**
* Detach a volume
*/
@Override
public AttachAnswer dettachVolume(DettachCommand cmd) {
logger.debug("execute dettachVolume: "+ cmd.getClass());
String vmName = cmd.getVmName();
DiskTO disk = cmd.getDisk();
return attachDetach(cmd, vmName, disk, false);
}
/**
* Creates a volume, just a normal empty volume.
*/
@Override
public Answer createVolume(CreateObjectCommand cmd) {
logger.debug("execute createVolume: "+ cmd.getClass());
DataTO data = cmd.getData();
VolumeObjectTO volume = (VolumeObjectTO) data;
try {
/*
* public Boolean storagePluginCreate(String uuid, String ssuuid,
* String host, String file, Integer size)
*/
String poolUuid = data.getDataStore().getUuid();
String storeUrl = data.getDataStore().getUrl();
URI uri = new URI(storeUrl);
String host = uri.getHost();
String file = getVirtualDiskPath(volume.getUuid(), poolUuid);
Long size = volume.getSize();
StoragePlugin sp = new StoragePlugin(c);
FileProperties fp = sp.storagePluginCreate(poolUuid, host, file,
size, false);
if (!fp.getName().equals(file)) {
return new CreateObjectAnswer("Filename mismatch: "
+ fp.getName() + " != " + file);
}
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setName(volume.getName());
newVol.setSize(fp.getSize());
newVol.setPath(volume.getUuid());
return new CreateObjectAnswer(newVol);
} catch (Ovm3ResourceException | URISyntaxException e) {
logger.info("Volume creation failed: " + e.toString(), e);
return new CreateObjectAnswer(e.toString());
}
}
/**
* Creates a snapshot from a volume, but only if the VM is stopped.
* This due qemu not being able to snap raw volumes.
*
* if stopped yes, if running ... no, unless we have ocfs2 when
* using raw partitions (file:) if using tap:aio we cloud...
* The "ancient" way:
* We do however follow the "two stage" approach, of "snap"
* on primary first, with the create object... and then
* backup the snapshot with the copycmd....
* (should transfer to createSnapshot, backupSnapshot)
*/
@Override
public Answer createSnapshot(CreateObjectCommand cmd) {
logger.debug("execute createSnapshot: "+ cmd.getClass());
DataTO data = cmd.getData();
Xen xen = new Xen(c);
SnapshotObjectTO snap = (SnapshotObjectTO) data;
VolumeObjectTO vol = snap.getVolume();
try {
Xen.Vm vm = xen.getVmConfig(snap.getVmName());
if (vm != null) {
return new CreateObjectAnswer(
"Snapshot object creation not supported for running VMs."
+ snap.getVmName());
}
Linux host = new Linux(c);
String uuid = host.newUuid();
/* for root volumes this works... */
String src = vol.getPath() + "/" + vol.getUuid()
+ ".raw";
String dest = vol.getPath() + "/" + uuid + ".raw";
/* seems that sometimes the path is already contains a file
* in case, we just replace it.... (Seems to happen if not ROOT)
*/
if (vol.getPath().contains(vol.getUuid())) {
src = getVirtualDiskPath(vol.getUuid(),data.getDataStore().getUuid());
dest = src.replace(vol.getUuid(), uuid);
}
logger.debug("Snapshot " + src + " to " + dest);
host.copyFile(src, dest);
SnapshotObjectTO nsnap = new SnapshotObjectTO();
// nsnap.setPath(dest);
// move to something that looks the same as xenserver.
nsnap.setPath(uuid);
return new CreateObjectAnswer(nsnap);
} catch (Ovm3ResourceException e) {
return new CreateObjectAnswer(
"Snapshot object creation failed. " + e.getMessage());
}
}
@Override
public Answer deleteVolume(DeleteCommand cmd) {
logger.debug("execute deleteVolume: "+ cmd.getClass());
DataTO data = cmd.getData();
VolumeObjectTO volume = (VolumeObjectTO) data;
try {
String poolUuid = data.getDataStore().getUuid();
String uuid = volume.getUuid();
String path = getVirtualDiskPath(uuid, poolUuid);
StoragePlugin sp = new StoragePlugin(c);
sp.storagePluginDestroy(poolUuid, path);
logger.debug("Volume deletion success: " + path);
} catch (Ovm3ResourceException e) {
logger.info("Volume deletion failed: " + e.toString(), e);
return new CreateObjectAnswer(e.toString());
}
return new Answer(cmd);
}
/*
* CopyVolumeCommand gets the storage_pool should use that for
* bumper bowling.
*/
public CopyVolumeAnswer execute(CopyVolumeCommand cmd) {
logger.debug("execute: "+ cmd.getClass());
String volumePath = cmd.getVolumePath();
/* is a repository */
String secondaryStorageURL = cmd.getSecondaryStorageURL();
int wait = cmd.getWait();
if (wait == 0) {
wait = 7200;
}
try {
Linux host = new Linux(c);
/* to secondary storage */
if (cmd.toSecondaryStorage()) {
logger.debug("Copy to secondary storage " + volumePath
+ " to " + secondaryStorageURL);
host.copyFile(volumePath, secondaryStorageURL);
/* from secondary storage */
} else {
logger.debug("Copy from secondary storage "
+ secondaryStorageURL + " to " + volumePath);
host.copyFile(secondaryStorageURL, volumePath);
}
/* check the truth of this */
return new CopyVolumeAnswer(cmd, true, null, null, null);
} catch (Ovm3ResourceException e) {
logger.debug("Copy volume failed", e);
return new CopyVolumeAnswer(cmd, false, e.getMessage(), null, null);
}
}
/* Destroy a volume (image) */
public Answer execute(DestroyCommand cmd) {
logger.debug("execute: "+ cmd.getClass());
VolumeTO vol = cmd.getVolume();
String vmName = cmd.getVmName();
try {
StoragePlugin store = new StoragePlugin(c);
store.storagePluginDestroy(vol.getPoolUuid(), vol.getPath());
return new Answer(cmd, true, "Success");
} catch (Ovm3ResourceException e) {
logger.debug("Destroy volume " + vol.getName() + " failed for "
+ vmName + " ", e);
return new Answer(cmd, false, e.getMessage());
}
}
/* check if a VM is running should be added */
public CreatePrivateTemplateAnswer execute(
final CreatePrivateTemplateFromVolumeCommand cmd) {
logger.debug("execute: "+ cmd.getClass());
String volumePath = cmd.getVolumePath();
Long accountId = cmd.getAccountId();
Long templateId = cmd.getTemplateId();
int wait = cmd.getWait();
if (wait == 0) {
/* Defaut timeout 2 hours */
wait = 7200;
}
try {
/* missing uuid */
String installPath = config.getAgentOvmRepoPath() + "/"
+ config.getTemplateDir() + "/"
+ accountId + "/" + templateId;
Linux host = new Linux(c);
host.copyFile(volumePath, installPath);
return new CreatePrivateTemplateAnswer(cmd, true, installPath);
} catch (Exception e) {
logger.debug("Create template failed", e);
return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
}
}
/**
* SnapshotObjectTO secondary to VolumeObjectTO primary in xenserver,
*/
@Override
public Answer createVolumeFromSnapshot(CopyCommand cmd) {
logger.debug("execute createVolumeFromSnapshot: "+ cmd.getClass());
try {
DataTO srcData = cmd.getSrcTO();
DataStoreTO srcStore = srcData.getDataStore();
NfsTO srcImageStore = (NfsTO) srcStore;
// source, should contain snap dir/filename
SnapshotObjectTO srcSnap = (SnapshotObjectTO) srcData;
String secPoolUuid = pool.setupSecondaryStorage(srcImageStore.getUrl());
String srcFile = config.getAgentSecStoragePath()
+ "/" + secPoolUuid + "/"
+ srcSnap.getPath();
// dest
DataTO destData = cmd.getDestTO();
VolumeObjectTO destVol = (VolumeObjectTO) destData;
String primaryPoolUuid = destData.getDataStore().getUuid();
String destFile = getVirtualDiskPath(destVol.getUuid(), ovmObject.deDash(primaryPoolUuid));
Linux host = new Linux(c);
host.copyFile(srcFile, destFile);
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setUuid(destVol.getUuid());
// newVol.setPath(destFile);
newVol.setPath(destVol.getUuid());
newVol.setFormat(ImageFormat.RAW);
return new CopyCmdAnswer(newVol);
/* we assume the cache for templates is local */
} catch (Ovm3ResourceException e) {
logger.debug("Failed to createVolumeFromSnapshot: ", e);
return new CopyCmdAnswer(e.toString());
}
}
/**
* Is not used in normal operation, the SSVM takes care of this.
*/
@Override
public Answer deleteSnapshot(DeleteCommand cmd) {
logger.debug("execute deleteSnapshot: "+ cmd.getClass());
DataTO data = cmd.getData();
SnapshotObjectTO snap = (SnapshotObjectTO) data;
String storeUrl = data.getDataStore().getUrl();
String snapUuid = snap.getPath();
try {
// snapshots/accountid/volumeid
String secPoolUuid = pool.setupSecondaryStorage(storeUrl);
String filePath = config.getAgentSecStoragePath()
+ "/" + secPoolUuid + "/"
+ snapUuid + ".raw";
StoragePlugin sp = new StoragePlugin(c);
sp.storagePluginDestroy(secPoolUuid, filePath);
logger.debug("Snapshot deletion success: " + filePath);
return new Answer(cmd, true, "Deleted Snapshot " + filePath);
} catch (Ovm3ResourceException e) {
logger.info("Snapshot deletion failed: " + e.toString(), e);
return new CreateObjectAnswer(e.toString());
}
}
/**
* SR scan in xenserver
*/
@Override
public Answer introduceObject(IntroduceObjectCmd cmd) {
logger.debug("execute introduceObject: "+ cmd.getClass());
return new Answer(cmd, false, "not implemented yet");
}
/**
* used as unmount for VDIs in xenserver
*/
@Override
public Answer forgetObject(ForgetObjectCmd cmd) {
logger.debug("execute forgetObject: "+ cmd.getClass());
return new Answer(cmd, false, "not implemented yet");
}
/**
* make sure both mounts are there, snapshot source image
* copy snap to dest image, remove source snap and unmount
* iSCSI?
*/
@Override
public SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand cmd) {
logger.info("'SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand)' not currently used for Ovm3StorageProcessor");
return new SnapshotAndCopyAnswer("Not implemented");
}
@Override
public ResignatureAnswer resignature(final ResignatureCommand cmd) {
logger.info("'ResignatureAnswer resignature(ResignatureCommand)' not currently used for Ovm3StorageProcessor");
return new ResignatureAnswer("Not implemented");
}
@Override
public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd) {
return null;
}
@Override
public Answer checkDataStoreStoragePolicyCompliance(CheckDataStoreStoragePolicyComplainceCommand cmd) {
logger.info("'CheckDataStoreStoragePolicyComplainceCommand' not applicable used for Ovm3StorageProcessor");
return new Answer(cmd,false,"Not applicable used for Ovm3StorageProcessor");
}
@Override
public Answer syncVolumePath(SyncVolumePathCommand cmd) {
logger.info("SyncVolumePathCommand not currently applicable for Ovm3StorageProcessor");
return new Answer(cmd, false, "Not currently applicable for Ovm3StorageProcessor");
}
@Override
public Answer copyVolumeFromPrimaryToPrimary(CopyCommand cmd) {
return null;
}
/**
* Attach disks
* @param cmd
* @return
*/
public Answer execute(AttachCommand cmd) {
logger.debug("execute: "+ cmd.getClass());
String vmName = cmd.getVmName();
DiskTO disk = cmd.getDisk();
return attachDetach(cmd, vmName, disk, true);
}
/**
* Detach disks, calls a middle man which calls attachDetach for volumes.
* @param cmd
* @return
*/
public Answer execute(DettachCommand cmd) {
logger.debug("execute: "+ cmd.getClass());
String vmName = cmd.getVmName();
DiskTO disk = cmd.getDisk();
return attachDetach(cmd, vmName, disk, false);
}
}