mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
Merge pull request #1361 from nvazquez/bothgoals
CLOUDSTACK-9252: Support configurable NFS version for Secondary Storage mountsJIRA Ticket: https://issues.apache.org/jira/browse/CLOUDSTACK-9252 ### Description of the problem After starting secondary storage VM, secondary storage tries to be mounted but fails with error: <code>Protocol family not supported</code> It was found out that adding <code>-o vers=X</code> to mount command it would work, where <code>X</code> is the desired NFS version to use. If it is desired to mount a store with a specific NFS version, it has passed in <code>image_store_details</code> table for a store with id <code>Y</code> as a property: | store_id| name| value | |:-------------:|:-------------:|:-------------:| |Y|nfs.version|X (e.g. 3)| Where X stands for NFS version * pr/1361: CLOUDSTACK-9252: Last refactor, passing nfs version to ssvm CLOUDSTACK-9252: Add missing licence header CLOUDSTACK-9252: Little refactor CLOUDSTACK-9252: Mock application context for unit test CLOUDSTACK-9252: Add unit tests CLOUDSTACK-9252: New refactor CLOUDSTACK-9252: Remove static dependencies, refactor CLOUDSTACK-9252: Remove duplicates getNfsVersion, refactor CLOUDSTACK-9252: Support configurable nfs version CLOUDSTACK-9252: Add nfs version to commands Signed-off-by: Rafael Weingärtner <rafael@apache.org>
This commit is contained in:
commit
d705d85270
@ -39,6 +39,7 @@ public class BackupSnapshotCommand extends SnapshotCommand {
|
||||
private S3TO s3;
|
||||
StorageFilerTO pool;
|
||||
private Long secHostId;
|
||||
private String nfsVersion;
|
||||
|
||||
protected BackupSnapshotCommand() {
|
||||
|
||||
@ -107,4 +108,12 @@ public class BackupSnapshotCommand extends SnapshotCommand {
|
||||
public Long getSecHostId() {
|
||||
return secHostId;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ public class CreatePrivateTemplateFromSnapshotCommand extends SnapshotCommand {
|
||||
private String origTemplateInstallPath;
|
||||
private Long newTemplateId;
|
||||
private String templateName;
|
||||
private String nfsVersion;
|
||||
|
||||
protected CreatePrivateTemplateFromSnapshotCommand() {
|
||||
|
||||
@ -72,4 +73,12 @@ public class CreatePrivateTemplateFromSnapshotCommand extends SnapshotCommand {
|
||||
public String getTemplateName() {
|
||||
return templateName;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
|
||||
StorageFilerTO _primaryPool;
|
||||
// For XenServer
|
||||
private String _secondaryStorageUrl;
|
||||
private String nfsVersion;
|
||||
|
||||
public CreatePrivateTemplateFromVolumeCommand() {
|
||||
}
|
||||
@ -99,4 +100,12 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
|
||||
public void setTemplateId(long templateId) {
|
||||
_templateId = templateId;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,8 @@ import com.cloud.storage.StoragePool;
|
||||
*/
|
||||
public class CreateVolumeFromSnapshotCommand extends SnapshotCommand {
|
||||
|
||||
private String nfsVersion;
|
||||
|
||||
protected CreateVolumeFromSnapshotCommand() {
|
||||
|
||||
}
|
||||
@ -50,4 +52,12 @@ public class CreateVolumeFromSnapshotCommand extends SnapshotCommand {
|
||||
super(pool, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId);
|
||||
setWait(wait);
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ public class GetStorageStatsCommand extends Command {
|
||||
private StoragePoolType pooltype;
|
||||
private String secUrl;
|
||||
private DataStoreTO store;
|
||||
private String nfsVersion;
|
||||
|
||||
public String getSecUrl() {
|
||||
return secUrl;
|
||||
@ -54,6 +55,11 @@ public class GetStorageStatsCommand extends Command {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public GetStorageStatsCommand(DataStoreTO store, String nfsVersion) {
|
||||
this.store = store;
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
|
||||
public GetStorageStatsCommand(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
@ -81,6 +87,14 @@ public class GetStorageStatsCommand extends Command {
|
||||
return this.store;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
|
||||
@ -28,6 +28,7 @@ public class SecStorageSetupCommand extends Command {
|
||||
private String secUrl;
|
||||
private KeystoreManager.Certificates certs;
|
||||
private String postUploadKey;
|
||||
private String nfsVersion;
|
||||
|
||||
|
||||
public SecStorageSetupCommand() {
|
||||
@ -74,4 +75,12 @@ public class SecStorageSetupCommand extends Command {
|
||||
public void setPostUploadKey(String postUploadKey) {
|
||||
this.postUploadKey = postUploadKey;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ public class CopyVolumeCommand extends Command {
|
||||
boolean toSecondaryStorage;
|
||||
String vmName;
|
||||
boolean executeInSequence = false;
|
||||
String nfsVersion;
|
||||
|
||||
public CopyVolumeCommand() {
|
||||
}
|
||||
@ -75,4 +76,12 @@ public class CopyVolumeCommand extends Command {
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import com.cloud.agent.api.to.DataStoreTO;
|
||||
|
||||
public class ListTemplateCommand extends StorageCommand {
|
||||
private DataStoreTO store;
|
||||
private String nfsVersion;
|
||||
|
||||
//private String secUrl;
|
||||
|
||||
@ -34,6 +35,11 @@ public class ListTemplateCommand extends StorageCommand {
|
||||
// this.secUrl = url;
|
||||
}
|
||||
|
||||
public ListTemplateCommand(DataStoreTO store, String nfsVersion) {
|
||||
this.store = store;
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
@ -43,6 +49,10 @@ public class ListTemplateCommand extends StorageCommand {
|
||||
return store;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
// public String getSecUrl() {
|
||||
// return secUrl;
|
||||
// }
|
||||
|
||||
@ -35,6 +35,7 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand {
|
||||
|
||||
String secondaryStorageUrl;
|
||||
String primaryStorageUrl;
|
||||
String nfsVersion;
|
||||
|
||||
protected PrimaryStorageDownloadCommand() {
|
||||
}
|
||||
@ -87,4 +88,12 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand {
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,6 +53,8 @@ public class TemplateOrVolumePostUploadCommand {
|
||||
|
||||
private long accountId;
|
||||
|
||||
private String nfsVersion;
|
||||
|
||||
public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo,
|
||||
String dataToRole) {
|
||||
this.entityId = entityId;
|
||||
@ -196,4 +198,12 @@ public class TemplateOrVolumePostUploadCommand {
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public String getNfsVersion() {
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
public void setNfsVersion(String nfsVersion) {
|
||||
this.nfsVersion = nfsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
<bean id="templateServiceImpl"
|
||||
class="org.apache.cloudstack.storage.image.TemplateServiceImpl"
|
||||
depends-on="dataObjectManagerImpl, dataStoreManagerImpl, dataMotionServiceImpl, objectInDataStoreManagerImpl, defaultEndPointSelector, templateDataFactoryImpl" />
|
||||
depends-on="dataObjectManagerImpl, dataStoreManagerImpl, dataMotionServiceImpl, objectInDataStoreManagerImpl, defaultEndPointSelector, templateDataFactoryImpl, imageStoreDetailsUtil" />
|
||||
|
||||
<bean id="templateDataFactoryImpl"
|
||||
class="org.apache.cloudstack.storage.image.TemplateDataFactoryImpl" />
|
||||
|
||||
@ -73,6 +73,7 @@ import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.ImageStoreDetailsUtil;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.TemplateType;
|
||||
import com.cloud.storage.StoragePool;
|
||||
@ -135,6 +136,8 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
ConfigurationDao _configDao;
|
||||
@Inject
|
||||
StorageCacheManager _cacheMgr;
|
||||
@Inject
|
||||
ImageStoreDetailsUtil imageStoreDetailsUtil;
|
||||
|
||||
class TemplateOpContext<T> extends AsyncRpcContext<T> {
|
||||
final TemplateObject template;
|
||||
@ -564,7 +567,7 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
}
|
||||
|
||||
private Map<String, TemplateProp> listTemplate(DataStore ssStore) {
|
||||
ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO());
|
||||
ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO(), imageStoreDetailsUtil.getNfsVersion(ssStore.getId()));
|
||||
EndPoint ep = _epSelector.select(ssStore);
|
||||
Answer answer = null;
|
||||
if (ep == null) {
|
||||
|
||||
@ -51,7 +51,7 @@ public class MockLocalNfsSecondaryStorageResource extends NfsSecondaryStorageRes
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRootDir(String secUrl) {
|
||||
public String getRootDir(String secUrl, String nfsVersion) {
|
||||
return "/mnt";
|
||||
}
|
||||
|
||||
|
||||
@ -69,5 +69,7 @@
|
||||
<property name="snapshotStrategies" value="#{snapshotStrategiesRegistry.registered}" />
|
||||
<property name="vmSnapshotStrategies" value="#{vmSnapshotStrategiesRegistry.registered}" />
|
||||
</bean>
|
||||
|
||||
<bean id="imageStoreDetailsUtil" class="com.cloud.storage.ImageStoreDetailsUtil" />
|
||||
|
||||
</beans>
|
||||
|
||||
@ -109,7 +109,7 @@ public class AgentStorageResource extends AgentResourceBase implements Secondary
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRootDir(String url) {
|
||||
public String getRootDir(String url, String nfsVersion) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ public interface VmwareManager {
|
||||
|
||||
String getSystemVMDefaultNicAdapterType();
|
||||
|
||||
void prepareSecondaryStorageStore(String strStorageUrl);
|
||||
void prepareSecondaryStorageStore(String strStorageUrl, Long storeId);
|
||||
|
||||
void setupResourceStartupParams(Map<String, Object> params);
|
||||
|
||||
@ -48,7 +48,7 @@ public interface VmwareManager {
|
||||
|
||||
String getManagementPortGroupName();
|
||||
|
||||
String getSecondaryStorageStoreUrl(long dcId);
|
||||
Pair<String, Long> getSecondaryStorageStoreUrlAndId(long dcId);
|
||||
|
||||
File getSystemVMKeyFile();
|
||||
|
||||
|
||||
@ -105,6 +105,7 @@ import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
|
||||
import com.cloud.org.Cluster.ClusterType;
|
||||
import com.cloud.secstorage.CommandExecLogDao;
|
||||
import com.cloud.server.ConfigurationServer;
|
||||
import com.cloud.storage.ImageStoreDetailsUtil;
|
||||
import com.cloud.storage.JavaStorageLayer;
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.utils.FileUtil;
|
||||
@ -167,6 +168,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
private ManagementServerHostPeerDao _mshostPeerDao;
|
||||
@Inject
|
||||
private ClusterManager _clusterMgr;
|
||||
@Inject
|
||||
private ImageStoreDetailsUtil imageStoreDetailsUtil;
|
||||
|
||||
private String _mountParent;
|
||||
private StorageLayer _storage;
|
||||
@ -439,12 +442,14 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSecondaryStorageStoreUrl(long dcId) {
|
||||
public Pair<String, Long> getSecondaryStorageStoreUrlAndId(long dcId) {
|
||||
|
||||
String secUrl = null;
|
||||
Long secId = null;
|
||||
DataStore secStore = _dataStoreMgr.getImageStore(dcId);
|
||||
if (secStore != null) {
|
||||
secUrl = secStore.getUri();
|
||||
secId = secStore.getId();
|
||||
}
|
||||
|
||||
if (secUrl == null) {
|
||||
@ -453,12 +458,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
DataStore cacheStore = _dataStoreMgr.getImageCacheStore(dcId);
|
||||
if (cacheStore != null) {
|
||||
secUrl = cacheStore.getUri();
|
||||
secId = cacheStore.getId();
|
||||
} else {
|
||||
s_logger.warn("No staging storage is found when non-NFS secondary storage is used");
|
||||
}
|
||||
}
|
||||
|
||||
return secUrl;
|
||||
return new Pair<String, Long>(secUrl, secId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -546,8 +552,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareSecondaryStorageStore(String storageUrl) {
|
||||
String mountPoint = getMountPoint(storageUrl);
|
||||
public void prepareSecondaryStorageStore(String storageUrl, Long storeId) {
|
||||
String mountPoint = getMountPoint(storageUrl, imageStoreDetailsUtil.getNfsVersion(storeId));
|
||||
|
||||
GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm");
|
||||
try {
|
||||
@ -655,7 +661,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMountPoint(String storageUrl) {
|
||||
public String getMountPoint(String storageUrl, String nfsVersion) {
|
||||
String mountPoint = null;
|
||||
synchronized (_storageMounts) {
|
||||
mountPoint = _storageMounts.get(storageUrl);
|
||||
@ -670,7 +676,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
s_logger.error("Invalid storage URL format ", e);
|
||||
throw new CloudRuntimeException("Unable to create mount point due to invalid storage URL format " + storageUrl);
|
||||
}
|
||||
mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent);
|
||||
|
||||
mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent, nfsVersion);
|
||||
if (mountPoint == null) {
|
||||
s_logger.error("Unable to create mount point for " + storageUrl);
|
||||
return "/mnt/sec"; // throw new CloudRuntimeException("Unable to create mount point for " + storageUrl);
|
||||
@ -745,7 +752,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
}
|
||||
}
|
||||
|
||||
protected String mount(String path, String parent) {
|
||||
protected String mount(String path, String parent, String nfsVersion) {
|
||||
String mountPoint = setupMountPoint(parent);
|
||||
if (mountPoint == null) {
|
||||
s_logger.warn("Unable to create a mount point");
|
||||
@ -756,6 +763,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
String result = null;
|
||||
Script command = new Script(true, "mount", _timeout, s_logger);
|
||||
command.add("-t", "nfs");
|
||||
if (nfsVersion != null){
|
||||
command.add("-o", "vers=" + nfsVersion);
|
||||
}
|
||||
// command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
|
||||
if ("Mac OS X".equalsIgnoreCase(System.getProperty("os.name"))) {
|
||||
command.add("-o", "resvport");
|
||||
@ -1234,4 +1244,5 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -92,6 +92,9 @@ import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
||||
public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
|
||||
private String _nfsVersion;
|
||||
|
||||
@Override
|
||||
public boolean execute(VmwareHostService hostService, CreateEntityDownloadURLCommand cmd) {
|
||||
DataTO data = cmd.getData();
|
||||
@ -138,6 +141,12 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
_mountService = mountService;
|
||||
}
|
||||
|
||||
public VmwareStorageManagerImpl(VmwareStorageMount mountService, String nfsVersion) {
|
||||
assert (mountService != null);
|
||||
_mountService = mountService;
|
||||
_nfsVersion = nfsVersion;
|
||||
}
|
||||
|
||||
public void configure(Map<String, Object> params) {
|
||||
s_logger.info("Configure VmwareStorageManagerImpl");
|
||||
|
||||
@ -156,7 +165,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
String secStorageUrl = nfsStore.getUrl();
|
||||
assert (secStorageUrl != null);
|
||||
String installPath = template.getPath();
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, _nfsVersion);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
try {
|
||||
if (installFullPath.endsWith(".ova")) {
|
||||
@ -194,7 +203,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
String installPath = volume.getPath();
|
||||
int index = installPath.lastIndexOf(File.separator);
|
||||
String volumeUuid = installPath.substring(index + 1);
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, _nfsVersion);
|
||||
//The real volume path
|
||||
String volumePath = installPath + File.separator + volumeUuid + ".ova";
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
@ -271,7 +280,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
assert (morDs != null);
|
||||
DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs);
|
||||
|
||||
copyTemplateFromSecondaryToPrimary(hyperHost, primaryStorageDatastoreMo, secondaryStorageUrl, mountPoint, templateName, templateUuidName);
|
||||
copyTemplateFromSecondaryToPrimary(hyperHost, primaryStorageDatastoreMo, secondaryStorageUrl, mountPoint, templateName, templateUuidName,
|
||||
cmd.getNfsVersion());
|
||||
} else {
|
||||
s_logger.info("Template " + templateName + " has already been setup, skip the template setup process in primary storage");
|
||||
}
|
||||
@ -345,7 +355,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
|
||||
snapshotBackupUuid =
|
||||
backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid,
|
||||
hostService.getWorkerName(context, cmd, 1));
|
||||
hostService.getWorkerName(context, cmd, 1), cmd.getNfsVersion());
|
||||
|
||||
success = (snapshotBackupUuid != null);
|
||||
if (success) {
|
||||
@ -413,7 +423,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
|
||||
Ternary<String, Long, Long> result =
|
||||
createTemplateFromVolume(vmMo, accountId, templateId, cmd.getUniqueName(), secondaryStoragePoolURL, volumePath,
|
||||
hostService.getWorkerName(context, cmd, 0));
|
||||
hostService.getWorkerName(context, cmd, 0), cmd.getNfsVersion());
|
||||
|
||||
return new CreatePrivateTemplateAnswer(cmd, true, null, result.first(), result.third(), result.second(), cmd.getUniqueName(), ImageFormat.OVA);
|
||||
|
||||
@ -441,7 +451,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
|
||||
VmwareContext context = hostService.getServiceContext(cmd);
|
||||
try {
|
||||
Ternary<String, Long, Long> result = createTemplateFromSnapshot(accountId, newTemplateId, uniqeName, secondaryStorageUrl, volumeId, backedUpSnapshotUuid);
|
||||
Ternary<String, Long, Long> result = createTemplateFromSnapshot(accountId, newTemplateId, uniqeName, secondaryStorageUrl, volumeId, backedUpSnapshotUuid,
|
||||
cmd.getNfsVersion());
|
||||
|
||||
return new CreatePrivateTemplateAnswer(cmd, true, null, result.first(), result.third(), result.second(), uniqeName, ImageFormat.OVA);
|
||||
} catch (Throwable e) {
|
||||
@ -471,7 +482,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
if (cmd.toSecondaryStorage()) {
|
||||
result =
|
||||
copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath, secondaryStorageURL,
|
||||
hostService.getWorkerName(context, cmd, 0));
|
||||
hostService.getWorkerName(context, cmd, 0), cmd.getNfsVersion());
|
||||
} else {
|
||||
StorageFilerTO poolTO = cmd.getPool();
|
||||
|
||||
@ -484,8 +495,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
}
|
||||
|
||||
result = copyVolumeFromSecStorage(hyperHost, volumeId, new DatastoreMO(context, morDatastore), secondaryStorageURL, volumePath);
|
||||
deleteVolumeDirOnSecondaryStorage(volumeId, secondaryStorageURL);
|
||||
result = copyVolumeFromSecStorage(hyperHost, volumeId, new DatastoreMO(context, morDatastore), secondaryStorageURL, volumePath,
|
||||
cmd.getNfsVersion());
|
||||
deleteVolumeDirOnSecondaryStorage(volumeId, secondaryStorageURL, cmd.getNfsVersion());
|
||||
}
|
||||
return new CopyVolumeAnswer(cmd, true, null, result.first(), result.second());
|
||||
} catch (Throwable e) {
|
||||
@ -523,7 +535,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
|
||||
details = createVolumeFromSnapshot(hyperHost, primaryDsMo, newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid);
|
||||
details = createVolumeFromSnapshot(hyperHost, primaryDsMo, newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid,
|
||||
cmd.getNfsVersion());
|
||||
if (details == null) {
|
||||
success = true;
|
||||
}
|
||||
@ -542,12 +555,12 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
// templateName: name in secondary storage
|
||||
// templateUuid: will be used at hypervisor layer
|
||||
private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
|
||||
String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception {
|
||||
String templatePathAtSecondaryStorage, String templateName, String templateUuid, String nfsVersion) throws Exception {
|
||||
|
||||
s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
|
||||
templatePathAtSecondaryStorage + ", templateName: " + templateName);
|
||||
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl);
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl, nfsVersion);
|
||||
s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
|
||||
|
||||
String srcOVAFileName = secondaryMountPoint + "/" + templatePathAtSecondaryStorage + templateName + "." + ImageFormat.OVA.getFileExtension();
|
||||
@ -598,9 +611,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
private Ternary<String, Long, Long> createTemplateFromVolume(VirtualMachineMO vmMo, long accountId, long templateId, String templateUniqueName, String secStorageUrl,
|
||||
String volumePath, String workerVmName) throws Exception {
|
||||
String volumePath, String workerVmName, String nfsVersion) throws Exception {
|
||||
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
synchronized (installPath.intern()) {
|
||||
@ -663,9 +676,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
private Ternary<String, Long, Long> createTemplateFromSnapshot(long accountId, long templateId, String templateUniqueName, String secStorageUrl, long volumeId,
|
||||
String backedUpSnapshotUuid) throws Exception {
|
||||
String backedUpSnapshotUuid, String nfsVersion) throws Exception {
|
||||
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova"; //Note: volss for tmpl
|
||||
@ -847,16 +860,16 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
private String createVolumeFromSnapshot(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, long accountId, long volumeId,
|
||||
String secStorageUrl, String snapshotBackupUuid) throws Exception {
|
||||
String secStorageUrl, String snapshotBackupUuid, String nfsVersion) throws Exception {
|
||||
|
||||
restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid);
|
||||
restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid, nfsVersion);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir,
|
||||
String backupName) throws Exception {
|
||||
String backupName, String nfsVersion) throws Exception {
|
||||
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + "." + ImageFormat.OVA.getFileExtension();
|
||||
String snapshotDir = "";
|
||||
if (backupName.contains("/")) {
|
||||
@ -914,17 +927,17 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
private String backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, long accountId, long volumeId, String volumePath, String snapshotUuid, String secStorageUrl,
|
||||
String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception {
|
||||
String prevSnapshotUuid, String prevBackupUuid, String workerVmName, String nfsVersion) throws Exception {
|
||||
|
||||
String backupUuid = UUID.randomUUID().toString();
|
||||
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName);
|
||||
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName, nfsVersion);
|
||||
return backupUuid + "/" + backupUuid;
|
||||
}
|
||||
|
||||
private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir, String exportName,
|
||||
String workerVmName) throws Exception {
|
||||
String workerVmName, String nfsVersion) throws Exception {
|
||||
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
|
||||
|
||||
synchronized (exportPath.intern()) {
|
||||
@ -967,7 +980,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
private Pair<String, String> copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyVolumeCommand cmd, String vmName,
|
||||
long volumeId, String poolId, String volumePath, String secStorageUrl, String workerVmName) throws Exception {
|
||||
long volumeId, String poolId, String volumePath, String secStorageUrl, String workerVmName, String nfsVersion) throws Exception {
|
||||
|
||||
String volumeFolder = String.valueOf(volumeId) + "/";
|
||||
VirtualMachineMO workerVm = null;
|
||||
@ -1004,7 +1017,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
|
||||
|
||||
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName,
|
||||
hostService.getWorkerName(hyperHost.getContext(), cmd, 1));
|
||||
hostService.getWorkerName(hyperHost.getContext(), cmd, 1), nfsVersion);
|
||||
return new Pair<String, String>(volumeFolder, exportName);
|
||||
|
||||
} finally {
|
||||
@ -1025,12 +1038,12 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
return datastoreVolumePath;
|
||||
}
|
||||
|
||||
private Pair<String, String> copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, long volumeId, DatastoreMO dsMo, String secStorageUrl, String exportName)
|
||||
private Pair<String, String> copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, long volumeId, DatastoreMO dsMo, String secStorageUrl, String exportName, String nfsVersion)
|
||||
throws Exception {
|
||||
|
||||
String volumeFolder = String.valueOf(volumeId) + "/";
|
||||
String newVolume = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, "volumes/" + volumeFolder, exportName);
|
||||
restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, "volumes/" + volumeFolder, exportName, nfsVersion);
|
||||
|
||||
return new Pair<String, String>(volumeFolder, newVolume);
|
||||
}
|
||||
@ -1445,8 +1458,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
}
|
||||
|
||||
private String deleteVolumeDirOnSecondaryStorage(long volumeId, String secStorageUrl) throws Exception {
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
|
||||
private String deleteVolumeDirOnSecondaryStorage(long volumeId, String secStorageUrl, String nfsVersion) throws Exception {
|
||||
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String volumeMountRoot = secondaryMountPoint + "/" + getVolumeRelativeDirInSecStroage(volumeId);
|
||||
|
||||
return deleteDir(volumeMountRoot);
|
||||
|
||||
@ -17,5 +17,5 @@
|
||||
package com.cloud.hypervisor.vmware.manager;
|
||||
|
||||
public interface VmwareStorageMount {
|
||||
String getMountPoint(String storageUrl);
|
||||
String getMountPoint(String storageUrl, String nfsVersion);
|
||||
}
|
||||
|
||||
@ -1637,12 +1637,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
// prepare systemvm patch ISO
|
||||
if (vmSpec.getType() != VirtualMachine.Type.User) {
|
||||
// attach ISO (for patching of system VM)
|
||||
String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
|
||||
Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
|
||||
String secStoreUrl = secStoreUrlAndId.first();
|
||||
Long secStoreId = secStoreUrlAndId.second();
|
||||
if (secStoreUrl == null) {
|
||||
String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
|
||||
throw new Exception(msg);
|
||||
}
|
||||
mgr.prepareSecondaryStorageStore(secStoreUrl);
|
||||
mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
|
||||
|
||||
ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
|
||||
if (morSecDs == null) {
|
||||
@ -3210,12 +3212,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false, cmd.getVirtualMachine().getType());
|
||||
}
|
||||
|
||||
String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
|
||||
Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
|
||||
String secStoreUrl = secStoreUrlAndId.first();
|
||||
Long secStoreId = secStoreUrlAndId.second();
|
||||
if (secStoreUrl == null) {
|
||||
String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
|
||||
throw new Exception(msg);
|
||||
}
|
||||
mgr.prepareSecondaryStorageStore(secStoreUrl);
|
||||
mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
|
||||
|
||||
ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
|
||||
if (morSecDs == null) {
|
||||
@ -3426,12 +3430,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
}
|
||||
|
||||
// Ensure secondary storage mounted on target host
|
||||
String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
|
||||
Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
|
||||
String secStoreUrl = secStoreUrlAndId.first();
|
||||
Long secStoreId = secStoreUrlAndId.second();
|
||||
if (secStoreUrl == null) {
|
||||
String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
|
||||
throw new Exception(msg);
|
||||
}
|
||||
mgr.prepareSecondaryStorageStore(secStoreUrl);
|
||||
mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
|
||||
ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnSpecificHost(secStoreUrl, tgtHyperHost);
|
||||
if (morSecDs == null) {
|
||||
String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
|
||||
@ -5267,8 +5273,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
|
||||
value = (String)params.get("scripts.timeout");
|
||||
int timeout = NumbersUtil.parseInt(value, 1440) * 1000;
|
||||
_storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null);
|
||||
storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor);
|
||||
_storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null, (String)params.get("nfsVersion"));
|
||||
storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor, (String)params.get("nfsVersion"));
|
||||
|
||||
_vrResource = new VirtualRoutingResource(this);
|
||||
if (!_vrResource.configure(name, params)) {
|
||||
|
||||
@ -102,7 +102,7 @@ public class PremiumSecondaryStorageResource extends NfsSecondaryStorageResource
|
||||
VmwareSecondaryStorageContextFactory.initFactoryEnvironment();
|
||||
}
|
||||
|
||||
registerHandler(Hypervisor.HypervisorType.VMware, new VmwareSecondaryStorageResourceHandler(this));
|
||||
registerHandler(Hypervisor.HypervisorType.VMware, new VmwareSecondaryStorageResourceHandler(this, (String)params.get("nfsVersion")));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,13 +66,13 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
|
||||
* private Map<String, HostMO> _activeHosts = new HashMap<String, HostMO>();
|
||||
*/
|
||||
|
||||
public VmwareSecondaryStorageResourceHandler(PremiumSecondaryStorageResource resource) {
|
||||
public VmwareSecondaryStorageResourceHandler(PremiumSecondaryStorageResource resource, String nfsVersion) {
|
||||
_resource = resource;
|
||||
_storageMgr = new VmwareStorageManagerImpl(this);
|
||||
_storageMgr = new VmwareStorageManagerImpl(this, nfsVersion);
|
||||
_gson = GsonHelper.getGsonLogger();
|
||||
|
||||
VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor(this, true, this, resource.getTimeout(), null, null, _resource);
|
||||
VmwareStorageSubsystemCommandHandler vmwareStorageSubsystemCommandHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor);
|
||||
VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor(this, true, this, resource.getTimeout(), null, null, _resource, nfsVersion);
|
||||
VmwareStorageSubsystemCommandHandler vmwareStorageSubsystemCommandHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor, nfsVersion);
|
||||
vmwareStorageSubsystemCommandHandler.setStorageResource(_resource);
|
||||
vmwareStorageSubsystemCommandHandler.setStorageManager(_storageMgr);
|
||||
storageSubsystemHandler = vmwareStorageSubsystemCommandHandler;
|
||||
@ -304,7 +304,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMountPoint(String storageUrl) {
|
||||
return _resource.getRootDir(storageUrl);
|
||||
public String getMountPoint(String storageUrl, String nfsVersion) {
|
||||
return _resource.getRootDir(storageUrl, nfsVersion);
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,6 +109,7 @@ import com.cloud.vm.VirtualMachine.PowerState;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
|
||||
public class VmwareStorageProcessor implements StorageProcessor {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class);
|
||||
private static final int DEFAULT_NFS_PORT = 2049;
|
||||
|
||||
@ -120,9 +121,10 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
protected Integer _shutdownWaitMs;
|
||||
private final Gson _gson;
|
||||
private final StorageLayer _storage = new JavaStorageLayer();
|
||||
private String _nfsVersion;
|
||||
|
||||
public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFlag, VmwareStorageMount mountService, Integer timeout, VmwareResource resource,
|
||||
Integer shutdownWaitMs, PremiumSecondaryStorageResource storageResource) {
|
||||
Integer shutdownWaitMs, PremiumSecondaryStorageResource storageResource, String nfsVersion) {
|
||||
this.hostService = hostService;
|
||||
_fullCloneFlag = fullCloneFlag;
|
||||
this.mountService = mountService;
|
||||
@ -130,6 +132,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
this.resource = resource;
|
||||
_shutdownWaitMs = shutdownWaitMs;
|
||||
_gson = GsonHelper.getGsonLogger();
|
||||
_nfsVersion = nfsVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -155,12 +158,12 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
|
||||
private VirtualMachineMO copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
|
||||
String templatePathAtSecondaryStorage, String templateName, String templateUuid, boolean createSnapshot) throws Exception {
|
||||
String templatePathAtSecondaryStorage, String templateName, String templateUuid, boolean createSnapshot, String nfsVersion) throws Exception {
|
||||
|
||||
s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
|
||||
templatePathAtSecondaryStorage + ", templateName: " + templateName);
|
||||
|
||||
String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl);
|
||||
String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, nfsVersion);
|
||||
s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
|
||||
|
||||
String srcOVAFileName =
|
||||
@ -316,7 +319,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
|
||||
if (managed) {
|
||||
VirtualMachineMO vmMo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
|
||||
managedStoragePoolRootVolumeName, false);
|
||||
managedStoragePoolRootVolumeName, false, _nfsVersion);
|
||||
|
||||
vmMo.unregisterVm();
|
||||
|
||||
@ -333,7 +336,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
else {
|
||||
copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
|
||||
templateUuidName, true);
|
||||
templateUuidName, true, _nfsVersion);
|
||||
}
|
||||
} else {
|
||||
s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage");
|
||||
@ -518,7 +521,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private Pair<String, String> copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl, long wait) throws Exception {
|
||||
private Pair<String, String> copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl, long wait, String nfsVersion) throws Exception {
|
||||
|
||||
String volumeFolder = null;
|
||||
String volumeName = null;
|
||||
@ -533,13 +536,13 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
|
||||
String newVolume = VmwareHelper.getVCenterSafeUuid();
|
||||
restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait);
|
||||
restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait, nfsVersion);
|
||||
|
||||
return new Pair<String, String>(volumeFolder, newVolume);
|
||||
}
|
||||
|
||||
private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl) throws Exception {
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
|
||||
private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl, String nfsVersion) throws Exception {
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String volumeMountRoot = secondaryMountPoint + File.separator + volumeDir;
|
||||
|
||||
return deleteDir(volumeMountRoot);
|
||||
@ -578,8 +581,8 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
Pair<String, String> result = copyVolumeFromSecStorage(hyperHost, srcVolume.getPath(), new DatastoreMO(context, morDatastore), srcStore.getUrl(), (long)cmd.getWait() * 1000);
|
||||
deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl());
|
||||
Pair<String, String> result = copyVolumeFromSecStorage(hyperHost, srcVolume.getPath(), new DatastoreMO(context, morDatastore), srcStore.getUrl(), (long)cmd.getWait() * 1000, _nfsVersion);
|
||||
deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl(), _nfsVersion);
|
||||
VolumeObjectTO newVolume = new VolumeObjectTO();
|
||||
newVolume.setPath(result.second());
|
||||
return new CopyCmdAnswer(newVolume);
|
||||
@ -636,7 +639,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
|
||||
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
|
||||
|
||||
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1));
|
||||
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1), _nfsVersion);
|
||||
return new Pair<String, String>(destVolumePath, exportName);
|
||||
|
||||
} finally {
|
||||
@ -720,9 +723,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
|
||||
private Ternary<String, Long, Long> createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName,
|
||||
String secStorageUrl, String volumePath, String workerVmName) throws Exception {
|
||||
String secStorageUrl, String volumePath, String workerVmName, String nfsVersion) throws Exception {
|
||||
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
synchronized (installPath.intern()) {
|
||||
Script command = new Script(false, "mkdir", _timeout, s_logger);
|
||||
@ -838,7 +841,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
|
||||
Ternary<String, Long, Long> result =
|
||||
createTemplateFromVolume(vmMo, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath,
|
||||
hostService.getWorkerName(context, cmd, 0));
|
||||
hostService.getWorkerName(context, cmd, 0), _nfsVersion);
|
||||
|
||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||
newTemplate.setPath(result.first());
|
||||
@ -885,7 +888,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
|
||||
private Ternary<String, Long, Long> createTemplateFromSnapshot(String installPath, String templateUniqueName, String secStorageUrl, String snapshotPath,
|
||||
Long templateId, long wait) throws Exception {
|
||||
Long templateId, long wait, String nfsVersion) throws Exception {
|
||||
//Snapshot path is decoded in this form: /snapshots/account/volumeId/uuid/uuid
|
||||
String backupSSUuid;
|
||||
String snapshotFolder;
|
||||
@ -899,7 +902,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
snapshotFolder = StringUtils.join(tokens, File.separator, 0, tokens.length - 1);
|
||||
}
|
||||
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String installFullPath = secondaryMountPoint + "/" + installPath;
|
||||
String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova"; //Note: volss for tmpl
|
||||
String snapshotRoot = secondaryMountPoint + "/" + snapshotFolder;
|
||||
@ -1029,7 +1032,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
|
||||
NfsTO nfsSvr = (NfsTO)imageStore;
|
||||
Ternary<String, Long, Long> result = createTemplateFromSnapshot(template.getPath(), uniqeName, nfsSvr.getUrl(), snapshot.getPath(), template.getId(), (long)cmd.getWait() * 1000);
|
||||
Ternary<String, Long, Long> result = createTemplateFromSnapshot(template.getPath(), uniqeName, nfsSvr.getUrl(), snapshot.getPath(), template.getId(), (long)cmd.getWait() * 1000, _nfsVersion);
|
||||
|
||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||
newTemplate.setPath(result.first());
|
||||
@ -1052,9 +1055,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
|
||||
// return Pair<String(divice bus name), String[](disk chain)>
|
||||
private Pair<String, String[]> exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir,
|
||||
String exportName, String workerVmName) throws Exception {
|
||||
String exportName, String workerVmName, String nfsVersion) throws Exception {
|
||||
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
|
||||
String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
|
||||
|
||||
synchronized (exportPath.intern()) {
|
||||
@ -1096,10 +1099,10 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
|
||||
// Ternary<String(backup uuid in secondary storage), String(device bus name), String[](original disk chain in the snapshot)>
|
||||
private Ternary<String, String, String[]> backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, String installPath, String volumePath, String snapshotUuid,
|
||||
String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception {
|
||||
String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName, String nfsVersion) throws Exception {
|
||||
|
||||
String backupUuid = UUID.randomUUID().toString();
|
||||
Pair<String, String[]> snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName);
|
||||
Pair<String, String[]> snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion);
|
||||
return new Ternary<String, String, String[]>(backupUuid, snapshotInfo.first(), snapshotInfo.second());
|
||||
}
|
||||
|
||||
@ -1174,7 +1177,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
|
||||
backupResult =
|
||||
backupSnapshotToSecondaryStorage(vmMo, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl,
|
||||
prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1));
|
||||
prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1), _nfsVersion);
|
||||
snapshotBackupUuid = backupResult.first();
|
||||
|
||||
success = (snapshotBackupUuid != null);
|
||||
@ -1186,7 +1189,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
|
||||
// Get snapshot physical size
|
||||
long physicalSize = 0l;
|
||||
String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl);
|
||||
String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion);
|
||||
String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid;
|
||||
File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
|
||||
if(files != null) {
|
||||
@ -2144,9 +2147,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
|
||||
private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir,
|
||||
String backupName, long wait) throws Exception {
|
||||
String backupName, long wait, String nfsVersion) throws Exception {
|
||||
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
|
||||
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
|
||||
String srcOVAFileName = null;
|
||||
String srcOVFFileName = null;
|
||||
|
||||
@ -2248,7 +2251,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ovf", "");
|
||||
}
|
||||
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
|
||||
restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000);
|
||||
restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000, _nfsVersion);
|
||||
|
||||
VolumeObjectTO newVol = new VolumeObjectTO();
|
||||
newVol.setPath(newVolumeName);
|
||||
|
||||
@ -21,7 +21,6 @@ package com.cloud.storage.resource;
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
|
||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||
import org.apache.cloudstack.storage.command.DeleteCommand;
|
||||
@ -40,9 +39,11 @@ import com.cloud.hypervisor.vmware.manager.VmwareStorageManager;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
|
||||
public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemCommandHandlerBase {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(VmwareStorageSubsystemCommandHandler.class);
|
||||
private VmwareStorageManager storageManager;
|
||||
private PremiumSecondaryStorageResource storageResource;
|
||||
private String _nfsVersion;
|
||||
|
||||
public PremiumSecondaryStorageResource getStorageResource() {
|
||||
return storageResource;
|
||||
@ -60,8 +61,9 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
|
||||
this.storageManager = storageManager;
|
||||
}
|
||||
|
||||
public VmwareStorageSubsystemCommandHandler(StorageProcessor processor) {
|
||||
public VmwareStorageSubsystemCommandHandler(StorageProcessor processor, String nfsVersion) {
|
||||
super(processor);
|
||||
this._nfsVersion = nfsVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -82,7 +84,7 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
|
||||
//need to take extra processing for vmware, such as packing to ova, before sending to S3
|
||||
if (srcData.getObjectType() == DataObjectType.VOLUME) {
|
||||
NfsTO cacheStore = (NfsTO)srcDataStore;
|
||||
String parentPath = storageResource.getRootDir(cacheStore.getUrl());
|
||||
String parentPath = storageResource.getRootDir(cacheStore.getUrl(), _nfsVersion);
|
||||
VolumeObjectTO vol = (VolumeObjectTO)srcData;
|
||||
String path = vol.getPath();
|
||||
int index = path.lastIndexOf(File.separator);
|
||||
@ -95,7 +97,7 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
|
||||
} else if (srcData.getObjectType() == DataObjectType.SNAPSHOT) {
|
||||
// pack ova first
|
||||
// sync snapshot from NFS cache to S3 in NFS migration to S3 case
|
||||
String parentPath = storageResource.getRootDir(srcDataStore.getUrl());
|
||||
String parentPath = storageResource.getRootDir(srcDataStore.getUrl(), _nfsVersion);
|
||||
SnapshotObjectTO snap = (SnapshotObjectTO)srcData;
|
||||
String path = snap.getPath();
|
||||
int index = path.lastIndexOf(File.separator);
|
||||
@ -138,7 +140,7 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
|
||||
return answer;
|
||||
}
|
||||
NfsTO cacheStore = (NfsTO)cmd.getCacheTO().getDataStore();
|
||||
String parentPath = storageResource.getRootDir(cacheStore.getUrl());
|
||||
String parentPath = storageResource.getRootDir(cacheStore.getUrl(), _nfsVersion);
|
||||
SnapshotObjectTO newSnapshot = (SnapshotObjectTO)answer.getNewData();
|
||||
String path = newSnapshot.getPath();
|
||||
int index = path.lastIndexOf(File.separator);
|
||||
|
||||
@ -25,18 +25,19 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.user.User;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
@ -48,12 +49,13 @@ import org.springframework.core.type.filter.TypeFilter;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||
import org.apache.cloudstack.test.utils.SpringUtils;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
@ -86,6 +88,7 @@ import com.cloud.org.Cluster.ClusterType;
|
||||
import com.cloud.org.Managed.ManagedState;
|
||||
import com.cloud.secstorage.CommandExecLogDao;
|
||||
import com.cloud.server.ConfigurationServer;
|
||||
import com.cloud.storage.ImageStoreDetailsUtil;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountService;
|
||||
@ -98,6 +101,7 @@ import com.cloud.vm.dao.UserVmDao;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
||||
@PrepareForTest({ComponentContext.class, ApplicationContext.class})
|
||||
public class VmwareDatacenterApiUnitTest {
|
||||
|
||||
@Inject
|
||||
@ -155,10 +159,6 @@ public class VmwareDatacenterApiUnitTest {
|
||||
@Mock
|
||||
private static RemoveVmwareDcCmd removeCmd;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws ConfigurationException {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void testSetUp() {
|
||||
Mockito.when(_configDao.isPremium()).thenReturn(true);
|
||||
@ -431,6 +431,22 @@ public class VmwareDatacenterApiUnitTest {
|
||||
return Mockito.mock(DataStoreManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ImageStoreDetailsUtil imageStoreDetailsUtil() {
|
||||
return Mockito.mock(ImageStoreDetailsUtil.class);
|
||||
}
|
||||
|
||||
//Mocks for ImageStoreDetailsUtil
|
||||
@Bean
|
||||
public ImageStoreDao imageStoreDao() {
|
||||
return Mockito.mock(ImageStoreDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ImageStoreDetailsDao imageStoreDetailsDao() {
|
||||
return Mockito.mock(ImageStoreDetailsDao.class);
|
||||
}
|
||||
|
||||
public static class Library implements TypeFilter {
|
||||
|
||||
@Override
|
||||
|
||||
@ -36,7 +36,6 @@ import javax.inject.Inject;
|
||||
import org.apache.cloudstack.utils.usage.UsageUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
||||
@ -90,6 +89,7 @@ import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.ImageStoreDetailsUtil;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StorageStats;
|
||||
import com.cloud.storage.VolumeStats;
|
||||
@ -198,6 +198,8 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
private ServiceOfferingDao _serviceOfferingDao;
|
||||
@Inject
|
||||
private HostGpuGroupsDao _hostGpuGroupsDao;
|
||||
@Inject
|
||||
private ImageStoreDetailsUtil imageStoreDetailsUtil;
|
||||
|
||||
private ConcurrentHashMap<Long, HostStats> _hostStats = new ConcurrentHashMap<Long, HostStats>();
|
||||
private final ConcurrentHashMap<Long, VmStats> _VmStats = new ConcurrentHashMap<Long, VmStats>();
|
||||
@ -715,7 +717,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
continue;
|
||||
}
|
||||
|
||||
GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO());
|
||||
GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO(), imageStoreDetailsUtil.getNfsVersion(store.getId()));
|
||||
EndPoint ssAhost = _epSelector.select(store);
|
||||
if (ssAhost == null) {
|
||||
s_logger.debug("There is no secondary storage VM for secondary storage host " + store.getName());
|
||||
@ -762,6 +764,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
s_logger.error("Error trying to retrieve storage stats", t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AutoScaleMonitor extends ManagedContextRunnable {
|
||||
|
||||
67
server/src/com/cloud/storage/ImageStoreDetailsUtil.java
Executable file
67
server/src/com/cloud/storage/ImageStoreDetailsUtil.java
Executable 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.storage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||
|
||||
public class ImageStoreDetailsUtil {
|
||||
|
||||
@Inject
|
||||
protected ImageStoreDao imageStoreDao;
|
||||
@Inject
|
||||
protected ImageStoreDetailsDao imageStoreDetailsDao;
|
||||
|
||||
/**
|
||||
* Obtain NFS protocol version (if provided) for a store id.<br/>
|
||||
* It can be set by adding an entry in {@code image_store_details} table, providing {@code name=nfs.version} and {@code value=X} (e.g. 3)
|
||||
* @param storeId image store id
|
||||
* @return {@code null} if {@code nfs.version} is not found for storeId <br/>
|
||||
* {@code X} if {@code nfs.version} is found found for storeId
|
||||
*/
|
||||
public String getNfsVersion(long storeId) {
|
||||
String nfsVersion = null;
|
||||
if (imageStoreDetailsDao.getDetails(storeId) != null){
|
||||
Map<String, String> storeDetails = imageStoreDetailsDao.getDetails(storeId);
|
||||
if (storeDetails != null && storeDetails.containsKey("nfs.version")){
|
||||
nfsVersion = storeDetails.get("nfs.version");
|
||||
}
|
||||
}
|
||||
return nfsVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain NFS protocol version (if provided) for a store uuid.<br/>
|
||||
* It can be set by adding an entry in {@code image_store_details} table, providing {@code name=nfs.version} and {@code value=X} (e.g. 3)
|
||||
* @param storeId image store id
|
||||
* @return {@code null} if {@code nfs.version} is not found for storeUuid <br/>
|
||||
* {@code X} if {@code nfs.version} is found found for storeUuid
|
||||
*/
|
||||
public String getNfsVersionByUuid(String storeUuid){
|
||||
ImageStoreVO imageStore = imageStoreDao.findByUuid(storeUuid);
|
||||
if (imageStore != null){
|
||||
return getNfsVersion(imageStore.getId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
95
server/test/com/cloud/storage/ImageStoreDetailsUtilTest.java
Executable file
95
server/test/com/cloud/storage/ImageStoreDetailsUtilTest.java
Executable file
@ -0,0 +1,95 @@
|
||||
// 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.storage;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ImageStoreDetailsUtilTest {
|
||||
|
||||
private final static long STORE_ID = 1l;
|
||||
private final static String STORE_UUID = "aaaa-aaaa-aaaa-aaaa";
|
||||
private final static String NFS_VERSION = "3";
|
||||
|
||||
ImageStoreDetailsUtil imageStoreDetailsUtil = new ImageStoreDetailsUtil();
|
||||
|
||||
ImageStoreDao imgStoreDao = mock(ImageStoreDao.class);
|
||||
ImageStoreDetailsDao imgStoreDetailsDao = mock(ImageStoreDetailsDao.class);
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
Map<String, String> imgStoreDetails = new HashMap<String, String>();
|
||||
imgStoreDetails.put("nfs.version", NFS_VERSION);
|
||||
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
||||
|
||||
ImageStoreVO imgStoreVO = mock(ImageStoreVO.class);
|
||||
when(imgStoreVO.getId()).thenReturn(Long.valueOf(STORE_ID));
|
||||
when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(imgStoreVO);
|
||||
|
||||
imageStoreDetailsUtil.imageStoreDao = imgStoreDao;
|
||||
imageStoreDetailsUtil.imageStoreDetailsDao = imgStoreDetailsDao;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNfsVersion(){
|
||||
String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
|
||||
assertEquals(NFS_VERSION, nfsVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNfsVersionNotFound(){
|
||||
Map<String, String> imgStoreDetails = new HashMap<String, String>();
|
||||
imgStoreDetails.put("other.prop", "propValue");
|
||||
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
||||
|
||||
String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
|
||||
assertNull(nfsVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNfsVersionNoDetails(){
|
||||
Map<String, String> imgStoreDetails = new HashMap<String, String>();
|
||||
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
||||
|
||||
String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
|
||||
assertNull(nfsVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNfsVersionByUuid(){
|
||||
String nfsVersion = imageStoreDetailsUtil.getNfsVersionByUuid(STORE_UUID);
|
||||
assertEquals(NFS_VERSION, nfsVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNfsVersionByUuidNoImgStore(){
|
||||
when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(null);
|
||||
String nfsVersion = imageStoreDetailsUtil.getNfsVersionByUuid(STORE_UUID);
|
||||
assertNull(nfsVersion);
|
||||
}
|
||||
}
|
||||
@ -101,6 +101,7 @@ import com.cloud.resource.ServerResource;
|
||||
import com.cloud.resource.UnableDeleteHostException;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.ImageStoreDetailsUtil;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.UploadVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
@ -239,6 +240,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
TemplateDataStoreDao _tmplStoreDao;
|
||||
@Inject
|
||||
VolumeDataStoreDao _volumeStoreDao;
|
||||
@Inject
|
||||
private ImageStoreDetailsUtil imageStoreDetailsUtil;
|
||||
private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
|
||||
private int _secStorageVmMtuSize;
|
||||
|
||||
@ -310,6 +313,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs);
|
||||
}
|
||||
|
||||
setupCmd.setNfsVersion(imageStoreDetailsUtil.getNfsVersion(ssStore.getId()));
|
||||
|
||||
//template/volume file upload key
|
||||
String postUploadKey = _configDao.getValue(Config.SSVMPSK.key());
|
||||
setupCmd.setPostUploadKey(postUploadKey);
|
||||
@ -1046,7 +1051,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
|
||||
@Override
|
||||
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
|
||||
|
||||
SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId());
|
||||
Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
|
||||
vm.setDetails(details);
|
||||
@ -1131,6 +1135,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
if (dc.getDns2() != null) {
|
||||
buf.append(" dns2=").append(dc.getDns2());
|
||||
}
|
||||
String nfsVersion = imageStoreDetailsUtil != null ? imageStoreDetailsUtil.getNfsVersion(secStore.getId()) : null;
|
||||
buf.append(" nfsVersion=").append(nfsVersion);
|
||||
|
||||
String bootArgs = buf.toString();
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
@ -1430,4 +1436,5 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
||||
public void setSecondaryStorageVmAllocators(List<SecondaryStorageVmAllocator> ssVmAllocators) {
|
||||
_ssVmAllocators = ssVmAllocators;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -53,10 +53,10 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public String getRootDir(String secUrl) {
|
||||
synchronized public String getRootDir(String secUrl, String nfsVersion) {
|
||||
try {
|
||||
URI uri = new URI(secUrl);
|
||||
String dir = mountUri(uri);
|
||||
String dir = mountUri(uri, nfsVersion);
|
||||
return _parent + "/" + dir;
|
||||
} catch (Exception e) {
|
||||
String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
|
||||
@ -66,14 +66,14 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mount(String localRootPath, String remoteDevice, URI uri) {
|
||||
protected void mount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) {
|
||||
ensureLocalRootPathExists(localRootPath, uri);
|
||||
|
||||
if (mountExists(localRootPath, uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
attemptMount(localRootPath, remoteDevice, uri);
|
||||
attemptMount(localRootPath, remoteDevice, uri, nfsVersion);
|
||||
|
||||
// Change permissions for the mountpoint - seems to bypass authentication
|
||||
Script script = new Script(true, "chmod", _timeout, s_logger);
|
||||
|
||||
@ -72,7 +72,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRootDir(String url) {
|
||||
public String getRootDir(String url, String nfsVersion) {
|
||||
return getRootDir();
|
||||
|
||||
}
|
||||
|
||||
@ -52,6 +52,7 @@ import com.cloud.storage.template.TemplateConstants;
|
||||
import com.cloud.utils.EncryptionUtil;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
@ -65,6 +66,7 @@ import io.netty.handler.codec.http.HttpRequestDecoder;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
|
||||
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
|
||||
import org.apache.cloudstack.storage.template.UploadEntity;
|
||||
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
|
||||
@ -161,6 +163,7 @@ import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.script.OutputInterpreter;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.cloud.vm.SecondaryStorageVm;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
|
||||
@ -205,6 +208,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
private String _storageIp;
|
||||
private String _storageNetmask;
|
||||
private String _storageGateway;
|
||||
private String _nfsVersion;
|
||||
private final List<String> nfsIps = new ArrayList<String>();
|
||||
protected String _parent = "/mnt/SecStorage";
|
||||
final private String _tmpltpp = "template.properties";
|
||||
@ -352,7 +356,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
final String storagePath = destImageStore.getUrl();
|
||||
final String destPath = destData.getPath();
|
||||
try {
|
||||
String downloadPath = determineStorageTemplatePath(storagePath, destPath);
|
||||
String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion);
|
||||
final File downloadDirectory = _storage.getFile(downloadPath);
|
||||
|
||||
if (downloadDirectory.exists()) {
|
||||
@ -379,7 +383,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
|
||||
try {
|
||||
|
||||
String downloadPath = determineStorageTemplatePath(storagePath, destPath);
|
||||
String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion);
|
||||
final File downloadDirectory = _storage.getFile(downloadPath);
|
||||
|
||||
if (downloadDirectory.exists()) {
|
||||
@ -412,7 +416,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
|
||||
protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData,
|
||||
NfsTO destDataStore) {
|
||||
String srcMountPoint = getRootDir(srcDataStore.getUrl());
|
||||
String srcMountPoint = getRootDir(srcDataStore.getUrl(), _nfsVersion);
|
||||
String snapshotPath = srcData.getPath();
|
||||
int index = snapshotPath.lastIndexOf("/");
|
||||
String snapshotName = snapshotPath.substring(index + 1);
|
||||
@ -422,7 +426,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
snapshotPath = snapshotPath.substring(0, index);
|
||||
|
||||
snapshotPath = srcMountPoint + File.separator + snapshotPath;
|
||||
String destMountPoint = getRootDir(destDataStore.getUrl());
|
||||
String destMountPoint = getRootDir(destDataStore.getUrl(), _nfsVersion);
|
||||
String destPath = destMountPoint + File.separator + destData.getPath();
|
||||
|
||||
String errMsg = null;
|
||||
@ -480,8 +484,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
if (srcData.getHypervisorType() == HypervisorType.XenServer) {
|
||||
return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
|
||||
} else if (srcData.getHypervisorType() == HypervisorType.KVM) {
|
||||
File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl());
|
||||
File destFile = getFile(destData.getPath(), destDataStore.getUrl());
|
||||
File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl(), _nfsVersion);
|
||||
File destFile = getFile(destData.getPath(), destDataStore.getUrl(), _nfsVersion);
|
||||
|
||||
VolumeObjectTO volumeObjectTO = srcData.getVolume();
|
||||
ImageFormat srcFormat = null;
|
||||
@ -565,8 +569,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
return new CopyCmdAnswer("");
|
||||
}
|
||||
|
||||
protected File getFile(String path, String nfsPath) {
|
||||
String filePath = getRootDir(nfsPath) + File.separator + path;
|
||||
protected File getFile(String path, String nfsPath, String nfsVersion) {
|
||||
String filePath = getRootDir(nfsPath, nfsVersion) + File.separator + path;
|
||||
File f = new File(filePath);
|
||||
if (!f.exists()) {
|
||||
_storage.mkdirs(filePath);
|
||||
@ -598,7 +602,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
}
|
||||
s_logger.debug("starting copy template to swift");
|
||||
DataTO newTemplate = answer.getNewData();
|
||||
File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl());
|
||||
File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl(), _nfsVersion);
|
||||
SwiftTO swift = (SwiftTO)destDataStore;
|
||||
String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId());
|
||||
String swiftPath = SwiftUtil.putObject(swift, templateFile, containterName, templateFile.getName());
|
||||
@ -705,8 +709,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
|
||||
}
|
||||
|
||||
private String determineStorageTemplatePath(final String storagePath, String dataPath) {
|
||||
return join(asList(getRootDir(storagePath), dataPath), File.separator);
|
||||
private String determineStorageTemplatePath(final String storagePath, String dataPath, String nfsVersion) {
|
||||
return join(asList(getRootDir(storagePath, nfsVersion), dataPath), File.separator);
|
||||
}
|
||||
|
||||
protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
|
||||
@ -720,7 +724,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
throw new CloudRuntimeException("Failed to get url: " + url);
|
||||
}
|
||||
|
||||
String nfsMountPath = getRootDir(nfs.getUrl());
|
||||
String nfsMountPath = getRootDir(nfs.getUrl(), _nfsVersion);
|
||||
|
||||
String filePath = nfsMountPath + File.separator + path;
|
||||
File directory = new File(filePath);
|
||||
@ -885,7 +889,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
final S3TO s3 = (S3TO)destDataStore;
|
||||
|
||||
try {
|
||||
final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath());
|
||||
final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath(), _nfsVersion);
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3.");
|
||||
@ -1098,7 +1102,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
if (dstore instanceof NfsTO) {
|
||||
NfsTO nfs = (NfsTO)dstore;
|
||||
String relativeSnapshotPath = cmd.getDirectory();
|
||||
String parent = getRootDir(nfs.getUrl());
|
||||
String parent = getRootDir(nfs.getUrl(), _nfsVersion);
|
||||
|
||||
if (relativeSnapshotPath.startsWith(File.separator)) {
|
||||
relativeSnapshotPath = relativeSnapshotPath.substring(1);
|
||||
@ -1176,7 +1180,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
return new Answer(cmd, false, "can't handle non nfs data store");
|
||||
}
|
||||
NfsTO nfsStore = (NfsTO)store;
|
||||
String parent = getRootDir(nfsStore.getUrl());
|
||||
String parent = getRootDir(nfsStore.getUrl(), _nfsVersion);
|
||||
|
||||
if (relativeTemplatePath.startsWith(File.separator)) {
|
||||
relativeTemplatePath = relativeTemplatePath.substring(1);
|
||||
@ -1310,7 +1314,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
String nfsHostIp = getUriHostIp(uri);
|
||||
|
||||
addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
|
||||
String dir = mountUri(uri);
|
||||
|
||||
String dir = mountUri(uri, cmd.getNfsVersion());
|
||||
|
||||
configCerts(cmd.getCerts());
|
||||
|
||||
@ -1386,7 +1391,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
DataStoreTO dstore = obj.getDataStore();
|
||||
if (dstore instanceof NfsTO) {
|
||||
NfsTO nfs = (NfsTO)dstore;
|
||||
String parent = getRootDir(nfs.getUrl());
|
||||
String parent = getRootDir(nfs.getUrl(), _nfsVersion);
|
||||
if (!parent.endsWith(File.separator)) {
|
||||
parent += File.separator;
|
||||
}
|
||||
@ -1557,7 +1562,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
if (store instanceof NfsTO) {
|
||||
NfsTO nfs = (NfsTO)store;
|
||||
String secUrl = nfs.getUrl();
|
||||
String root = getRootDir(secUrl);
|
||||
String root = getRootDir(secUrl, cmd.getNfsVersion());
|
||||
Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
|
||||
return new ListTemplateAnswer(secUrl, templateInfos);
|
||||
} else if (store instanceof SwiftTO) {
|
||||
@ -1579,7 +1584,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
}
|
||||
DataStoreTO store = cmd.getDataStore();
|
||||
if (store instanceof NfsTO) {
|
||||
String root = getRootDir(cmd.getSecUrl());
|
||||
String root = getRootDir(cmd.getSecUrl(), _nfsVersion);
|
||||
Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
|
||||
return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
|
||||
} else if (store instanceof S3TO) {
|
||||
@ -1714,7 +1719,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
return new GetStorageStatsAnswer(cmd, infinity, 0L);
|
||||
}
|
||||
|
||||
String rootDir = getRootDir(((NfsTO)store).getUrl());
|
||||
String rootDir = getRootDir(((NfsTO)store).getUrl(), cmd.getNfsVersion());
|
||||
final long usedSize = getUsedSize(rootDir);
|
||||
final long totalSize = getTotalSize(rootDir);
|
||||
if (usedSize == -1 || totalSize == -1) {
|
||||
@ -1748,7 +1753,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
if (dstore instanceof NfsTO) {
|
||||
NfsTO nfs = (NfsTO)dstore;
|
||||
String relativeTemplatePath = obj.getPath();
|
||||
String parent = getRootDir(nfs.getUrl());
|
||||
String parent = getRootDir(nfs.getUrl(), _nfsVersion);
|
||||
|
||||
if (relativeTemplatePath.startsWith(File.separator)) {
|
||||
relativeTemplatePath = relativeTemplatePath.substring(1);
|
||||
@ -1852,7 +1857,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
if (dstore instanceof NfsTO) {
|
||||
NfsTO nfs = (NfsTO)dstore;
|
||||
String relativeVolumePath = obj.getPath();
|
||||
String parent = getRootDir(nfs.getUrl());
|
||||
String parent = getRootDir(nfs.getUrl(), _nfsVersion);
|
||||
|
||||
if (relativeVolumePath.startsWith(File.separator)) {
|
||||
relativeVolumePath = relativeVolumePath.substring(1);
|
||||
@ -1954,13 +1959,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public String getRootDir(String secUrl) {
|
||||
synchronized public String getRootDir(String secUrl, String nfsVersion) {
|
||||
if (!_inSystemVM) {
|
||||
return _parent;
|
||||
}
|
||||
try {
|
||||
URI uri = new URI(secUrl);
|
||||
String dir = mountUri(uri);
|
||||
String dir = mountUri(uri, nfsVersion);
|
||||
return _parent + "/" + dir;
|
||||
} catch (Exception e) {
|
||||
String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
|
||||
@ -2117,6 +2122,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
startAdditionalServices();
|
||||
_params.put("install.numthreads", "50");
|
||||
_params.put("secondary.storage.vm", "true");
|
||||
_nfsVersion = (String)params.get("nfsVersion");
|
||||
}
|
||||
|
||||
try {
|
||||
@ -2291,10 +2297,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
* @param uri
|
||||
* crresponding to the remote device. Will throw for unsupported
|
||||
* scheme.
|
||||
* @param imgStoreId
|
||||
* @return name of folder in _parent that device was mounted.
|
||||
* @throws UnknownHostException
|
||||
*/
|
||||
protected String mountUri(URI uri) throws UnknownHostException {
|
||||
protected String mountUri(URI uri, String nfsVersion) throws UnknownHostException {
|
||||
String uriHostIp = getUriHostIp(uri);
|
||||
String nfsPath = uriHostIp + ":" + uri.getPath();
|
||||
|
||||
@ -2312,7 +2319,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
s_logger.debug("Mounting device with nfs-style path of " + remoteDevice);
|
||||
}
|
||||
|
||||
mount(localRootPath, remoteDevice, uri);
|
||||
mount(localRootPath, remoteDevice, uri, nfsVersion);
|
||||
|
||||
return dir;
|
||||
}
|
||||
@ -2340,15 +2347,15 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
s_logger.debug("Successfully umounted " + localRootPath);
|
||||
}
|
||||
|
||||
protected void mount(String localRootPath, String remoteDevice, URI uri) {
|
||||
s_logger.debug("mount " + uri.toString() + " on " + localRootPath);
|
||||
protected void mount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) {
|
||||
s_logger.debug("mount " + uri.toString() + " on " + localRootPath + ((nfsVersion != null) ? " nfsVersion="+nfsVersion : ""));
|
||||
ensureLocalRootPathExists(localRootPath, uri);
|
||||
|
||||
if (mountExists(localRootPath, uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
attemptMount(localRootPath, remoteDevice, uri);
|
||||
attemptMount(localRootPath, remoteDevice, uri, nfsVersion);
|
||||
|
||||
// XXX: Adding the check for creation of snapshots dir here. Might have
|
||||
// to move it somewhere more logical later.
|
||||
@ -2356,9 +2363,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
checkForVolumesDir(localRootPath);
|
||||
}
|
||||
|
||||
protected void attemptMount(String localRootPath, String remoteDevice, URI uri) {
|
||||
protected void attemptMount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) {
|
||||
String result;
|
||||
s_logger.debug("Make cmdline call to mount " + remoteDevice + " at " + localRootPath + " based on uri " + uri);
|
||||
s_logger.debug("Make cmdline call to mount " + remoteDevice + " at " + localRootPath + " based on uri " + uri
|
||||
+ ((nfsVersion != null) ? " nfsVersion=" + nfsVersion : ""));
|
||||
Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
|
||||
|
||||
String scheme = uri.getScheme().toLowerCase();
|
||||
@ -2370,7 +2378,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
command.add("-o", "resvport");
|
||||
}
|
||||
if (_inSystemVM) {
|
||||
command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
|
||||
command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0" + ((nfsVersion != null) ? ",vers=" + nfsVersion : ""));
|
||||
}
|
||||
} else if (scheme.equals("cifs")) {
|
||||
String extraOpts = parseCifsMountOptions(uri);
|
||||
@ -2647,7 +2655,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
//relative path with out ssvm mount info.
|
||||
uploadEntity.setTemplatePath(absolutePath);
|
||||
String dataStoreUrl = cmd.getDataTo();
|
||||
String installPathPrefix = this.getRootDir(dataStoreUrl) + File.separator + absolutePath;
|
||||
String installPathPrefix = this.getRootDir(dataStoreUrl, cmd.getNfsVersion()) + File.separator + absolutePath;
|
||||
uploadEntity.setInstallPathPrefix(installPathPrefix);
|
||||
uploadEntity.setHvm(cmd.getRequiresHvm());
|
||||
uploadEntity.setChksum(cmd.getChecksum());
|
||||
@ -2669,7 +2677,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
}
|
||||
|
||||
private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) {
|
||||
String rootDir = this.getRootDir(cmd.getDataTo()) + File.separator;
|
||||
String rootDir = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator;
|
||||
long accountId = cmd.getAccountId();
|
||||
|
||||
long accountTemplateDirSize = 0;
|
||||
@ -2716,7 +2724,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
|
||||
private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) {
|
||||
String uuid = cmd.getEntityUUID();
|
||||
String uploadPath = this.getRootDir(cmd.getDataTo()) + File.separator + cmd.getAbsolutePath();
|
||||
String uploadPath = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator + cmd.getAbsolutePath();
|
||||
return uploadEntityStateMap.containsKey(uuid) || new File(uploadPath).exists();
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,6 @@ import com.cloud.resource.ServerResource;
|
||||
*/
|
||||
public interface SecondaryStorageResource extends ServerResource {
|
||||
|
||||
String getRootDir(String cmd);
|
||||
String getRootDir(String cmd, String nfsVersion);
|
||||
|
||||
}
|
||||
|
||||
@ -89,6 +89,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
||||
StorageLayer _storage;
|
||||
public Map<String, Processor> _processors;
|
||||
|
||||
private String _nfsVersion;
|
||||
|
||||
public class Completion implements DownloadCompleteCallback {
|
||||
private final String jobId;
|
||||
|
||||
@ -708,7 +710,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
||||
String installPathPrefix = cmd.getInstallPath();
|
||||
// for NFS, we need to get mounted path
|
||||
if (dstore instanceof NfsTO) {
|
||||
installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl()) + File.separator + installPathPrefix;
|
||||
installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl(), _nfsVersion) + File.separator + installPathPrefix;
|
||||
}
|
||||
String user = null;
|
||||
String password = null;
|
||||
@ -982,6 +984,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
||||
String inSystemVM = (String)params.get("secondary.storage.vm");
|
||||
if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
|
||||
s_logger.info("DownloadManager: starting additional services since we are inside system vm");
|
||||
_nfsVersion = (String)params.get("nfsVersion");
|
||||
startAdditionalServices();
|
||||
blockOutgoingOnPrivate();
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ public class NfsSecondaryStorageResourceTest extends TestCase {
|
||||
if (!sampleMount.isEmpty()) {
|
||||
s_logger.info("functional test, mount " + sampleMount);
|
||||
URI realMntUri = new URI(sampleMount);
|
||||
String mntSubDir = resource.mountUri(realMntUri);
|
||||
String mntSubDir = resource.mountUri(realMntUri, null);
|
||||
s_logger.info("functional test, umount " + mntSubDir);
|
||||
resource.umount(resource.getMountingRoot() + mntSubDir, realMntUri);
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user