mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Refactor DownloadMonitorImpl code, move some functionalities to
TemplateServiceImpl and VolumeServiceImpl.
This commit is contained in:
parent
582a1f0539
commit
bb64672715
@ -18,16 +18,16 @@ package com.cloud.agent.api;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
|
||||
public class ModifyStoragePoolAnswer extends Answer {
|
||||
StoragePoolInfo poolInfo;
|
||||
Map<String, TemplateInfo> templateInfo;
|
||||
Map<String, TemplateProp> templateInfo;
|
||||
|
||||
protected ModifyStoragePoolAnswer() {
|
||||
}
|
||||
|
||||
public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, long capacityBytes, long availableBytes, Map<String, TemplateInfo> tInfo) {
|
||||
public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, long capacityBytes, long availableBytes, Map<String, TemplateProp> tInfo) {
|
||||
super(cmd);
|
||||
this.result = true;
|
||||
this.poolInfo = new StoragePoolInfo(null,
|
||||
@ -46,11 +46,11 @@ public class ModifyStoragePoolAnswer extends Answer {
|
||||
}
|
||||
|
||||
|
||||
public Map<String, TemplateInfo> getTemplateInfo() {
|
||||
public Map<String, TemplateProp> getTemplateInfo() {
|
||||
return templateInfo;
|
||||
}
|
||||
|
||||
public void setTemplateInfo(Map<String, TemplateInfo> templateInfo) {
|
||||
public void setTemplateInfo(Map<String, TemplateProp> templateInfo) {
|
||||
this.templateInfo = templateInfo;
|
||||
}
|
||||
|
||||
|
||||
@ -22,13 +22,13 @@ import java.util.Map;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
|
||||
|
||||
public class StartupStorageCommand extends StartupCommand {
|
||||
|
||||
String parent;
|
||||
Map<String, TemplateInfo> templateInfo;
|
||||
Map<String, TemplateProp> templateInfo;
|
||||
long totalSize;
|
||||
StoragePoolInfo poolInfo;
|
||||
Storage.StorageResourceType resourceType;
|
||||
@ -40,7 +40,7 @@ public class StartupStorageCommand extends StartupCommand {
|
||||
super(Host.Type.Storage);
|
||||
}
|
||||
|
||||
public StartupStorageCommand(String parent, StoragePoolType fsType, long totalSize, Map<String, TemplateInfo> info) {
|
||||
public StartupStorageCommand(String parent, StoragePoolType fsType, long totalSize, Map<String, TemplateProp> info) {
|
||||
super(Host.Type.Storage);
|
||||
this.parent = parent;
|
||||
this.totalSize = totalSize;
|
||||
@ -50,7 +50,7 @@ public class StartupStorageCommand extends StartupCommand {
|
||||
}
|
||||
|
||||
|
||||
public StartupStorageCommand(String parent, StoragePoolType fsType, Map<String, TemplateInfo> templateInfo, StoragePoolInfo poolInfo) {
|
||||
public StartupStorageCommand(String parent, StoragePoolType fsType, Map<String, TemplateProp> templateInfo, StoragePoolInfo poolInfo) {
|
||||
super(Host.Type.Storage);
|
||||
this.parent = parent;
|
||||
this.templateInfo = templateInfo;
|
||||
@ -79,11 +79,11 @@ public class StartupStorageCommand extends StartupCommand {
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
public Map<String, TemplateInfo> getTemplateInfo() {
|
||||
public Map<String, TemplateProp> getTemplateInfo() {
|
||||
return templateInfo;
|
||||
}
|
||||
|
||||
public void setTemplateInfo(Map<String, TemplateInfo> templateInfo) {
|
||||
public void setTemplateInfo(Map<String, TemplateProp> templateInfo) {
|
||||
this.templateInfo = templateInfo;
|
||||
}
|
||||
|
||||
|
||||
@ -19,27 +19,27 @@ package com.cloud.agent.api.storage;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
|
||||
public class ListTemplateAnswer extends Answer {
|
||||
private String secUrl;
|
||||
private Map<String, TemplateInfo> templateInfos;
|
||||
private Map<String, TemplateProp> templateInfos;
|
||||
|
||||
public ListTemplateAnswer() {
|
||||
|
||||
}
|
||||
|
||||
public ListTemplateAnswer(String secUrl, Map<String, TemplateInfo> templateInfos) {
|
||||
public ListTemplateAnswer(String secUrl, Map<String, TemplateProp> templateInfos) {
|
||||
super(null, true, "success");
|
||||
this.setSecUrl(secUrl);
|
||||
this.templateInfos = templateInfos;
|
||||
}
|
||||
|
||||
public Map<String, TemplateInfo> getTemplateInfo() {
|
||||
public Map<String, TemplateProp> getTemplateInfo() {
|
||||
return templateInfos;
|
||||
}
|
||||
|
||||
public void setTemplateInfo(Map<String, TemplateInfo> templateInfos) {
|
||||
public void setTemplateInfo(Map<String, TemplateProp> templateInfos) {
|
||||
this.templateInfos = templateInfos;
|
||||
}
|
||||
|
||||
|
||||
@ -19,27 +19,27 @@ package com.cloud.agent.api.storage;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
|
||||
public class ListVolumeAnswer extends Answer {
|
||||
private String secUrl;
|
||||
private Map<Long, TemplateInfo> templateInfos;
|
||||
private Map<Long, TemplateProp> templateInfos;
|
||||
|
||||
public ListVolumeAnswer() {
|
||||
|
||||
}
|
||||
|
||||
public ListVolumeAnswer(String secUrl, Map<Long, TemplateInfo> templateInfos) {
|
||||
public ListVolumeAnswer(String secUrl, Map<Long, TemplateProp> templateInfos) {
|
||||
super(null, true, "success");
|
||||
this.setSecUrl(secUrl);
|
||||
this.templateInfos = templateInfos;
|
||||
}
|
||||
|
||||
public Map<Long, TemplateInfo> getTemplateInfo() {
|
||||
public Map<Long, TemplateProp> getTemplateInfo() {
|
||||
return templateInfos;
|
||||
}
|
||||
|
||||
public void setTemplateInfo(Map<Long, TemplateInfo> templateInfos) {
|
||||
public void setTemplateInfo(Map<Long, TemplateProp> templateInfos) {
|
||||
this.templateInfos = templateInfos;
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
// under the License.
|
||||
package com.cloud.storage.template;
|
||||
|
||||
public class TemplateInfo {
|
||||
public class TemplateProp {
|
||||
String templateName;
|
||||
String installPath;
|
||||
long size;
|
||||
@ -25,11 +25,11 @@ public class TemplateInfo {
|
||||
boolean isPublic;
|
||||
boolean isCorrupted;
|
||||
|
||||
protected TemplateInfo() {
|
||||
protected TemplateProp() {
|
||||
|
||||
}
|
||||
|
||||
public TemplateInfo(String templateName, String installPath, long size, long physicalSize, boolean isPublic, boolean isCorrupted) {
|
||||
public TemplateProp(String templateName, String installPath, long size, long physicalSize, boolean isPublic, boolean isCorrupted) {
|
||||
this.templateName = templateName;
|
||||
this.installPath = installPath;
|
||||
this.size = size;
|
||||
@ -38,7 +38,7 @@ public class TemplateInfo {
|
||||
this.isCorrupted = isCorrupted;
|
||||
}
|
||||
|
||||
public TemplateInfo(String templateName, String installPath, boolean isPublic, boolean isCorrupted) {
|
||||
public TemplateProp(String templateName, String installPath, boolean isPublic, boolean isCorrupted) {
|
||||
this(templateName, installPath, 0, 0, isPublic, isCorrupted);
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ import com.cloud.exception.StorageUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
public interface TemplateService {
|
||||
public interface TemplateApiService {
|
||||
|
||||
VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException;
|
||||
|
||||
@ -65,7 +65,7 @@ import com.cloud.storage.DataStoreProviderApiService;
|
||||
import com.cloud.storage.StorageService;
|
||||
import com.cloud.storage.VolumeApiService;
|
||||
import com.cloud.storage.snapshot.SnapshotService;
|
||||
import com.cloud.template.TemplateService;
|
||||
import com.cloud.template.TemplateApiService;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.DomainService;
|
||||
@ -106,7 +106,7 @@ public abstract class BaseCmd {
|
||||
@Inject public VolumeApiService _volumeService;
|
||||
@Inject public ResourceService _resourceService;
|
||||
@Inject public NetworkService _networkService;
|
||||
@Inject public TemplateService _templateService;
|
||||
@Inject public TemplateApiService _templateService;
|
||||
@Inject public SecurityGroupService _securityGroupService;
|
||||
@Inject public SnapshotService _snapshotService;
|
||||
@Inject public ConsoleProxyService _consoleProxyService;
|
||||
|
||||
@ -744,7 +744,7 @@
|
||||
<bean id="imageDataManagerImpl" class="org.apache.cloudstack.storage.image.manager.ImageDataManagerImpl" />
|
||||
<bean id="imageStoreHelper" class="org.apache.cloudstack.storage.image.datastore.ImageStoreHelper" />
|
||||
<bean id="imageFormatHelper" class="org.apache.cloudstack.storage.image.format.ImageFormatHelper" />
|
||||
<bean id="imageServiceImpl" class="org.apache.cloudstack.storage.image.ImageServiceImpl" />
|
||||
<bean id="templateServiceImpl" class="org.apache.cloudstack.storage.image.TemplateServiceImpl" />
|
||||
<bean id="iso" class="org.apache.cloudstack.engine.subsystem.api.storage.type.Iso" />
|
||||
<bean id="networkFileSystem" class="org.apache.cloudstack.storage.datastore.type.NetworkFileSystem" />
|
||||
<bean id="networkRestService" class="org.apache.cloudstack.engine.rest.service.api.NetworkRestService" />
|
||||
|
||||
@ -105,7 +105,7 @@ import com.cloud.resource.ServerResource;
|
||||
import com.cloud.resource.ServerResourceBase;
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
@ -765,7 +765,7 @@ public class HypervResource extends ServerResourceBase implements ServerResource
|
||||
try {
|
||||
StorageFilerTO pool = cmd.getPool();
|
||||
s_logger.info("Primary storage pool details: " + pool.getHost() + " " + pool.getPath());
|
||||
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
|
||||
// FIXME: get the actual storage capacity and storage stats of CSV volume
|
||||
// by running powershell cmdlet. This hardcoding just for prototype.
|
||||
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
|
||||
|
||||
@ -60,7 +60,7 @@ import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.storage.template.DownloadManager;
|
||||
import com.cloud.storage.template.DownloadManagerImpl;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.storage.template.UploadManager;
|
||||
import com.cloud.storage.template.UploadManagerImpl;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
@ -650,7 +650,7 @@ public class CifsSecondaryStorageResource extends ServerResourceBase implements
|
||||
return null;
|
||||
}*/
|
||||
|
||||
final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap<String, TemplateInfo>());
|
||||
final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap<String, TemplateProp>());
|
||||
|
||||
cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
|
||||
cmd.setIqn(null);
|
||||
|
||||
@ -48,7 +48,7 @@ import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.storage.template.DownloadManager;
|
||||
import com.cloud.storage.template.DownloadManagerImpl;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
|
||||
public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
|
||||
@ -109,7 +109,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
|
||||
|
||||
private Answer execute(ListTemplateCommand cmd) {
|
||||
String root = getRootDir();
|
||||
Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
|
||||
Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
|
||||
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.storage.template.DownloadManager;
|
||||
import com.cloud.storage.template.DownloadManagerImpl;
|
||||
import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.storage.template.TemplateLocation;
|
||||
import com.cloud.storage.template.UploadManager;
|
||||
import com.cloud.storage.template.UploadManagerImpl;
|
||||
@ -1073,12 +1073,12 @@ SecondaryStorageResource {
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, TemplateInfo> swiftListTemplate(SwiftTO swift) {
|
||||
Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
|
||||
String[] containers = swiftList(swift, "", "");
|
||||
if (containers == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
|
||||
for( String container : containers) {
|
||||
if ( container.startsWith("T-")) {
|
||||
String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
|
||||
@ -1095,7 +1095,7 @@ SecondaryStorageResource {
|
||||
s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
|
||||
continue;
|
||||
}
|
||||
TemplateInfo tInfo = loc.getTemplateInfo();
|
||||
TemplateProp tInfo = loc.getTemplateInfo();
|
||||
tInfo.setInstallPath(container);
|
||||
tmpltInfos.put(tInfo.getTemplateName(), tInfo);
|
||||
loc.purge();
|
||||
@ -1111,11 +1111,11 @@ SecondaryStorageResource {
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
if (cmd.getSwift() != null) {
|
||||
Map<String, TemplateInfo> templateInfos = swiftListTemplate(cmd.getSwift());
|
||||
Map<String, TemplateProp> templateInfos = swiftListTemplate(cmd.getSwift());
|
||||
return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
|
||||
} else {
|
||||
String root = getRootDir(cmd.getSecUrl());
|
||||
Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
|
||||
Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
|
||||
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
|
||||
}
|
||||
}
|
||||
@ -1126,7 +1126,7 @@ SecondaryStorageResource {
|
||||
}
|
||||
|
||||
String root = getRootDir(cmd.getSecUrl());
|
||||
Map<Long, TemplateInfo> templateInfos = _dlMgr.gatherVolumeInfo(root);
|
||||
Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
|
||||
return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
|
||||
|
||||
}
|
||||
|
||||
@ -91,13 +91,13 @@ public interface DownloadManager extends Manager {
|
||||
/**
|
||||
* @return list of template info for installed templates
|
||||
*/
|
||||
public Map<String, TemplateInfo> gatherTemplateInfo(String templateDir);
|
||||
public Map<String, TemplateProp> gatherTemplateInfo(String templateDir);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @return list of volume info for installed volumes
|
||||
*/
|
||||
public Map<Long, TemplateInfo> gatherVolumeInfo(String volumeDir);
|
||||
public Map<Long, TemplateProp> gatherVolumeInfo(String volumeDir);
|
||||
|
||||
|
||||
}
|
||||
@ -717,8 +717,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TemplateInfo> gatherTemplateInfo(String rootDir) {
|
||||
Map<String, TemplateInfo> result = new HashMap<String, TemplateInfo>();
|
||||
public Map<String, TemplateProp> gatherTemplateInfo(String rootDir) {
|
||||
Map<String, TemplateProp> result = new HashMap<String, TemplateProp>();
|
||||
String templateDir = rootDir + File.separator + _templateDir;
|
||||
|
||||
if (! _storage.exists(templateDir)) {
|
||||
@ -741,7 +741,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
||||
continue;
|
||||
}
|
||||
|
||||
TemplateInfo tInfo = loc.getTemplateInfo();
|
||||
TemplateProp tInfo = loc.getTemplateInfo();
|
||||
|
||||
if ((tInfo.size == tInfo.physicalSize) && (tInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
|
||||
try {
|
||||
@ -774,8 +774,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, TemplateInfo> gatherVolumeInfo(String rootDir) {
|
||||
Map<Long, TemplateInfo> result = new HashMap<Long, TemplateInfo>();
|
||||
public Map<Long, TemplateProp> gatherVolumeInfo(String rootDir) {
|
||||
Map<Long, TemplateProp> result = new HashMap<Long, TemplateProp>();
|
||||
String volumeDir = rootDir + File.separator + _volumeDir;
|
||||
|
||||
if (! _storage.exists(volumeDir)) {
|
||||
@ -798,7 +798,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
||||
continue;
|
||||
}
|
||||
|
||||
TemplateInfo vInfo = loc.getTemplateInfo();
|
||||
TemplateProp vInfo = loc.getTemplateInfo();
|
||||
|
||||
if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
|
||||
try {
|
||||
|
||||
@ -156,8 +156,8 @@ public class TemplateLocation {
|
||||
return true;
|
||||
}
|
||||
|
||||
public TemplateInfo getTemplateInfo() {
|
||||
TemplateInfo tmplInfo = new TemplateInfo();
|
||||
public TemplateProp getTemplateInfo() {
|
||||
TemplateProp tmplInfo = new TemplateProp();
|
||||
tmplInfo.id = Long.parseLong(_props.getProperty("id"));
|
||||
tmplInfo.installPath = _templatePath + File.separator + _props.getProperty("filename");
|
||||
if (_resourceType == ResourceType.VOLUME){
|
||||
|
||||
@ -20,10 +20,16 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
|
||||
|
||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||
|
||||
public interface ImageService {
|
||||
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
|
||||
public interface TemplateService {
|
||||
AsyncCallFuture<CommandResult> createTemplateAsync(TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
|
||||
AsyncCallFuture<CommandResult> deleteTemplateAsync(TemplateInfo template);
|
||||
|
||||
|
||||
void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId);
|
||||
void handleTemplateSync(DataStore store);
|
||||
}
|
||||
@ -25,13 +25,13 @@ import com.cloud.exception.ConcurrentOperationException;
|
||||
|
||||
|
||||
public interface VolumeService {
|
||||
|
||||
|
||||
public class VolumeApiResult extends CommandResult {
|
||||
private final VolumeInfo volume;
|
||||
public VolumeApiResult(VolumeInfo volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
|
||||
public VolumeInfo getVolume() {
|
||||
return this.volume;
|
||||
}
|
||||
@ -39,16 +39,16 @@ public interface VolumeService {
|
||||
|
||||
/**
|
||||
* Creates the volume based on the given criteria
|
||||
*
|
||||
*
|
||||
* @param cmd
|
||||
*
|
||||
*
|
||||
* @return the volume object
|
||||
*/
|
||||
AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore store);
|
||||
|
||||
/**
|
||||
* Delete volume
|
||||
*
|
||||
*
|
||||
* @param volumeId
|
||||
* @return
|
||||
* @throws ConcurrentOperationException
|
||||
@ -56,12 +56,12 @@ public interface VolumeService {
|
||||
AsyncCallFuture<VolumeApiResult> expungeVolumeAsync(VolumeInfo volume);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
boolean cloneVolume(long volumeId, long baseVolId);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(VolumeInfo volume, DataStore store, SnapshotInfo snapshot);
|
||||
|
||||
@ -74,7 +74,9 @@ public interface VolumeService {
|
||||
boolean destroyVolume(long volumeId) throws ConcurrentOperationException;
|
||||
|
||||
AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store);
|
||||
|
||||
|
||||
AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume);
|
||||
|
||||
void handleVolumeSync(DataStore store);
|
||||
|
||||
}
|
||||
|
||||
@ -30,7 +30,5 @@ public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Lo
|
||||
|
||||
public List<SnapshotDataStoreVO> listByStoreId(long id);
|
||||
|
||||
public List<SnapshotDataStoreVO> listLiveByStoreId(long id);
|
||||
|
||||
public void deletePrimaryRecordsForStore(long id);
|
||||
}
|
||||
|
||||
@ -23,18 +23,20 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
|
||||
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.fsm.StateDao;
|
||||
|
||||
public interface TemplateDataStoreDao extends GenericDao<TemplateDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore> {
|
||||
|
||||
public List<TemplateDataStoreVO> listByStoreId(long id);
|
||||
|
||||
public List<TemplateDataStoreVO> listLiveByStoreId(long id);
|
||||
public List<TemplateDataStoreVO> listByStoreId(long id);
|
||||
|
||||
public void deletePrimaryRecordsForStore(long id);
|
||||
|
||||
List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states);
|
||||
|
||||
List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status);
|
||||
|
||||
TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId);
|
||||
}
|
||||
|
||||
@ -291,6 +291,12 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
|
||||
return this.state;
|
||||
}
|
||||
|
||||
|
||||
public void setState(ObjectInDataStoreStateMachine.State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
|
||||
public long getUpdatedCount() {
|
||||
return this.updatedCount;
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.List;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.fsm.StateDao;
|
||||
|
||||
@ -29,7 +30,9 @@ public interface VolumeDataStoreDao extends GenericDao<VolumeDataStoreVO, Long>,
|
||||
|
||||
public List<VolumeDataStoreVO> listByStoreId(long id);
|
||||
|
||||
public List<VolumeDataStoreVO> listLiveByStoreId(long id);
|
||||
|
||||
public void deletePrimaryRecordsForStore(long id);
|
||||
|
||||
public VolumeDataStoreVO findByVolumeId(long volumeId);
|
||||
|
||||
public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId);
|
||||
}
|
||||
|
||||
@ -203,14 +203,14 @@ public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMach
|
||||
this.state = ObjectInDataStoreStateMachine.State.Allocated;
|
||||
}
|
||||
|
||||
public VolumeDataStoreVO(long hostId, long volumeId, long zoneId, Date lastUpdated,
|
||||
public VolumeDataStoreVO(long hostId, long volumeId, Date lastUpdated,
|
||||
int downloadPercent, Status downloadState,
|
||||
String localDownloadPath, String errorString, String jobId,
|
||||
String installPath, String downloadUrl, String checksum, ImageFormat format) {
|
||||
//super();
|
||||
this.dataStoreId = hostId;
|
||||
this.volumeId = volumeId;
|
||||
this.zoneId = zoneId;
|
||||
//this.zoneId = zoneId;
|
||||
this.lastUpdated = lastUpdated;
|
||||
this.downloadPercent = downloadPercent;
|
||||
this.downloadState = downloadState;
|
||||
|
||||
@ -1,147 +0,0 @@
|
||||
/*
|
||||
* 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 org.apache.cloudstack.storage.image;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
||||
import org.apache.cloudstack.storage.datastore.DataObjectManager;
|
||||
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
|
||||
@Component
|
||||
public class ImageServiceImpl implements ImageService {
|
||||
private static final Logger s_logger = Logger.getLogger(ImageServiceImpl.class);
|
||||
@Inject
|
||||
ObjectInDataStoreManager objectInDataStoreMgr;
|
||||
@Inject
|
||||
DataObjectManager dataObjectMgr;
|
||||
|
||||
class CreateTemplateContext<T> extends AsyncRpcConext<T> {
|
||||
final TemplateInfo srcTemplate;
|
||||
final DataStore store;
|
||||
final AsyncCallFuture<CommandResult> future;
|
||||
final DataObject templateOnStore;
|
||||
|
||||
public CreateTemplateContext(AsyncCompletionCallback<T> callback, TemplateInfo srcTemplate,
|
||||
AsyncCallFuture<CommandResult> future,
|
||||
DataStore store,
|
||||
DataObject templateOnStore
|
||||
) {
|
||||
super(callback);
|
||||
this.srcTemplate = srcTemplate;
|
||||
this.future = future;
|
||||
this.store = store;
|
||||
this.templateOnStore = templateOnStore;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateAsync(
|
||||
TemplateInfo template, DataStore store) {
|
||||
TemplateObject to = (TemplateObject) template;
|
||||
AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
|
||||
// persist template_store_ref entry
|
||||
DataObject templateOnStore = store.create(template);
|
||||
// update template_store_ref state
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
|
||||
|
||||
CreateTemplateContext<CommandResult> context = new CreateTemplateContext<CommandResult>(null,
|
||||
template,
|
||||
future,
|
||||
store,
|
||||
templateOnStore
|
||||
);
|
||||
AsyncCallbackDispatcher<ImageServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
|
||||
store.getDriver().createAsync(templateOnStore, caller);
|
||||
return future;
|
||||
}
|
||||
|
||||
protected Void createTemplateCallback(AsyncCallbackDispatcher<ImageServiceImpl, CreateCmdResult> callback,
|
||||
CreateTemplateContext<CreateCmdResult> context) {
|
||||
TemplateObject template = (TemplateObject)context.srcTemplate;
|
||||
AsyncCallFuture<CommandResult> future = context.future;
|
||||
CommandResult result = new CommandResult();
|
||||
DataObject templateOnStore = context.templateOnStore;
|
||||
CreateCmdResult callbackResult = callback.getResult();
|
||||
if (callbackResult.isFailed()) {
|
||||
try {
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
template.stateTransit(TemplateEvent.OperationFailed);
|
||||
} catch (NoTransitionException e) {
|
||||
s_logger.debug("Failed to update template state", e);
|
||||
}
|
||||
result.setResult(callbackResult.getResult());
|
||||
future.complete(result);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
|
||||
template.stateTransit(TemplateEvent.OperationSucceeded);
|
||||
} catch (NoTransitionException e) {
|
||||
s_logger.debug("Failed to transit state", e);
|
||||
result.setResult(e.toString());
|
||||
future.complete(result);
|
||||
return null;
|
||||
}
|
||||
|
||||
future.complete(result);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> deleteTemplateAsync(
|
||||
TemplateInfo template) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(
|
||||
SnapshotInfo snapshot, TemplateInfo template, DataStore store) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(
|
||||
VolumeInfo volume, TemplateInfo template, DataStore store) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,481 @@
|
||||
/*
|
||||
* 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 org.apache.cloudstack.storage.image;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||
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.TemplateService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
||||
import org.apache.cloudstack.storage.datastore.DataObjectManager;
|
||||
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
||||
import com.cloud.agent.api.storage.ListTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.ListTemplateCommand;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.VMTemplateZoneVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplateZoneDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.download.DownloadMonitor;
|
||||
import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
|
||||
@Component
|
||||
public class TemplateServiceImpl implements TemplateService {
|
||||
private static final Logger s_logger = Logger.getLogger(TemplateServiceImpl.class);
|
||||
@Inject
|
||||
ObjectInDataStoreManager _objectInDataStoreMgr;
|
||||
@Inject
|
||||
DataObjectManager _dataObjectMgr;
|
||||
@Inject
|
||||
DataStoreManager _storeMgr;
|
||||
@Inject
|
||||
ResourceLimitService _resourceLimitMgr;
|
||||
@Inject
|
||||
AccountManager _accountMgr;
|
||||
@Inject
|
||||
AlertManager _alertMgr;
|
||||
@Inject
|
||||
VMTemplateDao _templateDao;
|
||||
@Inject
|
||||
TemplateDataStoreDao _vmTemplateStoreDao;
|
||||
@Inject
|
||||
VolumeDataStoreDao _volumeStoreDao;
|
||||
@Inject
|
||||
DownloadMonitor _dlMonitor;
|
||||
@Inject
|
||||
AgentManager _agentMgr;
|
||||
@Inject
|
||||
SecondaryStorageVmManager _ssvmMgr;
|
||||
@Inject
|
||||
DataCenterDao _dcDao = null;
|
||||
@Inject
|
||||
VMTemplateZoneDao _vmTemplateZoneDao;
|
||||
@Inject
|
||||
ClusterDao _clusterDao;
|
||||
@Inject
|
||||
UserVmDao _userVmDao;
|
||||
@Inject
|
||||
VolumeDao _volumeDao;
|
||||
|
||||
|
||||
class CreateTemplateContext<T> extends AsyncRpcConext<T> {
|
||||
final TemplateInfo srcTemplate;
|
||||
final DataStore store;
|
||||
final AsyncCallFuture<CommandResult> future;
|
||||
final DataObject templateOnStore;
|
||||
|
||||
public CreateTemplateContext(AsyncCompletionCallback<T> callback, TemplateInfo srcTemplate,
|
||||
AsyncCallFuture<CommandResult> future,
|
||||
DataStore store,
|
||||
DataObject templateOnStore
|
||||
) {
|
||||
super(callback);
|
||||
this.srcTemplate = srcTemplate;
|
||||
this.future = future;
|
||||
this.store = store;
|
||||
this.templateOnStore = templateOnStore;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateAsync(
|
||||
TemplateInfo template, DataStore store) {
|
||||
TemplateObject to = (TemplateObject) template;
|
||||
AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
|
||||
// persist template_store_ref entry
|
||||
DataObject templateOnStore = store.create(template);
|
||||
// update template_store_ref state
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
|
||||
|
||||
CreateTemplateContext<CommandResult> context = new CreateTemplateContext<CommandResult>(null,
|
||||
template,
|
||||
future,
|
||||
store,
|
||||
templateOnStore
|
||||
);
|
||||
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
|
||||
store.getDriver().createAsync(templateOnStore, caller);
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) {
|
||||
Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
|
||||
List<DataStore> ssHosts = this._storeMgr.getImageStoresByScope(new ZoneScope(dcId));
|
||||
if (ssHosts == null || ssHosts.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
/*Download all the templates in zone with the same hypervisortype*/
|
||||
for ( DataStore ssHost : ssHosts) {
|
||||
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
|
||||
List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
|
||||
|
||||
|
||||
for (VMTemplateVO rtngTmplt : rtngTmplts) {
|
||||
if (rtngTmplt.getHypervisorType() == hostHyper) {
|
||||
toBeDownloaded.add(rtngTmplt);
|
||||
}
|
||||
}
|
||||
|
||||
for (VMTemplateVO builtinTmplt : defaultBuiltin) {
|
||||
if (builtinTmplt.getHypervisorType() == hostHyper) {
|
||||
toBeDownloaded.add(builtinTmplt);
|
||||
}
|
||||
}
|
||||
|
||||
for (VMTemplateVO template: toBeDownloaded) {
|
||||
TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(ssHost.getId(), template.getId());
|
||||
if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) {
|
||||
_dlMonitor.downloadTemplateToStorage(template, ssHost, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void handleTemplateSync(DataStore store) {
|
||||
if (store == null) {
|
||||
s_logger.warn("Huh? image store is null");
|
||||
return;
|
||||
}
|
||||
long storeId = store.getId();
|
||||
Long zoneId = store.getScope().getScopeId();
|
||||
|
||||
Map<String, TemplateProp> templateInfos = listTemplate(store);
|
||||
if (templateInfos == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
|
||||
List<VMTemplateVO> allTemplates = null;
|
||||
if (zoneId == null){
|
||||
// region wide store
|
||||
allTemplates = _templateDao.listAll();
|
||||
}
|
||||
else{
|
||||
// zone wide store
|
||||
allTemplates = _templateDao.listAllInZone(zoneId);
|
||||
}
|
||||
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
|
||||
List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
|
||||
|
||||
if (rtngTmplts != null) {
|
||||
for (VMTemplateVO rtngTmplt : rtngTmplts) {
|
||||
if (!allTemplates.contains(rtngTmplt)) {
|
||||
allTemplates.add(rtngTmplt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultBuiltin != null) {
|
||||
for (VMTemplateVO builtinTmplt : defaultBuiltin) {
|
||||
if (!allTemplates.contains(builtinTmplt)) {
|
||||
allTemplates.add(builtinTmplt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toBeDownloaded.addAll(allTemplates);
|
||||
|
||||
for (VMTemplateVO tmplt : allTemplates) {
|
||||
String uniqueName = tmplt.getUniqueName();
|
||||
TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
|
||||
if (templateInfos.containsKey(uniqueName)) {
|
||||
TemplateProp tmpltInfo = templateInfos.remove(uniqueName);
|
||||
toBeDownloaded.remove(tmplt);
|
||||
if (tmpltStore != null) {
|
||||
s_logger.info("Template Sync found " + uniqueName + " already in the template host table");
|
||||
if (tmpltStore.getDownloadState() != Status.DOWNLOADED) {
|
||||
tmpltStore.setErrorString("");
|
||||
}
|
||||
if (tmpltInfo.isCorrupted()) {
|
||||
tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR);
|
||||
String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId();
|
||||
tmpltStore.setErrorString(msg);
|
||||
s_logger.info("msg");
|
||||
if (tmplt.getUrl() == null) {
|
||||
msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId();
|
||||
s_logger.warn(msg);
|
||||
} else {
|
||||
toBeDownloaded.add(tmplt);
|
||||
}
|
||||
|
||||
} else {
|
||||
tmpltStore.setDownloadPercent(100);
|
||||
tmpltStore.setDownloadState(Status.DOWNLOADED);
|
||||
tmpltStore.setInstallPath(tmpltInfo.getInstallPath());
|
||||
tmpltStore.setSize(tmpltInfo.getSize());
|
||||
tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
|
||||
tmpltStore.setLastUpdated(new Date());
|
||||
|
||||
if (tmpltInfo.getSize() > 0) {
|
||||
long accountId = tmplt.getAccountId();
|
||||
try {
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage,
|
||||
tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl()));
|
||||
} catch (ResourceAllocationException e) {
|
||||
s_logger.warn(e.getMessage());
|
||||
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId,
|
||||
null, e.getMessage(), e.getMessage());
|
||||
} finally {
|
||||
_resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
|
||||
}
|
||||
}
|
||||
}
|
||||
_vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore);
|
||||
} else {
|
||||
tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl());
|
||||
tmpltStore.setSize(tmpltInfo.getSize());
|
||||
tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
|
||||
_vmTemplateStoreDao.persist(tmpltStore);
|
||||
this.associateTemplateToZone(tmplt.getId(), zoneId);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) {
|
||||
s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + storeId + ", will request download to start/resume shortly");
|
||||
|
||||
} else if (tmpltStore == null) {
|
||||
s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly");
|
||||
TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl());
|
||||
_vmTemplateStoreDao.persist(templtStore);
|
||||
this.associateTemplateToZone(tmplt.getId(), zoneId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (toBeDownloaded.size() > 0) {
|
||||
/* Only download templates whose hypervirsor type is in the zone */
|
||||
List<HypervisorType> availHypers = _clusterDao.getAvailableHypervisorInZone(zoneId);
|
||||
if (availHypers.isEmpty()) {
|
||||
/*
|
||||
* This is for cloudzone, local secondary storage resource
|
||||
* started before cluster created
|
||||
*/
|
||||
availHypers.add(HypervisorType.KVM);
|
||||
}
|
||||
/* Baremetal need not to download any template */
|
||||
availHypers.remove(HypervisorType.BareMetal);
|
||||
availHypers.add(HypervisorType.None); // bug 9809: resume ISO
|
||||
// download.
|
||||
for (VMTemplateVO tmplt : toBeDownloaded) {
|
||||
if (tmplt.getUrl() == null) { // If url is null we can't
|
||||
// initiate the download
|
||||
continue;
|
||||
}
|
||||
// check if there is a record for this template in this store
|
||||
TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
|
||||
|
||||
// if this is private template, and there is no record for this
|
||||
// template in this store, skip
|
||||
if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) {
|
||||
if (tmpltHost == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (availHypers.contains(tmplt.getHypervisorType())) {
|
||||
if (tmpltHost != null ) {
|
||||
continue;
|
||||
}
|
||||
s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName());
|
||||
//TODO: we should pass a callback here
|
||||
_dlMonitor.downloadTemplateToStorage(tmplt, store, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String uniqueName : templateInfos.keySet()) {
|
||||
TemplateProp tInfo = templateInfos.get(uniqueName);
|
||||
List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId());
|
||||
//check if there is any Vm using this ISO.
|
||||
if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
|
||||
DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getUri(), tInfo.getInstallPath());
|
||||
try {
|
||||
HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
|
||||
_agentMgr.sendToSecStorage(ssAhost, dtCommand, null);
|
||||
} catch (AgentUnavailableException e) {
|
||||
String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database";
|
||||
s_logger.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId + " since it isn't in the database";
|
||||
s_logger.info(description);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// persist entry in template_zone_ref table. zoneId can be empty for region-wide image store, in that case,
|
||||
// we will associate the template to all the zones.
|
||||
private void associateTemplateToZone(long templateId, Long zoneId){
|
||||
List<Long> dcs = new ArrayList<Long>();
|
||||
if (zoneId != null ){
|
||||
dcs.add(zoneId);
|
||||
}
|
||||
else{
|
||||
List<DataCenterVO> zones = _dcDao.listAll();
|
||||
for (DataCenterVO zone : zones){
|
||||
dcs.add(zone.getId());
|
||||
}
|
||||
}
|
||||
for (Long id : dcs) {
|
||||
VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, templateId);
|
||||
if (tmpltZoneVO == null) {
|
||||
tmpltZoneVO = new VMTemplateZoneVO(id, templateId, new Date());
|
||||
_vmTemplateZoneDao.persist(tmpltZoneVO);
|
||||
} else {
|
||||
tmpltZoneVO.setLastUpdated(new Date());
|
||||
_vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Map<String, TemplateProp> listTemplate(DataStore ssHost) {
|
||||
ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getUri());
|
||||
HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssHost);
|
||||
Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
ListTemplateAnswer tanswer = (ListTemplateAnswer)answer;
|
||||
return tanswer.getTemplateInfo();
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("can not list template for secondary storage host " + ssHost.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected Void createTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> callback,
|
||||
CreateTemplateContext<CreateCmdResult> context) {
|
||||
TemplateObject template = (TemplateObject)context.srcTemplate;
|
||||
AsyncCallFuture<CommandResult> future = context.future;
|
||||
CommandResult result = new CommandResult();
|
||||
DataObject templateOnStore = context.templateOnStore;
|
||||
CreateCmdResult callbackResult = callback.getResult();
|
||||
if (callbackResult.isFailed()) {
|
||||
try {
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
template.stateTransit(TemplateEvent.OperationFailed);
|
||||
} catch (NoTransitionException e) {
|
||||
s_logger.debug("Failed to update template state", e);
|
||||
}
|
||||
result.setResult(callbackResult.getResult());
|
||||
future.complete(result);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
|
||||
template.stateTransit(TemplateEvent.OperationSucceeded);
|
||||
} catch (NoTransitionException e) {
|
||||
s_logger.debug("Failed to transit state", e);
|
||||
result.setResult(e.toString());
|
||||
future.complete(result);
|
||||
return null;
|
||||
}
|
||||
|
||||
future.complete(result);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> deleteTemplateAsync(
|
||||
TemplateInfo template) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(
|
||||
SnapshotInfo snapshot, TemplateInfo template, DataStore store) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(
|
||||
VolumeInfo volume, TemplateInfo template, DataStore store) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -39,7 +39,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
@ -86,7 +86,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
//@Inject
|
||||
//ImageDataStoreProviderManager imageProviderMgr;
|
||||
@Inject
|
||||
ImageService imageService;
|
||||
TemplateService imageService;
|
||||
@Inject
|
||||
VolumeService volumeService;
|
||||
@Inject
|
||||
|
||||
@ -42,21 +42,16 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
||||
private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class);
|
||||
private SearchBuilder<SnapshotDataStoreVO> updateStateSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> storeSearch;
|
||||
private SearchBuilder<SnapshotDataStoreVO> liveStoreSearch;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
storeSearch = createSearchBuilder();
|
||||
storeSearch = createSearchBuilder();
|
||||
storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
storeSearch.done();
|
||||
|
||||
liveStoreSearch = createSearchBuilder();
|
||||
liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
liveStoreSearch.done();
|
||||
|
||||
updateStateSearch = this.createSearchBuilder();
|
||||
updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
|
||||
updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
|
||||
@ -102,17 +97,11 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<SnapshotDataStoreVO> listByStoreId(long id) {
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
|
||||
sc.setParameters("store_id", id);
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SnapshotDataStoreVO> listLiveByStoreId(long id) {
|
||||
SearchCriteria<SnapshotDataStoreVO> sc = liveStoreSearch.create();
|
||||
sc.setParameters("store_id", id);
|
||||
sc.setParameters("destroyed", false);
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
@ -42,23 +43,20 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
||||
private static final Logger s_logger = Logger.getLogger(TemplateDataStoreDaoImpl.class);
|
||||
private SearchBuilder<TemplateDataStoreVO> updateStateSearch;
|
||||
private SearchBuilder<TemplateDataStoreVO> storeSearch;
|
||||
private SearchBuilder<TemplateDataStoreVO> liveStoreSearch;
|
||||
private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch;
|
||||
private SearchBuilder<TemplateDataStoreVO> storeTemplateDownloadStatusSearch;
|
||||
private SearchBuilder<TemplateDataStoreVO> storeTemplateSearch;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
|
||||
storeSearch = createSearchBuilder();
|
||||
storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
storeSearch.done();
|
||||
|
||||
liveStoreSearch = createSearchBuilder();
|
||||
liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
liveStoreSearch.done();
|
||||
|
||||
updateStateSearch = this.createSearchBuilder();
|
||||
updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
|
||||
updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
|
||||
@ -72,6 +70,14 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
||||
storeTemplateStateSearch.and("destroyed", storeTemplateStateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
storeTemplateStateSearch.done();
|
||||
|
||||
storeTemplateDownloadStatusSearch = createSearchBuilder();
|
||||
storeTemplateDownloadStatusSearch.and("template_id", storeTemplateDownloadStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
||||
storeTemplateDownloadStatusSearch.and("store_id", storeTemplateDownloadStatusSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
storeTemplateDownloadStatusSearch.and("downloadState", storeTemplateDownloadStatusSearch.entity().getDownloadState(), SearchCriteria.Op.IN);
|
||||
storeTemplateDownloadStatusSearch.and("destroyed", storeTemplateDownloadStatusSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
storeTemplateDownloadStatusSearch.done();
|
||||
|
||||
|
||||
storeTemplateSearch = createSearchBuilder();
|
||||
storeTemplateSearch.and("store_id", storeTemplateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
storeTemplateSearch.and("template_id", storeTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
||||
@ -118,16 +124,11 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<TemplateDataStoreVO> listByStoreId(long id) {
|
||||
SearchCriteria<TemplateDataStoreVO> sc = storeSearch.create();
|
||||
sc.setParameters("store_id", id);
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
@Override
|
||||
public List<TemplateDataStoreVO> listLiveByStoreId(long id) {
|
||||
SearchCriteria<TemplateDataStoreVO> sc = liveStoreSearch.create();
|
||||
sc.setParameters("store_id", id);
|
||||
sc.setParameters("destroyed", false);
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
@ -152,6 +153,17 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
||||
return search(sc, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status) {
|
||||
SearchCriteria<TemplateDataStoreVO> sc = storeTemplateStateSearch.create();
|
||||
sc.setParameters("template_id", templateId);
|
||||
sc.setParameters("store_id", storeId);
|
||||
sc.setParameters("downloadState", (Object[])status);
|
||||
return search(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId) {
|
||||
SearchCriteria<TemplateDataStoreVO> sc = storeTemplateSearch.create();
|
||||
|
||||
@ -31,6 +31,7 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.storage.VolumeHostVO;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
@ -42,21 +43,30 @@ import com.cloud.utils.db.UpdateBuilder;
|
||||
public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Long> implements VolumeDataStoreDao {
|
||||
private static final Logger s_logger = Logger.getLogger(VolumeDataStoreDaoImpl.class);
|
||||
private SearchBuilder<VolumeDataStoreVO> updateStateSearch;
|
||||
private SearchBuilder<VolumeDataStoreVO> volumeSearch;
|
||||
private SearchBuilder<VolumeDataStoreVO> storeSearch;
|
||||
private SearchBuilder<VolumeDataStoreVO> liveStoreSearch;
|
||||
private SearchBuilder<VolumeDataStoreVO> storeVolumeSearch;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
|
||||
storeSearch = createSearchBuilder();
|
||||
storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
storeSearch.done();
|
||||
|
||||
liveStoreSearch = createSearchBuilder();
|
||||
liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
liveStoreSearch.done();
|
||||
volumeSearch = createSearchBuilder();
|
||||
volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
volumeSearch.and("destroyed", volumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
volumeSearch.done();
|
||||
|
||||
storeVolumeSearch = createSearchBuilder();
|
||||
storeVolumeSearch.and("store_id", storeVolumeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||
storeVolumeSearch.and("volume_id", storeVolumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
storeVolumeSearch.and("destroyed", storeVolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
storeVolumeSearch.done();
|
||||
|
||||
updateStateSearch = this.createSearchBuilder();
|
||||
updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
|
||||
@ -102,16 +112,11 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<VolumeDataStoreVO> listByStoreId(long id) {
|
||||
SearchCriteria<VolumeDataStoreVO> sc = storeSearch.create();
|
||||
sc.setParameters("store_id", id);
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
@Override
|
||||
public List<VolumeDataStoreVO> listLiveByStoreId(long id) {
|
||||
SearchCriteria<VolumeDataStoreVO> sc = liveStoreSearch.create();
|
||||
sc.setParameters("store_id", id);
|
||||
sc.setParameters("destroyed", false);
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
@ -125,4 +130,23 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
|
||||
remove(sc);
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VolumeDataStoreVO findByVolumeId(long volumeId) {
|
||||
SearchCriteria<VolumeDataStoreVO> sc = volumeSearch.create();
|
||||
sc.setParameters("volume_id", volumeId);
|
||||
sc.setParameters("destroyed", false);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
@Override
|
||||
public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId) {
|
||||
SearchCriteria<VolumeDataStoreVO> sc = storeVolumeSearch.create();
|
||||
sc.setParameters("store_id", storeId);
|
||||
sc.setParameters("volume_id", volumeId);
|
||||
sc.setParameters("destroyed", false);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -318,6 +318,10 @@ public class VolumeObject implements VolumeInfo {
|
||||
return this.payload;
|
||||
}
|
||||
|
||||
public VolumeVO getVolume(){
|
||||
return this.volumeVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HypervisorType getHypervisorType() {
|
||||
return this.volumeDao.getHypervisorType(this.volumeVO.getId());
|
||||
|
||||
@ -18,6 +18,11 @@
|
||||
*/
|
||||
package org.apache.cloudstack.storage.volume;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
|
||||
@ -41,19 +46,37 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager;
|
||||
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
||||
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
|
||||
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.storage.DeleteVolumeCommand;
|
||||
import com.cloud.agent.api.storage.ListVolumeAnswer;
|
||||
import com.cloud.agent.api.storage.ListVolumeCommand;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.storage.Volume.Type;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.download.DownloadMonitor;
|
||||
import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
||||
import com.cloud.storage.snapshot.SnapshotManager;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
@ -77,13 +100,29 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
@Inject
|
||||
VolumeDataFactory volFactory;
|
||||
@Inject SnapshotManager snapshotMgr;
|
||||
@Inject
|
||||
ResourceLimitService _resourceLimitMgr;
|
||||
@Inject
|
||||
DownloadMonitor _dlMonitor;
|
||||
@Inject
|
||||
AccountManager _accountMgr;
|
||||
@Inject
|
||||
AlertManager _alertMgr;
|
||||
@Inject VMInstanceDao vmDao;
|
||||
@Inject
|
||||
ConfigurationDao configDao;
|
||||
@Inject
|
||||
SecondaryStorageVmManager _ssvmMgr;
|
||||
@Inject
|
||||
AgentManager _agentMgr;
|
||||
@Inject
|
||||
VolumeDataStoreDao _volumeStoreDao;
|
||||
@Inject
|
||||
VolumeDao _volumeDao;
|
||||
|
||||
public VolumeServiceImpl() {
|
||||
}
|
||||
|
||||
|
||||
private class CreateVolumeContext<T> extends AsyncRpcConext<T> {
|
||||
|
||||
private DataObject volume;
|
||||
@ -96,17 +135,17 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
this.volume = volume;
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
|
||||
public DataObject getVolume() {
|
||||
return this.volume;
|
||||
}
|
||||
|
||||
|
||||
public AsyncCallFuture<VolumeApiResult> getFuture() {
|
||||
return this.future;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore dataStore) {
|
||||
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
|
||||
@ -117,11 +156,11 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createVolumeCallback(null, null))
|
||||
.setContext(context);
|
||||
|
||||
|
||||
dataStore.getDriver().createAsync(volumeOnStore, caller);
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
|
||||
CreateCmdResult result = callback.getResult();
|
||||
DataObject vo = context.getVolume();
|
||||
@ -139,7 +178,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
context.getFuture().complete(volResult);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private class DeleteVolumeContext<T> extends AsyncRpcConext<T> {
|
||||
private final VolumeObject volume;
|
||||
private AsyncCallFuture<VolumeApiResult> future;
|
||||
@ -151,11 +190,11 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
this.volume = volume;
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
|
||||
public VolumeObject getVolume() {
|
||||
return this.volume;
|
||||
}
|
||||
|
||||
|
||||
public AsyncCallFuture<VolumeApiResult> getFuture() {
|
||||
return this.future;
|
||||
}
|
||||
@ -171,7 +210,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
future.complete(result);
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
String vmName = null;
|
||||
VolumeVO vol = this.volDao.findById(volume.getId());
|
||||
if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) {
|
||||
@ -194,19 +233,19 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
return future;
|
||||
}
|
||||
VolumeObject vo = (VolumeObject)volume;
|
||||
|
||||
|
||||
volume.processEvent(Event.ExpungeRequested);
|
||||
|
||||
|
||||
|
||||
|
||||
DeleteVolumeContext<VolumeApiResult> context = new DeleteVolumeContext<VolumeApiResult>(null, vo, future);
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null))
|
||||
.setContext(context);
|
||||
|
||||
|
||||
volume.getDataStore().getDriver().deleteAsync(volume, caller);
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
public Void deleteVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, DeleteVolumeContext<VolumeApiResult> context) {
|
||||
CommandResult result = callback.getResult();
|
||||
VolumeObject vo = context.getVolume();
|
||||
@ -249,7 +288,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
private final TemplateInfo srcTemplate;
|
||||
private final AsyncCallFuture<VolumeApiResult> future;
|
||||
final DataObject destObj;
|
||||
public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore,
|
||||
public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore,
|
||||
TemplateInfo srcTemplate,
|
||||
AsyncCallFuture<VolumeApiResult> future, DataObject destObj) {
|
||||
super(callback);
|
||||
@ -259,11 +298,11 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
this.srcTemplate = srcTemplate;
|
||||
this.destObj = destObj;
|
||||
}
|
||||
|
||||
|
||||
public VolumeInfo getVolume() {
|
||||
return this.volume;
|
||||
}
|
||||
|
||||
|
||||
public PrimaryDataStore getDataStore() {
|
||||
return this.dataStore;
|
||||
}
|
||||
@ -271,13 +310,13 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
public TemplateInfo getSrcTemplate() {
|
||||
return this.srcTemplate;
|
||||
}
|
||||
|
||||
|
||||
public AsyncCallFuture<VolumeApiResult> getFuture() {
|
||||
return this.future;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class CreateBaseImageResult extends CommandResult {
|
||||
final TemplateInfo template;
|
||||
public CreateBaseImageResult(TemplateInfo template) {
|
||||
@ -285,7 +324,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
this.template = template;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private TemplateInfo waitForTemplateDownloaded(PrimaryDataStore store, TemplateInfo template) {
|
||||
int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
|
||||
int sleepTime = 120;
|
||||
@ -306,16 +345,16 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
}
|
||||
@DB
|
||||
protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
|
||||
|
||||
|
||||
DataObject templateOnPrimaryStoreObj = dataStore.create(template);
|
||||
CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume,
|
||||
CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume,
|
||||
dataStore,
|
||||
template,
|
||||
future, templateOnPrimaryStoreObj);
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null))
|
||||
.setContext(context);
|
||||
|
||||
|
||||
try {
|
||||
templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested);
|
||||
} catch (Exception e) {
|
||||
@ -330,7 +369,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller);
|
||||
} catch (Exception e) {
|
||||
@ -342,12 +381,12 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@DB
|
||||
protected Void copyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
|
||||
CopyCommandResult result = callback.getResult();
|
||||
VolumeApiResult res = new VolumeApiResult(context.getVolume());
|
||||
|
||||
|
||||
AsyncCallFuture<VolumeApiResult> future = context.getFuture();
|
||||
DataObject templateOnPrimaryStoreObj = context.destObj;
|
||||
if (!result.isSuccess()) {
|
||||
@ -356,18 +395,18 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
future.complete(res);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed);
|
||||
createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private class CreateVolumeFromBaseImageContext<T> extends AsyncRpcConext<T> {
|
||||
private final VolumeObject vo;
|
||||
private final AsyncCallFuture<VolumeApiResult> future;
|
||||
private final DataStore primaryStore;
|
||||
private final DataObject templateOnStore;
|
||||
public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, VolumeObject vo,
|
||||
public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, VolumeObject vo,
|
||||
DataStore primaryStore,
|
||||
DataObject templateOnStore,
|
||||
AsyncCallFuture<VolumeApiResult> future) {
|
||||
@ -377,13 +416,13 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
this.primaryStore = primaryStore;
|
||||
this.templateOnStore = templateOnStore;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AsyncCallFuture<VolumeApiResult> getFuture() {
|
||||
return this.future;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@DB
|
||||
protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture<VolumeApiResult> future) {
|
||||
VolumeObject vo = (VolumeObject)volume;
|
||||
@ -398,23 +437,23 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
motionSrv.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@DB
|
||||
public Void copyBaseImageCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
|
||||
VolumeObject vo = context.vo;
|
||||
CopyCommandResult result = callback.getResult();
|
||||
VolumeApiResult volResult = new VolumeApiResult(vo);
|
||||
|
||||
|
||||
if (result.isSuccess()) {
|
||||
if (result.getPath() != null) {
|
||||
vo.setPath(result.getPath());
|
||||
}
|
||||
vo.processEvent(Event.OperationSuccessed);
|
||||
vo.processEvent(Event.OperationSuccessed);
|
||||
} else {
|
||||
vo.processEvent(Event.OperationFailed);
|
||||
volResult.setResult(result.getResult());
|
||||
}
|
||||
|
||||
|
||||
AsyncCallFuture<VolumeApiResult> future = context.getFuture();
|
||||
future.complete(volResult);
|
||||
return null;
|
||||
@ -427,12 +466,12 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId());
|
||||
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
|
||||
VolumeApiResult result = new VolumeApiResult(volume);
|
||||
|
||||
|
||||
if (templateOnPrimaryStore == null) {
|
||||
createBaseImageAsync(volume, pd, template, future);
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, future);
|
||||
return future;
|
||||
}
|
||||
@ -441,13 +480,13 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
@DB
|
||||
public boolean destroyVolume(long volumeId)
|
||||
throws ConcurrentOperationException {
|
||||
|
||||
|
||||
VolumeInfo vol = this.volFactory.getVolume(volumeId);
|
||||
vol.processEvent(Event.DestroyRequested);
|
||||
this.snapshotMgr.deletePoliciesForVolume(volumeId);
|
||||
|
||||
vol.processEvent(Event.OperationSuccessed);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -455,11 +494,11 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
public AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(
|
||||
VolumeInfo volume, DataStore store, SnapshotInfo snapshot) {
|
||||
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
|
||||
|
||||
|
||||
try {
|
||||
DataObject volumeOnStore = store.create(volume);
|
||||
volume.processEvent(Event.CreateOnlyRequested);
|
||||
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null,
|
||||
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null,
|
||||
(VolumeObject)volume, store, volumeOnStore, future);
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null))
|
||||
@ -471,11 +510,11 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
result.setResult(e.toString());
|
||||
future.complete(result);
|
||||
}
|
||||
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback,
|
||||
|
||||
protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback,
|
||||
CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
|
||||
CopyCommandResult result = callback.getResult();
|
||||
VolumeInfo volume = context.vo;
|
||||
@ -487,19 +526,19 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
} else {
|
||||
event = Event.OperationSuccessed;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
volume.processEvent(event);
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("create volume from snapshot failed", e);
|
||||
apiResult.setResult(e.toString());
|
||||
}
|
||||
|
||||
|
||||
AsyncCallFuture<VolumeApiResult> future = context.future;
|
||||
future.complete(apiResult);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePool pool) {
|
||||
Long lastPoolId = volume.getPoolId();
|
||||
VolumeVO newVol = new VolumeVO(volume);
|
||||
@ -511,7 +550,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
newVol.setPodId(pool.getPodId());
|
||||
return this.volDao.persist(newVol);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class CopyVolumeContext<T> extends AsyncRpcConext<T> {
|
||||
final VolumeInfo srcVolume;
|
||||
@ -529,7 +568,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
this.destStore = destStore;
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@Override
|
||||
public AsyncCallFuture<VolumeApiResult> copyVolume(VolumeInfo srcVolume,
|
||||
@ -540,7 +579,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
if (!this.snapshotMgr.canOperateOnVolume(srcVolume)) {
|
||||
s_logger.debug(
|
||||
"There are snapshots creating on this volume, can not move this volume");
|
||||
|
||||
|
||||
res.setResult("There are snapshots creating on this volume, can not move this volume");
|
||||
future.complete(res);
|
||||
return future;
|
||||
@ -551,7 +590,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
destVolume.processEvent(Event.CreateOnlyRequested);
|
||||
srcVolume.processEvent(Event.CopyingRequested);
|
||||
|
||||
CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume,
|
||||
CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume,
|
||||
destVolume,
|
||||
destStore);
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
@ -565,7 +604,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
protected Void copyVolumeCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
|
||||
VolumeInfo srcVolume = context.srcVolume;
|
||||
VolumeInfo destVolume = context.destVolume;
|
||||
@ -593,13 +632,13 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
res.setResult(e.toString());
|
||||
future.complete(res);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store) {
|
||||
|
||||
|
||||
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
|
||||
VolumeObject vo = (VolumeObject) volume;
|
||||
|
||||
@ -607,11 +646,11 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
|
||||
caller.setCallback(caller.getTarget().registerVolumeCallback(null, null))
|
||||
.setContext(context);
|
||||
|
||||
|
||||
dataObjectMgr.createAsync(volume, store, caller, true);
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
protected Void registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
|
||||
CreateCmdResult result = callback.getResult();
|
||||
VolumeObject vo = (VolumeObject)context.volume;
|
||||
@ -624,7 +663,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
context.future.complete(res);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume) {
|
||||
@ -645,12 +684,12 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
volume.getDataStore().getDriver().resize(volume, caller);
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
protected Void resizeVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
|
||||
CreateCmdResult result = callback.getResult();
|
||||
AsyncCallFuture<VolumeApiResult> future = context.future;
|
||||
VolumeInfo volume = (VolumeInfo)context.volume;
|
||||
|
||||
|
||||
if (result.isFailed()) {
|
||||
try {
|
||||
volume.processEvent(Event.OperationFailed);
|
||||
@ -662,7 +701,7 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
future.complete(res);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
volume.processEvent(Event.OperationSuccessed);
|
||||
} catch(Exception e) {
|
||||
@ -672,13 +711,137 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
future.complete(res);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
VolumeApiResult res = new VolumeApiResult(volume);
|
||||
future.complete(res);
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void handleVolumeSync(DataStore store) {
|
||||
if (store == null) {
|
||||
s_logger.warn("Huh? ssHost is null");
|
||||
return;
|
||||
}
|
||||
long storeId = store.getId();
|
||||
Long zoneId = store.getScope().getScopeId();
|
||||
|
||||
|
||||
Map<Long, TemplateProp> volumeInfos = listVolume(store);
|
||||
if (volumeInfos == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listByStoreId(storeId);
|
||||
List<VolumeDataStoreVO> toBeDownloaded = new ArrayList<VolumeDataStoreVO>(dbVolumes);
|
||||
for (VolumeDataStoreVO volumeStore : dbVolumes){
|
||||
VolumeVO volume = _volumeDao.findById(volumeStore.getVolumeId());
|
||||
//Exists then don't download
|
||||
if (volumeInfos.containsKey(volume.getId())){
|
||||
TemplateProp volInfo = volumeInfos.remove(volume.getId());
|
||||
toBeDownloaded.remove(volumeStore);
|
||||
s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table");
|
||||
if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
|
||||
volumeStore.setErrorString("");
|
||||
}
|
||||
if (volInfo.isCorrupted()) {
|
||||
volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
|
||||
String msg = "Volume " + volume.getUuid() + " is corrupted on image store ";
|
||||
volumeStore.setErrorString(msg);
|
||||
s_logger.info("msg");
|
||||
if (volumeStore.getDownloadUrl() == null) {
|
||||
msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in image store: " + volumeStore.getDataStoreId();
|
||||
s_logger.warn(msg);
|
||||
} else {
|
||||
toBeDownloaded.add(volumeStore);
|
||||
}
|
||||
|
||||
} else { // Put them in right status
|
||||
volumeStore.setDownloadPercent(100);
|
||||
volumeStore.setDownloadState(Status.DOWNLOADED);
|
||||
volumeStore.setInstallPath(volInfo.getInstallPath());
|
||||
volumeStore.setSize(volInfo.getSize());
|
||||
volumeStore.setPhysicalSize(volInfo.getPhysicalSize());
|
||||
volumeStore.setLastUpdated(new Date());
|
||||
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
|
||||
|
||||
if (volume.getSize() == 0) {
|
||||
// Set volume size in volumes table
|
||||
volume.setSize(volInfo.getSize());
|
||||
_volumeDao.update(volumeStore.getVolumeId(), volume);
|
||||
}
|
||||
|
||||
if (volInfo.getSize() > 0) {
|
||||
try {
|
||||
String url = _volumeStoreDao.findByVolumeId(volume.getId()).getDownloadUrl();
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage,
|
||||
volInfo.getSize() - UriUtils.getRemoteSize(url));
|
||||
} catch (ResourceAllocationException e) {
|
||||
s_logger.warn(e.getMessage());
|
||||
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(),
|
||||
volume.getPodId(), e.getMessage(), e.getMessage());
|
||||
} finally {
|
||||
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Volume is not on secondary but we should download.
|
||||
if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
|
||||
s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
|
||||
toBeDownloaded.add(volumeStore);
|
||||
}
|
||||
}
|
||||
|
||||
//Download volumes which haven't been downloaded yet.
|
||||
if (toBeDownloaded.size() > 0) {
|
||||
for (VolumeDataStoreVO volumeHost : toBeDownloaded) {
|
||||
if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download
|
||||
continue;
|
||||
}
|
||||
s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName());
|
||||
//TODO: pass a callback later
|
||||
_dlMonitor.downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null);
|
||||
}
|
||||
}
|
||||
|
||||
//Delete volumes which are not present on DB.
|
||||
for (Long uniqueName : volumeInfos.keySet()) {
|
||||
TemplateProp vInfo = volumeInfos.get(uniqueName);
|
||||
DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getUri(), vInfo.getInstallPath());
|
||||
try {
|
||||
HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
|
||||
_agentMgr.sendToSecStorage(ssAhost, dtCommand, null);
|
||||
} catch (AgentUnavailableException e) {
|
||||
String err = "Failed to delete " + vInfo.getTemplateName() + " on image store " + storeId + " which isn't in the database";
|
||||
s_logger.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
String description = "Deleted volume " + vInfo.getTemplateName() + " on image store " + storeId + " since it isn't in the database";
|
||||
s_logger.info(description);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<Long, TemplateProp> listVolume(DataStore store) {
|
||||
ListVolumeCommand cmd = new ListVolumeCommand(store.getUri());
|
||||
HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
|
||||
Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
ListVolumeAnswer tanswer = (ListVolumeAnswer)answer;
|
||||
return tanswer.getTemplateInfo();
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Can not list volumes for image store " + store.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.template.Processor;
|
||||
import com.cloud.storage.template.Processor.FormatInfo;
|
||||
import com.cloud.storage.template.QCOW2Processor;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.storage.template.TemplateLocation;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
@ -2381,7 +2381,7 @@ ServerResource {
|
||||
return new Answer(cmd, false, " Failed to create storage pool");
|
||||
}
|
||||
|
||||
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
|
||||
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
|
||||
storagepool.getCapacity(), storagepool.getUsed(), tInfo);
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ import com.cloud.resource.hypervisor.HypervisorResource;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.Ternary;
|
||||
@ -458,7 +458,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource {
|
||||
|
||||
setupHeartBeat(pool.getUuid());
|
||||
OvmStoragePool.Details d = OvmStoragePool.getDetailsByUuid(_conn, pool.getUuid());
|
||||
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
|
||||
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, d.totalSpace, d.freeSpace, tInfo);
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -74,7 +74,7 @@ import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
@ -357,7 +357,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
|
||||
txn = Transaction.open(Transaction.CLOUD_DB);
|
||||
txn.close();
|
||||
}
|
||||
return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateInfo>());
|
||||
return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateProp>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -398,7 +398,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
|
||||
txn = Transaction.open(Transaction.CLOUD_DB);
|
||||
txn.close();
|
||||
}
|
||||
return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateInfo>());
|
||||
return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateProp>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -449,9 +449,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
|
||||
List<MockVolumeVO> volumes = _mockVolumeDao.findByStorageIdAndType(storage.getId(),
|
||||
MockVolumeType.VOLUME);
|
||||
|
||||
Map<Long, TemplateInfo> templateInfos = new HashMap<Long, TemplateInfo>();
|
||||
Map<Long, TemplateProp> templateInfos = new HashMap<Long, TemplateProp>();
|
||||
for (MockVolumeVO volume : volumes) {
|
||||
templateInfos.put(volume.getId(), new TemplateInfo(volume.getName(), volume.getPath()
|
||||
templateInfos.put(volume.getId(), new TemplateProp(volume.getName(), volume.getPath()
|
||||
.replaceAll(storage.getMountPoint(), ""), volume.getSize(), volume.getSize(), true, false));
|
||||
}
|
||||
txn.commit();
|
||||
@ -492,9 +492,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
|
||||
List<MockVolumeVO> templates = _mockVolumeDao.findByStorageIdAndType(storage.getId(),
|
||||
MockVolumeType.TEMPLATE);
|
||||
|
||||
Map<String, TemplateInfo> templateInfos = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> templateInfos = new HashMap<String, TemplateProp>();
|
||||
for (MockVolumeVO template : templates) {
|
||||
templateInfos.put(template.getName(), new TemplateInfo(template.getName(), template.getPath()
|
||||
templateInfos.put(template.getName(), new TemplateProp(template.getName(), template.getPath()
|
||||
.replaceAll(storage.getMountPoint(), ""), template.getSize(), template.getSize(), true, false));
|
||||
}
|
||||
txn.commit();
|
||||
|
||||
@ -51,7 +51,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.network.Networks.RouterPrivateIpStrategy;
|
||||
import com.cloud.simulator.MockVMVO;
|
||||
import com.cloud.storage.Storage.StorageResourceType;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
@ -168,7 +168,7 @@ public class AgentRoutingResource extends AgentStorageResource {
|
||||
}
|
||||
|
||||
private StartupStorageCommand initializeLocalSR() {
|
||||
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
|
||||
|
||||
StoragePoolInfo poolInfo = _simMgr.getLocalStorage(hostGuid);
|
||||
|
||||
|
||||
@ -210,7 +210,7 @@ import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.resource.StoragePoolResource;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
@ -3137,7 +3137,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary();
|
||||
long capacity = summary.getCapacity();
|
||||
long available = summary.getFreeSpace();
|
||||
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
|
||||
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
|
||||
return answer;
|
||||
} catch (Throwable e) {
|
||||
|
||||
@ -233,7 +233,7 @@ import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
@ -5287,7 +5287,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
s_logger.warn(msg);
|
||||
return new Answer(cmd, false, msg);
|
||||
}
|
||||
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
|
||||
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
|
||||
return answer;
|
||||
} catch (XenAPIException e) {
|
||||
|
||||
@ -25,6 +25,16 @@
|
||||
<artifactId>cloud-engine-storage-image</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage-volume</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage-snapshot</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
|
||||
@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
||||
import org.apache.cloudstack.storage.image.ImageStoreDriver;
|
||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||
import org.apache.cloudstack.storage.volume.VolumeObject;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
@ -118,11 +119,10 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
||||
TemplateObject tData = (TemplateObject)data;
|
||||
_downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
|
||||
} else if (data.getType() == DataObjectType.VOLUME) {
|
||||
VolumeVO vol = this.volumeDao.findById(data.getId());
|
||||
VolumeInfo volInfo = (VolumeInfo)data;
|
||||
VolumeObject volInfo = (VolumeObject)data;
|
||||
RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
|
||||
_downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(),
|
||||
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()));
|
||||
_downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
|
||||
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
|
||||
}
|
||||
|
||||
CreateCmdResult result = new CreateCmdResult(null, null);
|
||||
|
||||
@ -32,6 +32,16 @@
|
||||
<artifactId>cloud-engine-storage-image</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage-volume</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage-snapshot</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<defaultGoal>install</defaultGoal>
|
||||
|
||||
@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
||||
import org.apache.cloudstack.storage.image.ImageStoreDriver;
|
||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||
import org.apache.cloudstack.storage.volume.VolumeObject;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
@ -118,11 +119,10 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
|
||||
TemplateObject tData = (TemplateObject)data;
|
||||
_downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
|
||||
} else if (data.getType() == DataObjectType.VOLUME) {
|
||||
VolumeVO vol = this.volumeDao.findById(data.getId());
|
||||
VolumeInfo volInfo = (VolumeInfo)data;
|
||||
VolumeObject volInfo = (VolumeObject)data;
|
||||
RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
|
||||
_downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(),
|
||||
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()));
|
||||
_downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
|
||||
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
|
||||
}
|
||||
|
||||
CreateCmdResult result = new CreateCmdResult(null, null);
|
||||
|
||||
@ -25,6 +25,16 @@
|
||||
<artifactId>cloud-engine-storage-image</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage-volume</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage-snapshot</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
|
||||
@ -25,6 +25,16 @@
|
||||
<artifactId>cloud-engine-storage-image</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage-volume</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage-snapshot</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
|
||||
@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
||||
import org.apache.cloudstack.storage.image.ImageStoreDriver;
|
||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||
import org.apache.cloudstack.storage.volume.VolumeObject;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
@ -118,11 +119,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
|
||||
TemplateObject tData = (TemplateObject)data;
|
||||
_downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
|
||||
} else if (data.getType() == DataObjectType.VOLUME) {
|
||||
VolumeVO vol = this.volumeDao.findById(data.getId());
|
||||
VolumeInfo volInfo = (VolumeInfo)data;
|
||||
VolumeObject volInfo = (VolumeObject)data;
|
||||
RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
|
||||
_downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(),
|
||||
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()));
|
||||
_downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
|
||||
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
|
||||
}
|
||||
|
||||
CreateCmdResult result = new CreateCmdResult(null, null);
|
||||
|
||||
@ -1993,15 +1993,15 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
_accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), store.getDataCenterId());
|
||||
|
||||
// Verify that there are no live snapshot, template, volume on the image store to be deleted
|
||||
List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listLiveByStoreId(storeId);
|
||||
List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listByStoreId(storeId);
|
||||
if ( snapshots != null && snapshots.size() > 0 ){
|
||||
throw new CloudRuntimeException("Cannot delete image store with active snapshots backup!");
|
||||
}
|
||||
List<VolumeDataStoreVO> volumes = _volumeStoreDao.listLiveByStoreId(storeId);
|
||||
List<VolumeDataStoreVO> volumes = _volumeStoreDao.listByStoreId(storeId);
|
||||
if ( volumes != null && volumes.size() > 0 ){
|
||||
throw new CloudRuntimeException("Cannot delete image store with active volumes backup!");
|
||||
}
|
||||
List<TemplateDataStoreVO> templates = _templateStoreDao.listLiveByStoreId(storeId);
|
||||
List<TemplateDataStoreVO> templates = _templateStoreDao.listByStoreId(storeId);
|
||||
if ( templates != null && templates.size() > 0 ){
|
||||
throw new CloudRuntimeException("Cannot delete image store with active templates backup!");
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ package com.cloud.storage.download;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
@ -26,9 +27,15 @@ import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||
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.TemplateService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ -52,6 +59,8 @@ import com.cloud.exception.ConnectionException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
@ -117,57 +126,68 @@ public class DownloadListener implements Listener {
|
||||
public static final String DOWNLOAD_ABANDONED=Status.ABANDONED.toString();
|
||||
|
||||
|
||||
private HostVO sserver;
|
||||
private HostVO ssAgent;
|
||||
private HostVO _sserver;
|
||||
private HostVO _ssAgent;
|
||||
|
||||
private VMTemplateVO template;
|
||||
private VolumeVO volume;
|
||||
private boolean downloadActive = true;
|
||||
private VMTemplateVO _template;
|
||||
private VolumeVO _volume;
|
||||
private boolean _downloadActive = true;
|
||||
|
||||
private VolumeHostDao volumeHostDao;
|
||||
private VolumeHostDao _volumeHostDao;
|
||||
private VolumeDataStoreDao _volumeStoreDao;
|
||||
private VolumeDao _volumeDao;
|
||||
private StorageManager _storageMgr;
|
||||
private VMTemplateHostDao vmTemplateHostDao;
|
||||
private VMTemplateHostDao _vmTemplateHostDao;
|
||||
private TemplateDataStoreDao _vmTemplateStoreDao;
|
||||
private VMTemplateDao _vmTemplateDao;
|
||||
private ResourceLimitService _resourceLimitMgr;
|
||||
private AccountManager _accountMgr;
|
||||
private AlertManager _alertMgr;
|
||||
|
||||
private final DownloadMonitorImpl downloadMonitor;
|
||||
private final DownloadMonitorImpl _downloadMonitor;
|
||||
|
||||
private DownloadState currState;
|
||||
private DownloadState _currState;
|
||||
|
||||
private DownloadCommand cmd;
|
||||
private DownloadCommand _cmd;
|
||||
|
||||
private Timer timer;
|
||||
private Timer _timer;
|
||||
|
||||
private StatusTask statusTask;
|
||||
private TimeoutTask timeoutTask;
|
||||
private Date lastUpdated = new Date();
|
||||
private String jobId;
|
||||
private StatusTask _statusTask;
|
||||
private TimeoutTask _timeoutTask;
|
||||
private Date _lastUpdated = new Date();
|
||||
private String _jobId;
|
||||
|
||||
private final Map<String, DownloadState> stateMap = new HashMap<String, DownloadState>();
|
||||
private Long templateHostId;
|
||||
private Long volumeHostId;
|
||||
private final Map<String, DownloadState> _stateMap = new HashMap<String, DownloadState>();
|
||||
private Long _templateHostId;
|
||||
private Long _volumeHostId;
|
||||
|
||||
private DataStore sstore;
|
||||
private Long templateStoreId;
|
||||
private AsyncCompletionCallback<CreateCmdResult> callback;
|
||||
private DataStore _sstore;
|
||||
private Long _templateStoreId;
|
||||
private Long _volumeStoreId;
|
||||
private AsyncCompletionCallback<CreateCmdResult> _callback;
|
||||
|
||||
@Inject
|
||||
private ResourceManager _resourceMgr;
|
||||
@Inject
|
||||
private TemplateService _imageSrv;
|
||||
@Inject
|
||||
private DataStoreManager _storeMgr;
|
||||
@Inject
|
||||
private VolumeService _volumeSrv;
|
||||
|
||||
public DownloadListener(HostVO ssAgent, HostVO host, VMTemplateVO template, Timer _timer, VMTemplateHostDao dao, Long templHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) {
|
||||
this.ssAgent = ssAgent;
|
||||
this.sserver = host;
|
||||
this.template = template;
|
||||
this.vmTemplateHostDao = dao;
|
||||
this.downloadMonitor = downloadMonitor;
|
||||
this.cmd = cmd;
|
||||
this.templateHostId = templHostId;
|
||||
this._ssAgent = ssAgent;
|
||||
this._sserver = host;
|
||||
this._template = template;
|
||||
this._vmTemplateHostDao = dao;
|
||||
this._downloadMonitor = downloadMonitor;
|
||||
this._cmd = cmd;
|
||||
this._templateHostId = templHostId;
|
||||
initStateMachine();
|
||||
this.currState=getState(Status.NOT_DOWNLOADED.toString());
|
||||
this.timer = _timer;
|
||||
this.timeoutTask = new TimeoutTask(this);
|
||||
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
|
||||
this._currState=getState(Status.NOT_DOWNLOADED.toString());
|
||||
this._timer = _timer;
|
||||
this._timeoutTask = new TimeoutTask(this);
|
||||
this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
|
||||
this._vmTemplateDao = templateDao;
|
||||
this._resourceLimitMgr = _resourceLimitMgr;
|
||||
this._accountMgr = _accountMgr;
|
||||
@ -177,63 +197,64 @@ public class DownloadListener implements Listener {
|
||||
|
||||
// TODO: this constructor should be the one used for template only, remove other template constructor later
|
||||
public DownloadListener(HostVO ssAgent, DataStore store, VMTemplateVO template, Timer _timer, TemplateDataStoreDao dao, Long templStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||
this.ssAgent = ssAgent;
|
||||
this.sstore = store;
|
||||
this.template = template;
|
||||
this._ssAgent = ssAgent;
|
||||
this._sstore = store;
|
||||
this._template = template;
|
||||
this._vmTemplateStoreDao = dao;
|
||||
this.downloadMonitor = downloadMonitor;
|
||||
this.cmd = cmd;
|
||||
this.templateStoreId = templStoreId;
|
||||
this._downloadMonitor = downloadMonitor;
|
||||
this._cmd = cmd;
|
||||
this._templateStoreId = templStoreId;
|
||||
initStateMachine();
|
||||
this.currState=getState(Status.NOT_DOWNLOADED.toString());
|
||||
this.timer = _timer;
|
||||
this.timeoutTask = new TimeoutTask(this);
|
||||
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
|
||||
this._currState=getState(Status.NOT_DOWNLOADED.toString());
|
||||
this._timer = _timer;
|
||||
this._timeoutTask = new TimeoutTask(this);
|
||||
this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
|
||||
this._vmTemplateDao = templateDao;
|
||||
this._resourceLimitMgr = _resourceLimitMgr;
|
||||
this._accountMgr = _accountMgr;
|
||||
this._alertMgr = _alertMgr;
|
||||
this.callback = callback;
|
||||
this._callback = callback;
|
||||
updateDatabase(Status.NOT_DOWNLOADED, "");
|
||||
}
|
||||
|
||||
|
||||
public DownloadListener(HostVO ssAgent, HostVO host, VolumeVO volume, Timer _timer, VolumeHostDao dao, Long volHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) {
|
||||
this.ssAgent = ssAgent;
|
||||
this.sserver = host;
|
||||
this.volume = volume;
|
||||
this.volumeHostDao = dao;
|
||||
this.downloadMonitor = downloadMonitor;
|
||||
this.cmd = cmd;
|
||||
this.volumeHostId = volHostId;
|
||||
public DownloadListener(HostVO ssAgent, DataStore store, VolumeVO volume, Timer _timer, VolumeDataStoreDao dao, Long volStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||
this._ssAgent = ssAgent;
|
||||
this._sstore = store;
|
||||
this._volume = volume;
|
||||
this._volumeStoreDao = dao;
|
||||
this._downloadMonitor = downloadMonitor;
|
||||
this._cmd = cmd;
|
||||
this._volumeStoreId = volStoreId;
|
||||
initStateMachine();
|
||||
this.currState=getState(Status.NOT_DOWNLOADED.toString());
|
||||
this.timer = _timer;
|
||||
this.timeoutTask = new TimeoutTask(this);
|
||||
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
|
||||
this._currState=getState(Status.NOT_DOWNLOADED.toString());
|
||||
this._timer = _timer;
|
||||
this._timeoutTask = new TimeoutTask(this);
|
||||
this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
|
||||
this._volumeDao = volumeDao;
|
||||
this._storageMgr = storageMgr;
|
||||
this._resourceLimitMgr = _resourceLimitMgr;
|
||||
this._accountMgr = _accountMgr;
|
||||
this._alertMgr = _alertMgr;
|
||||
this._callback = callback;
|
||||
updateDatabase(Status.NOT_DOWNLOADED, "");
|
||||
}
|
||||
|
||||
|
||||
public void setCurrState(VMTemplateHostVO.Status currState) {
|
||||
this.currState = getState(currState.toString());
|
||||
this._currState = getState(currState.toString());
|
||||
}
|
||||
|
||||
private void initStateMachine() {
|
||||
stateMap.put(Status.NOT_DOWNLOADED.toString(), new NotDownloadedState(this));
|
||||
stateMap.put(Status.DOWNLOADED.toString(), new DownloadCompleteState(this));
|
||||
stateMap.put(Status.DOWNLOAD_ERROR.toString(), new DownloadErrorState(this));
|
||||
stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this));
|
||||
stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this));
|
||||
_stateMap.put(Status.NOT_DOWNLOADED.toString(), new NotDownloadedState(this));
|
||||
_stateMap.put(Status.DOWNLOADED.toString(), new DownloadCompleteState(this));
|
||||
_stateMap.put(Status.DOWNLOAD_ERROR.toString(), new DownloadErrorState(this));
|
||||
_stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this));
|
||||
_stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this));
|
||||
}
|
||||
|
||||
private DownloadState getState(String stateName) {
|
||||
return stateMap.get(stateName);
|
||||
return _stateMap.get(stateName);
|
||||
}
|
||||
|
||||
public void sendCommand(RequestType reqType) {
|
||||
@ -243,10 +264,10 @@ public class DownloadListener implements Listener {
|
||||
}
|
||||
try {
|
||||
DownloadProgressCommand dcmd = new DownloadProgressCommand(getCommand(), getJobId(), reqType);
|
||||
if (template == null){
|
||||
if (_template == null){
|
||||
dcmd.setResourceType(ResourceType.VOLUME);
|
||||
}
|
||||
downloadMonitor.send(ssAgent.getId(), dcmd, this);
|
||||
_downloadMonitor.send(_ssAgent.getId(), dcmd, this);
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.debug("Send command failed", e);
|
||||
setDisconnected();
|
||||
@ -264,63 +285,63 @@ public class DownloadListener implements Listener {
|
||||
}
|
||||
|
||||
public void logDisconnect() {
|
||||
if (template != null){
|
||||
s_logger.warn("Unable to monitor download progress of " + template.getName() + " at host " + sserver.getName());
|
||||
if (_template != null){
|
||||
s_logger.warn("Unable to monitor download progress of " + _template.getName() + " at host " + _sserver.getName());
|
||||
}else {
|
||||
s_logger.warn("Unable to monitor download progress of " + volume.getName() + " at host " + sserver.getName());
|
||||
s_logger.warn("Unable to monitor download progress of " + _volume.getName() + " at host " + _sserver.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void updateDatabase(Status state, String errorString) {
|
||||
if (template != null){
|
||||
VMTemplateHostVO vo = vmTemplateHostDao.createForUpdate();
|
||||
if (_template != null){
|
||||
VMTemplateHostVO vo = _vmTemplateHostDao.createForUpdate();
|
||||
vo.setDownloadState(state);
|
||||
vo.setLastUpdated(new Date());
|
||||
vo.setErrorString(errorString);
|
||||
vmTemplateHostDao.update(getTemplateHostId(), vo);
|
||||
_vmTemplateHostDao.update(getTemplateHostId(), vo);
|
||||
}else {
|
||||
VolumeHostVO vo = volumeHostDao.createForUpdate();
|
||||
VolumeHostVO vo = _volumeHostDao.createForUpdate();
|
||||
vo.setDownloadState(state);
|
||||
vo.setLastUpdated(new Date());
|
||||
vo.setErrorString(errorString);
|
||||
volumeHostDao.update(getVolumeHostId(), vo);
|
||||
_volumeHostDao.update(getVolumeHostId(), vo);
|
||||
}
|
||||
}
|
||||
|
||||
public void log(String message, Level level) {
|
||||
if (template != null){
|
||||
s_logger.log(level, message + ", template=" + template.getName() + " at host " + sserver.getName());
|
||||
if (_template != null){
|
||||
s_logger.log(level, message + ", template=" + _template.getName() + " at host " + _sserver.getName());
|
||||
}else {
|
||||
s_logger.log(level, message + ", volume=" + volume.getName() + " at host " + sserver.getName());
|
||||
s_logger.log(level, message + ", volume=" + _volume.getName() + " at host " + _sserver.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private Long getTemplateHostId() {
|
||||
if (templateHostId == null){
|
||||
VMTemplateHostVO templHost = vmTemplateHostDao.findByHostTemplate(sserver.getId(), template.getId());
|
||||
templateHostId = templHost.getId();
|
||||
if (_templateHostId == null){
|
||||
VMTemplateHostVO templHost = _vmTemplateHostDao.findByHostTemplate(_sserver.getId(), _template.getId());
|
||||
_templateHostId = templHost.getId();
|
||||
}
|
||||
return templateHostId;
|
||||
return _templateHostId;
|
||||
}
|
||||
|
||||
private Long getTemplateStoreId() {
|
||||
if (templateStoreId == null){
|
||||
TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(sstore.getId(), template.getId());
|
||||
templateStoreId = templStore.getId();
|
||||
if (_templateStoreId == null){
|
||||
TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(_sstore.getId(), _template.getId());
|
||||
_templateStoreId = templStore.getId();
|
||||
}
|
||||
return templateStoreId;
|
||||
return _templateStoreId;
|
||||
}
|
||||
|
||||
private Long getVolumeHostId() {
|
||||
if (volumeHostId == null){
|
||||
VolumeHostVO volHost = volumeHostDao.findByHostVolume(sserver.getId(), volume.getId());
|
||||
volumeHostId = volHost.getId();
|
||||
if (_volumeHostId == null){
|
||||
VolumeHostVO volHost = _volumeHostDao.findByHostVolume(_sserver.getId(), _volume.getId());
|
||||
_volumeHostId = volHost.getId();
|
||||
}
|
||||
return volumeHostId;
|
||||
return _volumeHostId;
|
||||
}
|
||||
|
||||
public DownloadListener(DownloadMonitorImpl monitor) {
|
||||
downloadMonitor = monitor;
|
||||
_downloadMonitor = monitor;
|
||||
}
|
||||
|
||||
|
||||
@ -350,15 +371,15 @@ public class DownloadListener implements Listener {
|
||||
}
|
||||
|
||||
private synchronized void transition(DownloadEvent event, Object evtObj) {
|
||||
if (currState == null) {
|
||||
if (_currState == null) {
|
||||
return;
|
||||
}
|
||||
String prevName = currState.getName();
|
||||
String nextState = currState.handleEvent(event, evtObj);
|
||||
String prevName = _currState.getName();
|
||||
String nextState = _currState.handleEvent(event, evtObj);
|
||||
if (nextState != null) {
|
||||
currState = getState(nextState);
|
||||
if (currState != null) {
|
||||
currState.onEntry(prevName, event, evtObj);
|
||||
_currState = getState(nextState);
|
||||
if (_currState != null) {
|
||||
_currState.onEntry(prevName, event, evtObj);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Invalid next state: currState="+prevName+", evt="+event + ", next=" + nextState);
|
||||
}
|
||||
@ -368,7 +389,7 @@ public class DownloadListener implements Listener {
|
||||
}
|
||||
|
||||
public synchronized void updateDatabase(DownloadAnswer answer) {
|
||||
if (template != null){
|
||||
if (_template != null){
|
||||
TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate();
|
||||
updateBuilder.setDownloadPercent(answer.getDownloadPct());
|
||||
updateBuilder.setDownloadState(answer.getDownloadStatus());
|
||||
@ -380,40 +401,58 @@ public class DownloadListener implements Listener {
|
||||
updateBuilder.setSize(answer.getTemplateSize());
|
||||
updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
|
||||
|
||||
// only invoke callback when Download is completed or errored so that callback will update template_store_ref state column
|
||||
Status dndStatus = answer.getDownloadStatus();
|
||||
// if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){
|
||||
if ( _callback != null ){
|
||||
if (dndStatus == Status.DOWNLOAD_ERROR){
|
||||
CreateCmdResult result = new CreateCmdResult(null, null);
|
||||
result.setSucess(false);
|
||||
result.setResult("Download template failed");
|
||||
_callback.complete(result);
|
||||
} else if (dndStatus == Status.DOWNLOADED){
|
||||
CreateCmdResult result = new CreateCmdResult(null, null);
|
||||
_callback.complete(result);
|
||||
}
|
||||
}
|
||||
else{
|
||||
// no callback specified, just update state here
|
||||
if (dndStatus == Status.DOWNLOAD_ERROR){
|
||||
updateBuilder.setState(ObjectInDataStoreStateMachine.State.Failed);
|
||||
} else if (dndStatus == Status.DOWNLOAD_IN_PROGRESS){
|
||||
updateBuilder.setState(ObjectInDataStoreStateMachine.State.Creating2);
|
||||
} else if (dndStatus == Status.DOWNLOADED){
|
||||
updateBuilder.setState(ObjectInDataStoreStateMachine.State.Ready);
|
||||
}
|
||||
}
|
||||
// }
|
||||
_vmTemplateStoreDao.update(getTemplateStoreId(), updateBuilder);
|
||||
|
||||
if (answer.getCheckSum() != null) {
|
||||
VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate();
|
||||
templateDaoBuilder.setChecksum(answer.getCheckSum());
|
||||
_vmTemplateDao.update(template.getId(), templateDaoBuilder);
|
||||
_vmTemplateDao.update(_template.getId(), templateDaoBuilder);
|
||||
}
|
||||
|
||||
if (answer.getTemplateSize() > 0) {
|
||||
//long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId();
|
||||
long accountId = template.getAccountId();
|
||||
long accountId = _template.getAccountId();
|
||||
try {
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage,
|
||||
answer.getTemplateSize() - UriUtils.getRemoteSize(template.getUrl()));
|
||||
answer.getTemplateSize() - UriUtils.getRemoteSize(_template.getUrl()));
|
||||
} catch (ResourceAllocationException e) {
|
||||
s_logger.warn(e.getMessage());
|
||||
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, sserver.getDataCenterId(),
|
||||
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _sserver.getDataCenterId(),
|
||||
null, e.getMessage(), e.getMessage());
|
||||
} finally {
|
||||
_resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
|
||||
}
|
||||
}
|
||||
// only invoke callback when Download is completed or errored so that callback will update template_store_ref state column
|
||||
Status dndStatus = answer.getDownloadStatus();
|
||||
if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){
|
||||
if ( callback != null ){
|
||||
CreateCmdResult result = new CreateCmdResult(null, null);
|
||||
callback.complete(result);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
VolumeHostVO updateBuilder = volumeHostDao.createForUpdate();
|
||||
VolumeHostVO updateBuilder = _volumeHostDao.createForUpdate();
|
||||
updateBuilder.setDownloadPercent(answer.getDownloadPct());
|
||||
updateBuilder.setDownloadState(answer.getDownloadStatus());
|
||||
updateBuilder.setLastUpdated(new Date());
|
||||
@ -424,25 +463,25 @@ public class DownloadListener implements Listener {
|
||||
updateBuilder.setSize(answer.getTemplateSize());
|
||||
updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
|
||||
|
||||
volumeHostDao.update(getVolumeHostId(), updateBuilder);
|
||||
_volumeHostDao.update(getVolumeHostId(), updateBuilder);
|
||||
|
||||
// Update volume size in Volume table.
|
||||
VolumeVO updateVolume = _volumeDao.createForUpdate();
|
||||
updateVolume.setSize(answer.getTemplateSize());
|
||||
_volumeDao.update(volume.getId(), updateVolume);
|
||||
_volumeDao.update(_volume.getId(), updateVolume);
|
||||
|
||||
if (answer.getTemplateSize() > 0) {
|
||||
try {
|
||||
String url = volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl();
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
|
||||
String url = _volumeHostDao.findByVolumeId(_volume.getId()).getDownloadUrl();
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(_volume.getAccountId()),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage,
|
||||
answer.getTemplateSize() - UriUtils.getRemoteSize(url));
|
||||
} catch (ResourceAllocationException e) {
|
||||
s_logger.warn(e.getMessage());
|
||||
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(),
|
||||
volume.getPodId(), e.getMessage(), e.getMessage());
|
||||
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _volume.getDataCenterId(),
|
||||
_volume.getPodId(), e.getMessage(), e.getMessage());
|
||||
} finally {
|
||||
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
|
||||
_resourceLimitMgr.recalculateResourceCount(_volume.getAccountId(), _volume.getDomainId(),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
|
||||
}
|
||||
}
|
||||
@ -474,8 +513,12 @@ public class DownloadListener implements Listener {
|
||||
@Override
|
||||
public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
|
||||
if (cmd instanceof StartupRoutingCommand) {
|
||||
|
||||
downloadMonitor.handleSysTemplateDownload(agent);
|
||||
List<HypervisorType> hypers = _resourceMgr.listAvailHypervisorInZone(agent.getId(), agent.getDataCenterId());
|
||||
HypervisorType hostHyper = agent.getHypervisorType();
|
||||
if (hypers.contains(hostHyper)) {
|
||||
return;
|
||||
}
|
||||
_imageSrv.handleSysTemplateDownload(hostHyper, agent.getDataCenterId());
|
||||
}
|
||||
/* This can be removed since
|
||||
else if ( cmd instanceof StartupStorageCommand) {
|
||||
@ -488,16 +531,20 @@ public class DownloadListener implements Listener {
|
||||
}
|
||||
}*/
|
||||
else if ( cmd instanceof StartupSecondaryStorageCommand ) {
|
||||
downloadMonitor.handleSync(agent.getDataCenterId());
|
||||
List<DataStore> imageStores = this._storeMgr.getImageStoresByScope(new ZoneScope(agent.getDataCenterId()));
|
||||
for (DataStore store : imageStores){
|
||||
_volumeSrv.handleVolumeSync(store);
|
||||
_imageSrv.handleTemplateSync(store);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCommand(DownloadCommand _cmd) {
|
||||
this.cmd = _cmd;
|
||||
this._cmd = _cmd;
|
||||
}
|
||||
|
||||
public DownloadCommand getCommand() {
|
||||
return cmd;
|
||||
return _cmd;
|
||||
}
|
||||
|
||||
|
||||
@ -506,63 +553,63 @@ public class DownloadListener implements Listener {
|
||||
}
|
||||
|
||||
public void setJobId(String _jobId) {
|
||||
this.jobId = _jobId;
|
||||
this._jobId = _jobId;
|
||||
}
|
||||
|
||||
public String getJobId() {
|
||||
return jobId;
|
||||
return _jobId;
|
||||
}
|
||||
|
||||
public void scheduleStatusCheck(RequestType request) {
|
||||
if (statusTask != null) statusTask.cancel();
|
||||
if (_statusTask != null) _statusTask.cancel();
|
||||
|
||||
statusTask = new StatusTask(this, request);
|
||||
timer.schedule(statusTask, STATUS_POLL_INTERVAL);
|
||||
_statusTask = new StatusTask(this, request);
|
||||
_timer.schedule(_statusTask, STATUS_POLL_INTERVAL);
|
||||
}
|
||||
|
||||
public void scheduleTimeoutTask(long delay) {
|
||||
if (timeoutTask != null) timeoutTask.cancel();
|
||||
if (_timeoutTask != null) _timeoutTask.cancel();
|
||||
|
||||
timeoutTask = new TimeoutTask(this);
|
||||
timer.schedule(timeoutTask, delay);
|
||||
_timeoutTask = new TimeoutTask(this);
|
||||
_timer.schedule(_timeoutTask, delay);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
log("Scheduling timeout at " + delay + " ms", Level.DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
public void scheduleImmediateStatusCheck(RequestType request) {
|
||||
if (statusTask != null) statusTask.cancel();
|
||||
statusTask = new StatusTask(this, request);
|
||||
timer.schedule(statusTask, SMALL_DELAY);
|
||||
if (_statusTask != null) _statusTask.cancel();
|
||||
_statusTask = new StatusTask(this, request);
|
||||
_timer.schedule(_statusTask, SMALL_DELAY);
|
||||
}
|
||||
|
||||
public boolean isDownloadActive() {
|
||||
return downloadActive;
|
||||
return _downloadActive;
|
||||
}
|
||||
|
||||
public void cancelStatusTask() {
|
||||
if (statusTask != null) statusTask.cancel();
|
||||
if (_statusTask != null) _statusTask.cancel();
|
||||
}
|
||||
|
||||
public Date getLastUpdated() {
|
||||
return lastUpdated;
|
||||
return _lastUpdated;
|
||||
}
|
||||
|
||||
public void setLastUpdated() {
|
||||
lastUpdated = new Date();
|
||||
_lastUpdated = new Date();
|
||||
}
|
||||
|
||||
public void setDownloadInactive(Status reason) {
|
||||
downloadActive=false;
|
||||
if (template != null){
|
||||
downloadMonitor.handleDownloadEvent(sserver, template, reason);
|
||||
_downloadActive=false;
|
||||
if (_template != null){
|
||||
_downloadMonitor.handleDownloadEvent(_sserver, _template, reason);
|
||||
}else {
|
||||
downloadMonitor.handleDownloadEvent(sserver, volume, reason);
|
||||
_downloadMonitor.handleDownloadEvent(_sserver, _volume, reason);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelTimeoutTask() {
|
||||
if (timeoutTask != null) timeoutTask.cancel();
|
||||
if (_timeoutTask != null) _timeoutTask.cancel();
|
||||
}
|
||||
|
||||
public void logDownloadStart() {
|
||||
|
||||
@ -16,8 +16,6 @@
|
||||
// under the License.
|
||||
package com.cloud.storage.download;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
@ -28,7 +26,6 @@ import com.cloud.host.HostVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.utils.component.Manager;
|
||||
|
||||
/**
|
||||
@ -37,23 +34,17 @@ import com.cloud.utils.component.Manager;
|
||||
*/
|
||||
public interface DownloadMonitor extends Manager{
|
||||
|
||||
public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback);
|
||||
public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback);
|
||||
|
||||
public void cancelAllDownloads(Long templateId);
|
||||
|
||||
public void handleTemplateSync(DataStore store);
|
||||
|
||||
public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer)
|
||||
throws StorageUnavailableException;
|
||||
|
||||
void handleSysTemplateDownload(HostVO hostId);
|
||||
//void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateProp> templateInfos);
|
||||
|
||||
void handleSync(Long dcId);
|
||||
//public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format);
|
||||
|
||||
void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos);
|
||||
|
||||
boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format);
|
||||
|
||||
void handleVolumeSync(HostVO ssHost);
|
||||
public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback<CreateCmdResult> callback);
|
||||
|
||||
}
|
||||
@ -18,12 +18,9 @@ package com.cloud.storage.download;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -33,19 +30,17 @@ import javax.inject.Inject;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||
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.ZoneScope;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.Listener;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
||||
import com.cloud.agent.api.storage.DeleteVolumeCommand;
|
||||
import com.cloud.agent.api.storage.DownloadCommand;
|
||||
|
||||
import com.cloud.agent.api.storage.DownloadCommand.Proxy;
|
||||
@ -53,16 +48,10 @@ import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
|
||||
import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
|
||||
|
||||
import com.cloud.agent.api.storage.DownloadProgressCommand;
|
||||
import com.cloud.agent.api.storage.ListTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.ListTemplateCommand;
|
||||
import com.cloud.agent.api.storage.ListVolumeAnswer;
|
||||
import com.cloud.agent.api.storage.ListVolumeCommand;
|
||||
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.event.EventTypes;
|
||||
@ -70,9 +59,7 @@ import com.cloud.event.UsageEventUtils;
|
||||
import com.cloud.event.dao.UsageEventDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
@ -80,12 +67,10 @@ import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.SwiftVO;
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.storage.VMTemplateZoneVO;
|
||||
import com.cloud.storage.VolumeHostVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
@ -101,12 +86,10 @@ import com.cloud.storage.dao.VolumeHostDao;
|
||||
import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
||||
import com.cloud.storage.swift.SwiftManager;
|
||||
import com.cloud.storage.template.TemplateConstants;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
@ -117,14 +100,10 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.SecondaryStorageVm;
|
||||
import com.cloud.vm.SecondaryStorageVmVO;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
|
||||
|
||||
@ -152,6 +131,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
@Inject
|
||||
VolumeHostDao _volumeHostDao;
|
||||
@Inject
|
||||
VolumeDataStoreDao _volumeStoreDao;
|
||||
@Inject
|
||||
AlertManager _alertMgr;
|
||||
@Inject
|
||||
protected SwiftManager _swiftMgr;
|
||||
@ -206,6 +187,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
final Map<TemplateDataStoreVO, DownloadListener> _listenerTemplateMap = new ConcurrentHashMap<TemplateDataStoreVO, DownloadListener>();
|
||||
final Map<VMTemplateHostVO, DownloadListener> _listenerMap = new ConcurrentHashMap<VMTemplateHostVO, DownloadListener>();
|
||||
final Map<VolumeHostVO, DownloadListener> _listenerVolumeMap = new ConcurrentHashMap<VolumeHostVO, DownloadListener>();
|
||||
final Map<VolumeDataStoreVO, DownloadListener> _listenerVolMap = new ConcurrentHashMap<VolumeDataStoreVO, DownloadListener>();
|
||||
|
||||
|
||||
public void send(Long hostId, Command cmd, Listener listener) throws AgentUnavailableException {
|
||||
@ -256,7 +238,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
|
||||
public boolean isTemplateUpdateable(Long templateId, Long storeId) {
|
||||
List<TemplateDataStoreVO> downloadsInProgress =
|
||||
_vmTemplateStoreDao.listByTemplateStoreStatus(templateId, storeId, ObjectInDataStoreStateMachine.State.Creating, ObjectInDataStoreStateMachine.State.Creating2, ObjectInDataStoreStateMachine.State.Ready);
|
||||
_vmTemplateStoreDao.listByTemplateStoreDownloadStatus(templateId, storeId, Status.DOWNLOAD_IN_PROGRESS, Status.DOWNLOADED );
|
||||
return (downloadsInProgress.size() == 0);
|
||||
}
|
||||
|
||||
@ -370,7 +352,11 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
TemplateDataStoreVO vmTemplateStore = null;
|
||||
|
||||
vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
|
||||
// we should already persist one entry in template_store_ref table, so vmTemplateStore should not be null
|
||||
if (vmTemplateStore == null) {
|
||||
// This method can be invoked other places, for example, handleTemplateSync, in that case, vmTemplateStore may be null
|
||||
vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl());
|
||||
_vmTemplateStoreDao.persist(vmTemplateStore);
|
||||
} else
|
||||
if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) {
|
||||
downloadJobExists = true;
|
||||
}
|
||||
@ -420,42 +406,33 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
|
||||
|
||||
@Override
|
||||
public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||
public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||
long templateId = template.getId();
|
||||
if (isTemplateUpdateable(templateId, store.getId())) {
|
||||
if ( template != null && template.getUrl() != null ){
|
||||
initiateTemplateDownload(template, store, callback);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format) {
|
||||
|
||||
List<HostVO> ssHosts = _ssvmMgr.listAllTypesSecondaryStorageHostsInOneZone(zoneId);
|
||||
Collections.shuffle(ssHosts);
|
||||
HostVO ssHost = ssHosts.get(0);
|
||||
downloadVolumeToStorage(volume, ssHost, url, checkSum, format);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void downloadVolumeToStorage(VolumeVO volume, HostVO sserver, String url, String checkSum, ImageFormat format) {
|
||||
public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||
boolean downloadJobExists = false;
|
||||
VolumeHostVO volumeHost = null;
|
||||
VolumeDataStoreVO volumeHost = null;
|
||||
|
||||
volumeHost = _volumeHostDao.findByHostVolume(sserver.getId(), volume.getId());
|
||||
volumeHost = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
|
||||
if (volumeHost == null) {
|
||||
volumeHost = new VolumeHostVO(sserver.getId(), volume.getId(), sserver.getDataCenterId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null,
|
||||
volumeHost = new VolumeDataStoreVO(store.getId(), volume.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null,
|
||||
"jobid0000", null, url, checkSum, format);
|
||||
_volumeHostDao.persist(volumeHost);
|
||||
_volumeStoreDao.persist(volumeHost);
|
||||
} else if ((volumeHost.getJobId() != null) && (volumeHost.getJobId().length() > 2)) {
|
||||
downloadJobExists = true;
|
||||
}
|
||||
|
||||
|
||||
Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes();
|
||||
String secUrl = sserver.getStorageUrl();
|
||||
String secUrl = store.getUri();
|
||||
if(volumeHost != null) {
|
||||
start();
|
||||
DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format);
|
||||
@ -465,45 +442,35 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
dcmd.setResourceType(ResourceType.VOLUME);
|
||||
}
|
||||
|
||||
HostVO ssvm = _ssvmMgr.pickSsvmHost(sserver);
|
||||
if( ssvm == null ) {
|
||||
s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName());
|
||||
HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
|
||||
if( ssAhost == null ) {
|
||||
s_logger.warn("There is no secondary storage VM for image store " + store.getName());
|
||||
return;
|
||||
}
|
||||
DownloadListener dl = new DownloadListener(ssvm, sserver, volume, _timer, _volumeHostDao, volumeHost.getId(),
|
||||
this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr);
|
||||
DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(),
|
||||
this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback);
|
||||
|
||||
if (downloadJobExists) {
|
||||
dl.setCurrState(volumeHost.getDownloadState());
|
||||
}
|
||||
DownloadListener old = null;
|
||||
synchronized (_listenerVolumeMap) {
|
||||
old = _listenerVolumeMap.put(volumeHost, dl);
|
||||
synchronized (_listenerVolMap) {
|
||||
old = _listenerVolMap.put(volumeHost, dl);
|
||||
}
|
||||
if( old != null ) {
|
||||
old.abandon();
|
||||
}
|
||||
|
||||
try {
|
||||
send(ssvm.getId(), dcmd, dl);
|
||||
send(ssAhost.getId(), dcmd, dl);
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + sserver.getName(), e);
|
||||
s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + store.getName(), e);
|
||||
dl.setDisconnected();
|
||||
dl.scheduleStatusCheck(RequestType.GET_OR_RESTART);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private void initiateTemplateDownload(Long templateId, DataStore store) {
|
||||
VMTemplateVO template = _templateDao.findById(templateId);
|
||||
if (template != null && (template.getUrl() != null)) {
|
||||
//find all storage hosts and tell them to initiate download
|
||||
downloadTemplateToStorage(template, store);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
@DB
|
||||
public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) {
|
||||
@ -583,62 +550,18 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSysTemplateDownload(HostVO host) {
|
||||
List<HypervisorType> hypers = _resourceMgr.listAvailHypervisorInZone(host.getId(), host.getDataCenterId());
|
||||
HypervisorType hostHyper = host.getHypervisorType();
|
||||
if (hypers.contains(hostHyper)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
|
||||
List<DataStore> ssHosts = this.storeMgr.getImageStoresByScope(new ZoneScope(host.getDataCenterId()));
|
||||
if (ssHosts == null || ssHosts.isEmpty()){
|
||||
return;
|
||||
}
|
||||
/*
|
||||
List<HostVO> ssHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.SecondaryStorage, host.getDataCenterId());
|
||||
if (ssHosts == null || ssHosts.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
/*Download all the templates in zone with the same hypervisortype*/
|
||||
for ( DataStore ssHost : ssHosts) {
|
||||
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
|
||||
List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
|
||||
|
||||
|
||||
for (VMTemplateVO rtngTmplt : rtngTmplts) {
|
||||
if (rtngTmplt.getHypervisorType() == hostHyper) {
|
||||
toBeDownloaded.add(rtngTmplt);
|
||||
}
|
||||
}
|
||||
|
||||
for (VMTemplateVO builtinTmplt : defaultBuiltin) {
|
||||
if (builtinTmplt.getHypervisorType() == hostHyper) {
|
||||
toBeDownloaded.add(builtinTmplt);
|
||||
}
|
||||
}
|
||||
|
||||
for (VMTemplateVO template: toBeDownloaded) {
|
||||
VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(ssHost.getId(), template.getId());
|
||||
if (tmpltHost == null || tmpltHost.getDownloadState() != Status.DOWNLOADED) {
|
||||
//TODO: pass callback here
|
||||
initiateTemplateDownload(template, ssHost, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos){
|
||||
public void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateProp> templateInfos){
|
||||
if ( templateInfos == null ) {
|
||||
return;
|
||||
}
|
||||
Long hostId = host.getId();
|
||||
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
|
||||
for ( VMTemplateVO tmplt : rtngTmplts ) {
|
||||
TemplateInfo tmpltInfo = templateInfos.get(tmplt.getUniqueName());
|
||||
TemplateProp tmpltInfo = templateInfos.get(tmplt.getUniqueName());
|
||||
if ( tmpltInfo == null ) {
|
||||
continue;
|
||||
}
|
||||
@ -651,354 +574,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void handleSync(Long dcId) {
|
||||
if (dcId != null) {
|
||||
List<HostVO> ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dcId);
|
||||
for (HostVO ssHost : ssHosts) {
|
||||
//handleTemplateSync(ssHost);
|
||||
handleVolumeSync(ssHost);
|
||||
}
|
||||
}
|
||||
List<DataStore> imageStores = this.storeMgr.getImageStoresByScope(new ZoneScope(dcId));
|
||||
for (DataStore store : imageStores){
|
||||
handleTemplateSync(store);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, TemplateInfo> listTemplate(DataStore ssHost) {
|
||||
ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getUri());
|
||||
HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssHost);
|
||||
Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
ListTemplateAnswer tanswer = (ListTemplateAnswer)answer;
|
||||
return tanswer.getTemplateInfo();
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("can not list template for secondary storage host " + ssHost.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<Long, TemplateInfo> listVolume(HostVO ssHost) {
|
||||
ListVolumeCommand cmd = new ListVolumeCommand(ssHost.getStorageUrl());
|
||||
Answer answer = _agentMgr.sendToSecStorage(ssHost, cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
ListVolumeAnswer tanswer = (ListVolumeAnswer)answer;
|
||||
return tanswer.getTemplateInfo();
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Can not list volumes for secondary storage host " + ssHost.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, TemplateInfo> listTemplate(SwiftVO swift) {
|
||||
if (swift == null) {
|
||||
return null;
|
||||
}
|
||||
ListTemplateCommand cmd = new ListTemplateCommand(swift.toSwiftTO());
|
||||
Answer answer = _agentMgr.sendToSSVM(null, cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
ListTemplateAnswer tanswer = (ListTemplateAnswer) answer;
|
||||
return tanswer.getTemplateInfo();
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("can not list template for swift " + swift);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleVolumeSync(HostVO ssHost) {
|
||||
if (ssHost == null) {
|
||||
s_logger.warn("Huh? ssHost is null");
|
||||
return;
|
||||
}
|
||||
long sserverId = ssHost.getId();
|
||||
if (!(ssHost.getType() == Host.Type.SecondaryStorage || ssHost.getType() == Host.Type.LocalSecondaryStorage)) {
|
||||
s_logger.warn("Huh? Agent id " + sserverId + " is not secondary storage host");
|
||||
return;
|
||||
}
|
||||
|
||||
Map<Long, TemplateInfo> volumeInfos = listVolume(ssHost);
|
||||
if (volumeInfos == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<VolumeHostVO> dbVolumes = _volumeHostDao.listBySecStorage(sserverId);
|
||||
List<VolumeHostVO> toBeDownloaded = new ArrayList<VolumeHostVO>(dbVolumes);
|
||||
for (VolumeHostVO volumeHost : dbVolumes){
|
||||
VolumeVO volume = _volumeDao.findById(volumeHost.getVolumeId());
|
||||
//Exists then don't download
|
||||
if (volumeInfos.containsKey(volume.getId())){
|
||||
TemplateInfo volInfo = volumeInfos.remove(volume.getId());
|
||||
toBeDownloaded.remove(volumeHost);
|
||||
s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume host table");
|
||||
if (volumeHost.getDownloadState() != Status.DOWNLOADED) {
|
||||
volumeHost.setErrorString("");
|
||||
}
|
||||
if (volInfo.isCorrupted()) {
|
||||
volumeHost.setDownloadState(Status.DOWNLOAD_ERROR);
|
||||
String msg = "Volume " + volume.getUuid() + " is corrupted on secondary storage ";
|
||||
volumeHost.setErrorString(msg);
|
||||
s_logger.info("msg");
|
||||
if (volumeHost.getDownloadUrl() == null) {
|
||||
msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in secondary storage: " + volumeHost.getHostId();
|
||||
s_logger.warn(msg);
|
||||
} else {
|
||||
toBeDownloaded.add(volumeHost);
|
||||
}
|
||||
|
||||
} else { // Put them in right status
|
||||
volumeHost.setDownloadPercent(100);
|
||||
volumeHost.setDownloadState(Status.DOWNLOADED);
|
||||
volumeHost.setInstallPath(volInfo.getInstallPath());
|
||||
volumeHost.setSize(volInfo.getSize());
|
||||
volumeHost.setPhysicalSize(volInfo.getPhysicalSize());
|
||||
volumeHost.setLastUpdated(new Date());
|
||||
_volumeHostDao.update(volumeHost.getId(), volumeHost);
|
||||
|
||||
if (volume.getSize() == 0) {
|
||||
// Set volume size in volumes table
|
||||
volume.setSize(volInfo.getSize());
|
||||
_volumeDao.update(volumeHost.getVolumeId(), volume);
|
||||
}
|
||||
|
||||
if (volInfo.getSize() > 0) {
|
||||
try {
|
||||
String url = _volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl();
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage,
|
||||
volInfo.getSize() - UriUtils.getRemoteSize(url));
|
||||
} catch (ResourceAllocationException e) {
|
||||
s_logger.warn(e.getMessage());
|
||||
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(),
|
||||
volume.getPodId(), e.getMessage(), e.getMessage());
|
||||
} finally {
|
||||
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Volume is not on secondary but we should download.
|
||||
if (volumeHost.getDownloadState() != Status.DOWNLOADED) {
|
||||
s_logger.info("Volume Sync did not find " + volume.getName() + " ready on server " + sserverId + ", will request download to start/resume shortly");
|
||||
toBeDownloaded.add(volumeHost);
|
||||
}
|
||||
}
|
||||
|
||||
//Download volumes which haven't been downloaded yet.
|
||||
if (toBeDownloaded.size() > 0) {
|
||||
for (VolumeHostVO volumeHost : toBeDownloaded) {
|
||||
if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download
|
||||
continue;
|
||||
}
|
||||
s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + ssHost.getName());
|
||||
downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), ssHost, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat());
|
||||
}
|
||||
}
|
||||
|
||||
//Delete volumes which are not present on DB.
|
||||
for (Long uniqueName : volumeInfos.keySet()) {
|
||||
TemplateInfo vInfo = volumeInfos.get(uniqueName);
|
||||
DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), vInfo.getInstallPath());
|
||||
try {
|
||||
_agentMgr.sendToSecStorage(ssHost, dtCommand, null);
|
||||
} catch (AgentUnavailableException e) {
|
||||
String err = "Failed to delete " + vInfo.getTemplateName() + " on secondary storage " + sserverId + " which isn't in the database";
|
||||
s_logger.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
String description = "Deleted volume " + vInfo.getTemplateName() + " on secondary storage " + sserverId + " since it isn't in the database";
|
||||
s_logger.info(description);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTemplateSync(DataStore ssStore) {
|
||||
if (ssStore == null) {
|
||||
s_logger.warn("Huh? image store is null");
|
||||
return;
|
||||
}
|
||||
long storeId = ssStore.getId();
|
||||
Long zoneId = ssStore.getScope().getScopeId();
|
||||
|
||||
Map<String, TemplateInfo> templateInfos = listTemplate(ssStore);
|
||||
if (templateInfos == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
|
||||
List<VMTemplateVO> allTemplates = null;
|
||||
if (zoneId == null){
|
||||
// region wide store
|
||||
allTemplates = _templateDao.listAll();
|
||||
}
|
||||
else{
|
||||
// zone wide store
|
||||
allTemplates = _templateDao.listAllInZone(zoneId);
|
||||
}
|
||||
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
|
||||
List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();
|
||||
|
||||
if (rtngTmplts != null) {
|
||||
for (VMTemplateVO rtngTmplt : rtngTmplts) {
|
||||
if (!allTemplates.contains(rtngTmplt)) {
|
||||
allTemplates.add(rtngTmplt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultBuiltin != null) {
|
||||
for (VMTemplateVO builtinTmplt : defaultBuiltin) {
|
||||
if (!allTemplates.contains(builtinTmplt)) {
|
||||
allTemplates.add(builtinTmplt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toBeDownloaded.addAll(allTemplates);
|
||||
|
||||
for (VMTemplateVO tmplt : allTemplates) {
|
||||
String uniqueName = tmplt.getUniqueName();
|
||||
TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
|
||||
if (templateInfos.containsKey(uniqueName)) {
|
||||
TemplateInfo tmpltInfo = templateInfos.remove(uniqueName);
|
||||
toBeDownloaded.remove(tmplt);
|
||||
if (tmpltStore != null) {
|
||||
s_logger.info("Template Sync found " + uniqueName + " already in the template host table");
|
||||
if (tmpltStore.getDownloadState() != Status.DOWNLOADED) {
|
||||
tmpltStore.setErrorString("");
|
||||
}
|
||||
if (tmpltInfo.isCorrupted()) {
|
||||
tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR);
|
||||
String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId();
|
||||
tmpltStore.setErrorString(msg);
|
||||
s_logger.info("msg");
|
||||
if (tmplt.getUrl() == null) {
|
||||
msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId();
|
||||
s_logger.warn(msg);
|
||||
} else {
|
||||
toBeDownloaded.add(tmplt);
|
||||
}
|
||||
|
||||
} else {
|
||||
tmpltStore.setDownloadPercent(100);
|
||||
tmpltStore.setDownloadState(Status.DOWNLOADED);
|
||||
tmpltStore.setInstallPath(tmpltInfo.getInstallPath());
|
||||
tmpltStore.setSize(tmpltInfo.getSize());
|
||||
tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
|
||||
tmpltStore.setLastUpdated(new Date());
|
||||
|
||||
if (tmpltInfo.getSize() > 0) {
|
||||
long accountId = tmplt.getAccountId();
|
||||
try {
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage,
|
||||
tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl()));
|
||||
} catch (ResourceAllocationException e) {
|
||||
s_logger.warn(e.getMessage());
|
||||
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId,
|
||||
null, e.getMessage(), e.getMessage());
|
||||
} finally {
|
||||
_resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
|
||||
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
|
||||
}
|
||||
}
|
||||
}
|
||||
_vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore);
|
||||
} else {
|
||||
tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl());
|
||||
tmpltStore.setSize(tmpltInfo.getSize());
|
||||
tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
|
||||
_vmTemplateStoreDao.persist(tmpltStore);
|
||||
this.associateTemplateToZone(tmplt.getId(), zoneId);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) {
|
||||
s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + storeId + ", will request download to start/resume shortly");
|
||||
|
||||
} else if (tmpltStore == null) {
|
||||
s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly");
|
||||
TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl());
|
||||
_vmTemplateStoreDao.persist(templtStore);
|
||||
this.associateTemplateToZone(tmplt.getId(), zoneId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (toBeDownloaded.size() > 0) {
|
||||
/* Only download templates whose hypervirsor type is in the zone */
|
||||
List<HypervisorType> availHypers = _clusterDao.getAvailableHypervisorInZone(zoneId);
|
||||
if (availHypers.isEmpty()) {
|
||||
/*
|
||||
* This is for cloudzone, local secondary storage resource
|
||||
* started before cluster created
|
||||
*/
|
||||
availHypers.add(HypervisorType.KVM);
|
||||
}
|
||||
/* Baremetal need not to download any template */
|
||||
availHypers.remove(HypervisorType.BareMetal);
|
||||
availHypers.add(HypervisorType.None); // bug 9809: resume ISO
|
||||
// download.
|
||||
for (VMTemplateVO tmplt : toBeDownloaded) {
|
||||
if (tmplt.getUrl() == null) { // If url is null we can't
|
||||
// initiate the download
|
||||
continue;
|
||||
}
|
||||
// if this is private template, and there is no record for this
|
||||
// template in this sHost, skip
|
||||
if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) {
|
||||
VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(storeId, tmplt.getId());
|
||||
if (tmpltHost == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (availHypers.contains(tmplt.getHypervisorType())) {
|
||||
if (_swiftMgr.isSwiftEnabled()) {
|
||||
if (_swiftMgr.isTemplateInstalled(tmplt.getId())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssStore.getName());
|
||||
//TODO: we should pass a callback here
|
||||
initiateTemplateDownload(tmplt, ssStore, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String uniqueName : templateInfos.keySet()) {
|
||||
TemplateInfo tInfo = templateInfos.get(uniqueName);
|
||||
List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId());
|
||||
//check if there is any Vm using this ISO.
|
||||
if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
|
||||
DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(ssStore.getUri(), tInfo.getInstallPath());
|
||||
try {
|
||||
HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssStore);
|
||||
_agentMgr.sendToSecStorage(ssAhost, dtCommand, null);
|
||||
} catch (AgentUnavailableException e) {
|
||||
String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database";
|
||||
s_logger.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId + " since it isn't in the database";
|
||||
s_logger.info(description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAllDownloads(Long templateId) {
|
||||
@ -1067,30 +645,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
|
||||
}
|
||||
}
|
||||
|
||||
// persist entry in template_zone_ref table. zoneId can be empty for region-wide image store, in that case,
|
||||
// we will associate the template to all the zones.
|
||||
private void associateTemplateToZone(long templateId, Long zoneId){
|
||||
List<Long> dcs = new ArrayList<Long>();
|
||||
if (zoneId != null ){
|
||||
dcs.add(zoneId);
|
||||
}
|
||||
else{
|
||||
List<DataCenterVO> zones = _dcDao.listAll();
|
||||
for (DataCenterVO zone : zones){
|
||||
dcs.add(zone.getId());
|
||||
}
|
||||
}
|
||||
for (Long id : dcs) {
|
||||
VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, templateId);
|
||||
if (tmpltZoneVO == null) {
|
||||
tmpltZoneVO = new VMTemplateZoneVO(id, templateId, new Date());
|
||||
_vmTemplateZoneDao.persist(tmpltZoneVO);
|
||||
} else {
|
||||
tmpltZoneVO.setLastUpdated(new Date());
|
||||
_vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.template.TemplateConstants;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
|
||||
|
||||
public class DummySecondaryStorageResource extends ServerResourceBase implements ServerResource {
|
||||
@ -113,7 +113,7 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements
|
||||
public StartupCommand[] initialize() {
|
||||
final StartupStorageCommand cmd = new StartupStorageCommand("dummy",
|
||||
StoragePoolType.NetworkFilesystem, 1024*1024*1024*100L,
|
||||
new HashMap<String, TemplateInfo>());
|
||||
new HashMap<String, TemplateProp>());
|
||||
|
||||
cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
|
||||
cmd.setIqn(null);
|
||||
@ -173,12 +173,12 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements
|
||||
return _useServiceVm;
|
||||
}
|
||||
|
||||
public Map<String, TemplateInfo> getDefaultSystemVmTemplateInfo() {
|
||||
public Map<String, TemplateProp> getDefaultSystemVmTemplateInfo() {
|
||||
List<VMTemplateVO> tmplts = _tmpltDao.listAllSystemVMTemplates();
|
||||
Map<String, TemplateInfo> tmpltInfo = new HashMap<String, TemplateInfo>();
|
||||
Map<String, TemplateProp> tmpltInfo = new HashMap<String, TemplateProp>();
|
||||
if (tmplts != null) {
|
||||
for (VMTemplateVO tmplt : tmplts) {
|
||||
TemplateInfo routingInfo = new TemplateInfo(tmplt.getUniqueName(), TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, false, false);
|
||||
TemplateProp routingInfo = new TemplateProp(tmplt.getUniqueName(), TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, false, false);
|
||||
tmpltInfo.put(tmplt.getUniqueName(), routingInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ 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.DataStoreRole;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||
import org.apache.log4j.Logger;
|
||||
@ -75,7 +75,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
|
||||
@Inject AgentManager _agentMgr;
|
||||
|
||||
@Inject DataStoreManager storeMgr;
|
||||
@Inject ImageService imageService;
|
||||
@Inject TemplateService imageService;
|
||||
@Inject ImageDataFactory imageFactory;
|
||||
@Inject TemplateManager templateMgr;
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ import com.cloud.utils.Pair;
|
||||
/**
|
||||
* TemplateManager manages the templates stored on secondary storage. It is responsible for creating private/public templates.
|
||||
*/
|
||||
public interface TemplateManager extends TemplateService{
|
||||
public interface TemplateManager extends TemplateApiService{
|
||||
|
||||
/**
|
||||
* Prepares a template for vm creation for a certain storage pool.
|
||||
|
||||
@ -58,7 +58,7 @@ 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.DataStoreRole;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
@ -187,8 +187,8 @@ import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Component
|
||||
@Local(value={TemplateManager.class, TemplateService.class})
|
||||
public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateService {
|
||||
@Local(value={TemplateManager.class, TemplateApiService.class})
|
||||
public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateApiService {
|
||||
private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
|
||||
@Inject VMTemplateDao _tmpltDao;
|
||||
@Inject VMTemplateHostDao _tmpltHostDao;
|
||||
@ -246,7 +246,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
@Inject
|
||||
SnapshotDataFactory snapshotFactory;
|
||||
@Inject
|
||||
ImageService imageSvr;
|
||||
TemplateService imageSvr;
|
||||
@Inject
|
||||
DataStoreManager dataStoreMgr;
|
||||
@Inject
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user