Refactor DownloadMonitorImpl code, move some functionalities to

TemplateServiceImpl and VolumeServiceImpl.
This commit is contained in:
Min Chen 2013-04-11 18:09:42 -07:00
parent 582a1f0539
commit bb64672715
51 changed files with 1174 additions and 999 deletions

View File

@ -18,16 +18,16 @@ package com.cloud.agent.api;
import java.util.Map; import java.util.Map;
import com.cloud.storage.template.TemplateInfo; import com.cloud.storage.template.TemplateProp;
public class ModifyStoragePoolAnswer extends Answer { public class ModifyStoragePoolAnswer extends Answer {
StoragePoolInfo poolInfo; StoragePoolInfo poolInfo;
Map<String, TemplateInfo> templateInfo; Map<String, TemplateProp> templateInfo;
protected ModifyStoragePoolAnswer() { 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); super(cmd);
this.result = true; this.result = true;
this.poolInfo = new StoragePoolInfo(null, 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; return templateInfo;
} }
public void setTemplateInfo(Map<String, TemplateInfo> templateInfo) { public void setTemplateInfo(Map<String, TemplateProp> templateInfo) {
this.templateInfo = templateInfo; this.templateInfo = templateInfo;
} }

View File

@ -22,13 +22,13 @@ import java.util.Map;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.template.TemplateInfo; import com.cloud.storage.template.TemplateProp;
public class StartupStorageCommand extends StartupCommand { public class StartupStorageCommand extends StartupCommand {
String parent; String parent;
Map<String, TemplateInfo> templateInfo; Map<String, TemplateProp> templateInfo;
long totalSize; long totalSize;
StoragePoolInfo poolInfo; StoragePoolInfo poolInfo;
Storage.StorageResourceType resourceType; Storage.StorageResourceType resourceType;
@ -40,7 +40,7 @@ public class StartupStorageCommand extends StartupCommand {
super(Host.Type.Storage); 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); super(Host.Type.Storage);
this.parent = parent; this.parent = parent;
this.totalSize = totalSize; 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); super(Host.Type.Storage);
this.parent = parent; this.parent = parent;
this.templateInfo = templateInfo; this.templateInfo = templateInfo;
@ -79,11 +79,11 @@ public class StartupStorageCommand extends StartupCommand {
return totalSize; return totalSize;
} }
public Map<String, TemplateInfo> getTemplateInfo() { public Map<String, TemplateProp> getTemplateInfo() {
return templateInfo; return templateInfo;
} }
public void setTemplateInfo(Map<String, TemplateInfo> templateInfo) { public void setTemplateInfo(Map<String, TemplateProp> templateInfo) {
this.templateInfo = templateInfo; this.templateInfo = templateInfo;
} }

View File

@ -19,27 +19,27 @@ package com.cloud.agent.api.storage;
import java.util.Map; import java.util.Map;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.storage.template.TemplateInfo; import com.cloud.storage.template.TemplateProp;
public class ListTemplateAnswer extends Answer { public class ListTemplateAnswer extends Answer {
private String secUrl; private String secUrl;
private Map<String, TemplateInfo> templateInfos; private Map<String, TemplateProp> templateInfos;
public ListTemplateAnswer() { public ListTemplateAnswer() {
} }
public ListTemplateAnswer(String secUrl, Map<String, TemplateInfo> templateInfos) { public ListTemplateAnswer(String secUrl, Map<String, TemplateProp> templateInfos) {
super(null, true, "success"); super(null, true, "success");
this.setSecUrl(secUrl); this.setSecUrl(secUrl);
this.templateInfos = templateInfos; this.templateInfos = templateInfos;
} }
public Map<String, TemplateInfo> getTemplateInfo() { public Map<String, TemplateProp> getTemplateInfo() {
return templateInfos; return templateInfos;
} }
public void setTemplateInfo(Map<String, TemplateInfo> templateInfos) { public void setTemplateInfo(Map<String, TemplateProp> templateInfos) {
this.templateInfos = templateInfos; this.templateInfos = templateInfos;
} }

View File

@ -19,27 +19,27 @@ package com.cloud.agent.api.storage;
import java.util.Map; import java.util.Map;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.storage.template.TemplateInfo; import com.cloud.storage.template.TemplateProp;
public class ListVolumeAnswer extends Answer { public class ListVolumeAnswer extends Answer {
private String secUrl; private String secUrl;
private Map<Long, TemplateInfo> templateInfos; private Map<Long, TemplateProp> templateInfos;
public ListVolumeAnswer() { public ListVolumeAnswer() {
} }
public ListVolumeAnswer(String secUrl, Map<Long, TemplateInfo> templateInfos) { public ListVolumeAnswer(String secUrl, Map<Long, TemplateProp> templateInfos) {
super(null, true, "success"); super(null, true, "success");
this.setSecUrl(secUrl); this.setSecUrl(secUrl);
this.templateInfos = templateInfos; this.templateInfos = templateInfos;
} }
public Map<Long, TemplateInfo> getTemplateInfo() { public Map<Long, TemplateProp> getTemplateInfo() {
return templateInfos; return templateInfos;
} }
public void setTemplateInfo(Map<Long, TemplateInfo> templateInfos) { public void setTemplateInfo(Map<Long, TemplateProp> templateInfos) {
this.templateInfos = templateInfos; this.templateInfos = templateInfos;
} }

View File

@ -16,7 +16,7 @@
// under the License. // under the License.
package com.cloud.storage.template; package com.cloud.storage.template;
public class TemplateInfo { public class TemplateProp {
String templateName; String templateName;
String installPath; String installPath;
long size; long size;
@ -25,11 +25,11 @@ public class TemplateInfo {
boolean isPublic; boolean isPublic;
boolean isCorrupted; 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.templateName = templateName;
this.installPath = installPath; this.installPath = installPath;
this.size = size; this.size = size;
@ -38,7 +38,7 @@ public class TemplateInfo {
this.isCorrupted = isCorrupted; 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); this(templateName, installPath, 0, 0, isPublic, isCorrupted);
} }

View File

@ -36,7 +36,7 @@ import com.cloud.exception.StorageUnavailableException;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
public interface TemplateService { public interface TemplateApiService {
VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException; VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException;

View File

@ -65,7 +65,7 @@ import com.cloud.storage.DataStoreProviderApiService;
import com.cloud.storage.StorageService; import com.cloud.storage.StorageService;
import com.cloud.storage.VolumeApiService; import com.cloud.storage.VolumeApiService;
import com.cloud.storage.snapshot.SnapshotService; 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.Account;
import com.cloud.user.AccountService; import com.cloud.user.AccountService;
import com.cloud.user.DomainService; import com.cloud.user.DomainService;
@ -106,7 +106,7 @@ public abstract class BaseCmd {
@Inject public VolumeApiService _volumeService; @Inject public VolumeApiService _volumeService;
@Inject public ResourceService _resourceService; @Inject public ResourceService _resourceService;
@Inject public NetworkService _networkService; @Inject public NetworkService _networkService;
@Inject public TemplateService _templateService; @Inject public TemplateApiService _templateService;
@Inject public SecurityGroupService _securityGroupService; @Inject public SecurityGroupService _securityGroupService;
@Inject public SnapshotService _snapshotService; @Inject public SnapshotService _snapshotService;
@Inject public ConsoleProxyService _consoleProxyService; @Inject public ConsoleProxyService _consoleProxyService;

View File

@ -744,7 +744,7 @@
<bean id="imageDataManagerImpl" class="org.apache.cloudstack.storage.image.manager.ImageDataManagerImpl" /> <bean id="imageDataManagerImpl" class="org.apache.cloudstack.storage.image.manager.ImageDataManagerImpl" />
<bean id="imageStoreHelper" class="org.apache.cloudstack.storage.image.datastore.ImageStoreHelper" /> <bean id="imageStoreHelper" class="org.apache.cloudstack.storage.image.datastore.ImageStoreHelper" />
<bean id="imageFormatHelper" class="org.apache.cloudstack.storage.image.format.ImageFormatHelper" /> <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="iso" class="org.apache.cloudstack.engine.subsystem.api.storage.type.Iso" />
<bean id="networkFileSystem" class="org.apache.cloudstack.storage.datastore.type.NetworkFileSystem" /> <bean id="networkFileSystem" class="org.apache.cloudstack.storage.datastore.type.NetworkFileSystem" />
<bean id="networkRestService" class="org.apache.cloudstack.engine.rest.service.api.NetworkRestService" /> <bean id="networkRestService" class="org.apache.cloudstack.engine.rest.service.api.NetworkRestService" />

View File

@ -105,7 +105,7 @@ import com.cloud.resource.ServerResource;
import com.cloud.resource.ServerResourceBase; import com.cloud.resource.ServerResourceBase;
import com.cloud.serializer.GsonHelper; import com.cloud.serializer.GsonHelper;
import com.cloud.storage.Volume; 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.Pair;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DiskProfile; import com.cloud.vm.DiskProfile;
@ -765,7 +765,7 @@ public class HypervResource extends ServerResourceBase implements ServerResource
try { try {
StorageFilerTO pool = cmd.getPool(); StorageFilerTO pool = cmd.getPool();
s_logger.info("Primary storage pool details: " + pool.getHost() + " " + pool.getPath()); 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 // FIXME: get the actual storage capacity and storage stats of CSV volume
// by running powershell cmdlet. This hardcoding just for prototype. // by running powershell cmdlet. This hardcoding just for prototype.
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,

View File

@ -60,7 +60,7 @@ import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageLayer; import com.cloud.storage.StorageLayer;
import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManager;
import com.cloud.storage.template.DownloadManagerImpl; 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.UploadManager;
import com.cloud.storage.template.UploadManagerImpl; import com.cloud.storage.template.UploadManagerImpl;
import com.cloud.utils.NumbersUtil; import com.cloud.utils.NumbersUtil;
@ -650,7 +650,7 @@ public class CifsSecondaryStorageResource extends ServerResourceBase implements
return null; 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.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
cmd.setIqn(null); cmd.setIqn(null);

View File

@ -48,7 +48,7 @@ import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.StorageLayer; import com.cloud.storage.StorageLayer;
import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManager;
import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.DownloadManagerImpl;
import com.cloud.storage.template.TemplateInfo; import com.cloud.storage.template.TemplateProp;
import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ComponentContext;
public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource { public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
@ -109,7 +109,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
private Answer execute(ListTemplateCommand cmd) { private Answer execute(ListTemplateCommand cmd) {
String root = getRootDir(); String root = getRootDir();
Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root); Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
} }

View File

@ -100,7 +100,7 @@ import com.cloud.storage.StorageLayer;
import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManager;
import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.DownloadManagerImpl;
import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser; 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.TemplateLocation;
import com.cloud.storage.template.UploadManager; import com.cloud.storage.template.UploadManager;
import com.cloud.storage.template.UploadManagerImpl; 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, "", ""); String[] containers = swiftList(swift, "", "");
if (containers == null) { if (containers == null) {
return null; return null;
} }
Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>(); Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
for( String container : containers) { for( String container : containers) {
if ( container.startsWith("T-")) { if ( container.startsWith("T-")) {
String ldir = _tmpltDir + "/" + UUID.randomUUID().toString(); 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); s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
continue; continue;
} }
TemplateInfo tInfo = loc.getTemplateInfo(); TemplateProp tInfo = loc.getTemplateInfo();
tInfo.setInstallPath(container); tInfo.setInstallPath(container);
tmpltInfos.put(tInfo.getTemplateName(), tInfo); tmpltInfos.put(tInfo.getTemplateName(), tInfo);
loc.purge(); loc.purge();
@ -1111,11 +1111,11 @@ SecondaryStorageResource {
return new Answer(cmd, true, null); return new Answer(cmd, true, null);
} }
if (cmd.getSwift() != 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); return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
} else { } else {
String root = getRootDir(cmd.getSecUrl()); 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); return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
} }
} }
@ -1126,7 +1126,7 @@ SecondaryStorageResource {
} }
String root = getRootDir(cmd.getSecUrl()); 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); return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
} }

View File

@ -91,13 +91,13 @@ public interface DownloadManager extends Manager {
/** /**
* @return list of template info for installed templates * @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 * @return list of volume info for installed volumes
*/ */
public Map<Long, TemplateInfo> gatherVolumeInfo(String volumeDir); public Map<Long, TemplateProp> gatherVolumeInfo(String volumeDir);
} }

View File

@ -717,8 +717,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
} }
@Override @Override
public Map<String, TemplateInfo> gatherTemplateInfo(String rootDir) { public Map<String, TemplateProp> gatherTemplateInfo(String rootDir) {
Map<String, TemplateInfo> result = new HashMap<String, TemplateInfo>(); Map<String, TemplateProp> result = new HashMap<String, TemplateProp>();
String templateDir = rootDir + File.separator + _templateDir; String templateDir = rootDir + File.separator + _templateDir;
if (! _storage.exists(templateDir)) { if (! _storage.exists(templateDir)) {
@ -741,7 +741,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
continue; continue;
} }
TemplateInfo tInfo = loc.getTemplateInfo(); TemplateProp tInfo = loc.getTemplateInfo();
if ((tInfo.size == tInfo.physicalSize) && (tInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) { if ((tInfo.size == tInfo.physicalSize) && (tInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
try { try {
@ -774,8 +774,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
} }
@Override @Override
public Map<Long, TemplateInfo> gatherVolumeInfo(String rootDir) { public Map<Long, TemplateProp> gatherVolumeInfo(String rootDir) {
Map<Long, TemplateInfo> result = new HashMap<Long, TemplateInfo>(); Map<Long, TemplateProp> result = new HashMap<Long, TemplateProp>();
String volumeDir = rootDir + File.separator + _volumeDir; String volumeDir = rootDir + File.separator + _volumeDir;
if (! _storage.exists(volumeDir)) { if (! _storage.exists(volumeDir)) {
@ -798,7 +798,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
continue; continue;
} }
TemplateInfo vInfo = loc.getTemplateInfo(); TemplateProp vInfo = loc.getTemplateInfo();
if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) { if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
try { try {

View File

@ -156,8 +156,8 @@ public class TemplateLocation {
return true; return true;
} }
public TemplateInfo getTemplateInfo() { public TemplateProp getTemplateInfo() {
TemplateInfo tmplInfo = new TemplateInfo(); TemplateProp tmplInfo = new TemplateProp();
tmplInfo.id = Long.parseLong(_props.getProperty("id")); tmplInfo.id = Long.parseLong(_props.getProperty("id"));
tmplInfo.installPath = _templatePath + File.separator + _props.getProperty("filename"); tmplInfo.installPath = _templatePath + File.separator + _props.getProperty("filename");
if (_resourceType == ResourceType.VOLUME){ if (_resourceType == ResourceType.VOLUME){

View File

@ -20,10 +20,16 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
import org.apache.cloudstack.framework.async.AsyncCallFuture; 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> createTemplateAsync(TemplateInfo template, DataStore store);
AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store); AsyncCallFuture<CommandResult> createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store);
AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store); AsyncCallFuture<CommandResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
AsyncCallFuture<CommandResult> deleteTemplateAsync(TemplateInfo template); AsyncCallFuture<CommandResult> deleteTemplateAsync(TemplateInfo template);
void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId);
void handleTemplateSync(DataStore store);
} }

View File

@ -77,4 +77,6 @@ public interface VolumeService {
AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume); AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume);
void handleVolumeSync(DataStore store);
} }

View File

@ -30,7 +30,5 @@ public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Lo
public List<SnapshotDataStoreVO> listByStoreId(long id); public List<SnapshotDataStoreVO> listByStoreId(long id);
public List<SnapshotDataStoreVO> listLiveByStoreId(long id);
public void deletePrimaryRecordsForStore(long id); public void deletePrimaryRecordsForStore(long id);
} }

View File

@ -23,18 +23,20 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; 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.db.GenericDao;
import com.cloud.utils.fsm.StateDao; import com.cloud.utils.fsm.StateDao;
public interface TemplateDataStoreDao extends GenericDao<TemplateDataStoreVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore> { 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); public void deletePrimaryRecordsForStore(long id);
List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states); List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states);
List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status);
TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId); TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId);
} }

View File

@ -291,6 +291,12 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
return this.state; return this.state;
} }
public void setState(ObjectInDataStoreStateMachine.State state) {
this.state = state;
}
public long getUpdatedCount() { public long getUpdatedCount() {
return this.updatedCount; return this.updatedCount;
} }

View File

@ -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.DataObjectInStore;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao; 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> listByStoreId(long id);
public List<VolumeDataStoreVO> listLiveByStoreId(long id);
public void deletePrimaryRecordsForStore(long id); public void deletePrimaryRecordsForStore(long id);
public VolumeDataStoreVO findByVolumeId(long volumeId);
public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId);
} }

View File

@ -203,14 +203,14 @@ public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMach
this.state = ObjectInDataStoreStateMachine.State.Allocated; 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, int downloadPercent, Status downloadState,
String localDownloadPath, String errorString, String jobId, String localDownloadPath, String errorString, String jobId,
String installPath, String downloadUrl, String checksum, ImageFormat format) { String installPath, String downloadUrl, String checksum, ImageFormat format) {
//super(); //super();
this.dataStoreId = hostId; this.dataStoreId = hostId;
this.volumeId = volumeId; this.volumeId = volumeId;
this.zoneId = zoneId; //this.zoneId = zoneId;
this.lastUpdated = lastUpdated; this.lastUpdated = lastUpdated;
this.downloadPercent = downloadPercent; this.downloadPercent = downloadPercent;
this.downloadState = downloadState; this.downloadState = downloadState;

View File

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

View File

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

View File

@ -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.DataStoreRole;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; 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.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.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
@ -86,7 +86,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
//@Inject //@Inject
//ImageDataStoreProviderManager imageProviderMgr; //ImageDataStoreProviderManager imageProviderMgr;
@Inject @Inject
ImageService imageService; TemplateService imageService;
@Inject @Inject
VolumeService volumeService; VolumeService volumeService;
@Inject @Inject

View File

@ -42,7 +42,6 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class); private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class);
private SearchBuilder<SnapshotDataStoreVO> updateStateSearch; private SearchBuilder<SnapshotDataStoreVO> updateStateSearch;
private SearchBuilder<SnapshotDataStoreVO> storeSearch; private SearchBuilder<SnapshotDataStoreVO> storeSearch;
private SearchBuilder<SnapshotDataStoreVO> liveStoreSearch;
@Override @Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@ -50,13 +49,9 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
storeSearch = createSearchBuilder(); storeSearch = createSearchBuilder();
storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
storeSearch.done(); 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 = this.createSearchBuilder();
updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
@ -102,17 +97,11 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO
return rows > 0; return rows > 0;
} }
@Override @Override
public List<SnapshotDataStoreVO> listByStoreId(long id) { public List<SnapshotDataStoreVO> listByStoreId(long id) {
SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create(); SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
sc.setParameters("store_id", id); 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); sc.setParameters("destroyed", false);
return listIncludingRemovedBy(sc); return listIncludingRemovedBy(sc);
} }

View File

@ -30,6 +30,7 @@ import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria; 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 static final Logger s_logger = Logger.getLogger(TemplateDataStoreDaoImpl.class);
private SearchBuilder<TemplateDataStoreVO> updateStateSearch; private SearchBuilder<TemplateDataStoreVO> updateStateSearch;
private SearchBuilder<TemplateDataStoreVO> storeSearch; private SearchBuilder<TemplateDataStoreVO> storeSearch;
private SearchBuilder<TemplateDataStoreVO> liveStoreSearch;
private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch; private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch;
private SearchBuilder<TemplateDataStoreVO> storeTemplateDownloadStatusSearch;
private SearchBuilder<TemplateDataStoreVO> storeTemplateSearch; private SearchBuilder<TemplateDataStoreVO> storeTemplateSearch;
@Override @Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params); super.configure(name, params);
storeSearch = createSearchBuilder(); storeSearch = createSearchBuilder();
storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
storeSearch.done(); 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 = this.createSearchBuilder();
updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
updateStateSearch.and("state", updateStateSearch.entity().getState(), 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.and("destroyed", storeTemplateStateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
storeTemplateStateSearch.done(); 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 = createSearchBuilder();
storeTemplateSearch.and("store_id", storeTemplateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); storeTemplateSearch.and("store_id", storeTemplateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
storeTemplateSearch.and("template_id", storeTemplateSearch.entity().getTemplateId(), 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; return rows > 0;
} }
@Override @Override
public List<TemplateDataStoreVO> listByStoreId(long id) { public List<TemplateDataStoreVO> listByStoreId(long id) {
SearchCriteria<TemplateDataStoreVO> sc = storeSearch.create(); SearchCriteria<TemplateDataStoreVO> sc = storeSearch.create();
sc.setParameters("store_id", id); 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); sc.setParameters("destroyed", false);
return listIncludingRemovedBy(sc); return listIncludingRemovedBy(sc);
} }
@ -152,6 +153,17 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
return search(sc, null); 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 @Override
public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId) { public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId) {
SearchCriteria<TemplateDataStoreVO> sc = storeTemplateSearch.create(); SearchCriteria<TemplateDataStoreVO> sc = storeTemplateSearch.create();

View File

@ -31,6 +31,7 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.storage.VolumeHostVO;
import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria; 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 { public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Long> implements VolumeDataStoreDao {
private static final Logger s_logger = Logger.getLogger(VolumeDataStoreDaoImpl.class); private static final Logger s_logger = Logger.getLogger(VolumeDataStoreDaoImpl.class);
private SearchBuilder<VolumeDataStoreVO> updateStateSearch; private SearchBuilder<VolumeDataStoreVO> updateStateSearch;
private SearchBuilder<VolumeDataStoreVO> volumeSearch;
private SearchBuilder<VolumeDataStoreVO> storeSearch; private SearchBuilder<VolumeDataStoreVO> storeSearch;
private SearchBuilder<VolumeDataStoreVO> liveStoreSearch; private SearchBuilder<VolumeDataStoreVO> storeVolumeSearch;
@Override @Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params); super.configure(name, params);
storeSearch = createSearchBuilder(); storeSearch = createSearchBuilder();
storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
storeSearch.done(); storeSearch.done();
liveStoreSearch = createSearchBuilder(); volumeSearch = createSearchBuilder();
liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); volumeSearch.and("destroyed", volumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
liveStoreSearch.done(); 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 = this.createSearchBuilder();
updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
@ -102,16 +112,11 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
return rows > 0; return rows > 0;
} }
@Override @Override
public List<VolumeDataStoreVO> listByStoreId(long id) { public List<VolumeDataStoreVO> listByStoreId(long id) {
SearchCriteria<VolumeDataStoreVO> sc = storeSearch.create(); SearchCriteria<VolumeDataStoreVO> sc = storeSearch.create();
sc.setParameters("store_id", id); 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); sc.setParameters("destroyed", false);
return listIncludingRemovedBy(sc); return listIncludingRemovedBy(sc);
} }
@ -125,4 +130,23 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
remove(sc); remove(sc);
txn.commit(); 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);
}
} }

View File

@ -318,6 +318,10 @@ public class VolumeObject implements VolumeInfo {
return this.payload; return this.payload;
} }
public VolumeVO getVolume(){
return this.volumeVO;
}
@Override @Override
public HypervisorType getHypervisorType() { public HypervisorType getHypervisorType() {
return this.volumeDao.getHypervisorType(this.volumeVO.getId()); return this.volumeDao.getHypervisorType(this.volumeVO.getId());

View File

@ -18,6 +18,11 @@
*/ */
package org.apache.cloudstack.storage.volume; 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 javax.inject.Inject;
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; 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.ObjectInDataStoreManager;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; 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.apache.log4j.Logger;
import org.springframework.stereotype.Component; 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.Config;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.host.HostVO;
import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Volume.Type; import com.cloud.storage.Volume.Type;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao; 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.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.NumbersUtil;
import com.cloud.utils.UriUtils;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
@ -77,9 +100,25 @@ public class VolumeServiceImpl implements VolumeService {
@Inject @Inject
VolumeDataFactory volFactory; VolumeDataFactory volFactory;
@Inject SnapshotManager snapshotMgr; @Inject SnapshotManager snapshotMgr;
@Inject
ResourceLimitService _resourceLimitMgr;
@Inject
DownloadMonitor _dlMonitor;
@Inject
AccountManager _accountMgr;
@Inject
AlertManager _alertMgr;
@Inject VMInstanceDao vmDao; @Inject VMInstanceDao vmDao;
@Inject @Inject
ConfigurationDao configDao; ConfigurationDao configDao;
@Inject
SecondaryStorageVmManager _ssvmMgr;
@Inject
AgentManager _agentMgr;
@Inject
VolumeDataStoreDao _volumeStoreDao;
@Inject
VolumeDao _volumeDao;
public VolumeServiceImpl() { public VolumeServiceImpl() {
} }
@ -679,6 +718,130 @@ public class VolumeServiceImpl implements VolumeService {
return null; 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;
}
} }

View File

@ -215,7 +215,7 @@ import com.cloud.storage.Volume;
import com.cloud.storage.template.Processor; import com.cloud.storage.template.Processor;
import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.Processor.FormatInfo;
import com.cloud.storage.template.QCOW2Processor; 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.storage.template.TemplateLocation;
import com.cloud.utils.NumbersUtil; import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
@ -2381,7 +2381,7 @@ ServerResource {
return new Answer(cmd, false, " Failed to create storage pool"); 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, ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
storagepool.getCapacity(), storagepool.getUsed(), tInfo); storagepool.getCapacity(), storagepool.getUsed(), tInfo);

View File

@ -114,7 +114,7 @@ import com.cloud.resource.hypervisor.HypervisorResource;
import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Volume; 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.template.VirtualMachineTemplate.BootloaderType;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
import com.cloud.utils.Ternary; import com.cloud.utils.Ternary;
@ -458,7 +458,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource {
setupHeartBeat(pool.getUuid()); setupHeartBeat(pool.getUuid());
OvmStoragePool.Details d = OvmStoragePool.getDetailsByUuid(_conn, 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); ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, d.totalSpace, d.freeSpace, tInfo);
return answer; return answer;
} catch (Exception e) { } catch (Exception e) {

View File

@ -74,7 +74,7 @@ import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; 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.component.ManagerBase;
import com.cloud.utils.db.Transaction; import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
@ -357,7 +357,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
txn = Transaction.open(Transaction.CLOUD_DB); txn = Transaction.open(Transaction.CLOUD_DB);
txn.close(); 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 @Override
@ -398,7 +398,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
txn = Transaction.open(Transaction.CLOUD_DB); txn = Transaction.open(Transaction.CLOUD_DB);
txn.close(); 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 @Override
@ -449,9 +449,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
List<MockVolumeVO> volumes = _mockVolumeDao.findByStorageIdAndType(storage.getId(), List<MockVolumeVO> volumes = _mockVolumeDao.findByStorageIdAndType(storage.getId(),
MockVolumeType.VOLUME); MockVolumeType.VOLUME);
Map<Long, TemplateInfo> templateInfos = new HashMap<Long, TemplateInfo>(); Map<Long, TemplateProp> templateInfos = new HashMap<Long, TemplateProp>();
for (MockVolumeVO volume : volumes) { 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)); .replaceAll(storage.getMountPoint(), ""), volume.getSize(), volume.getSize(), true, false));
} }
txn.commit(); txn.commit();
@ -492,9 +492,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa
List<MockVolumeVO> templates = _mockVolumeDao.findByStorageIdAndType(storage.getId(), List<MockVolumeVO> templates = _mockVolumeDao.findByStorageIdAndType(storage.getId(),
MockVolumeType.TEMPLATE); MockVolumeType.TEMPLATE);
Map<String, TemplateInfo> templateInfos = new HashMap<String, TemplateInfo>(); Map<String, TemplateProp> templateInfos = new HashMap<String, TemplateProp>();
for (MockVolumeVO template : templates) { 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)); .replaceAll(storage.getMountPoint(), ""), template.getSize(), template.getSize(), true, false));
} }
txn.commit(); txn.commit();

View File

@ -51,7 +51,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.network.Networks.RouterPrivateIpStrategy;
import com.cloud.simulator.MockVMVO; import com.cloud.simulator.MockVMVO;
import com.cloud.storage.Storage.StorageResourceType; 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.utils.Pair;
import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachine.State;
@ -168,7 +168,7 @@ public class AgentRoutingResource extends AgentStorageResource {
} }
private StartupStorageCommand initializeLocalSR() { private StartupStorageCommand initializeLocalSR() {
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>(); Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
StoragePoolInfo poolInfo = _simMgr.getLocalStorage(hostGuid); StoragePoolInfo poolInfo = _simMgr.getLocalStorage(hostGuid);

View File

@ -210,7 +210,7 @@ import com.cloud.storage.Storage;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
import com.cloud.storage.resource.StoragePoolResource; 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.DateUtil;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils; import com.cloud.utils.StringUtils;
@ -3137,7 +3137,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary(); DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary();
long capacity = summary.getCapacity(); long capacity = summary.getCapacity();
long available = summary.getFreeSpace(); 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); ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
return answer; return answer;
} catch (Throwable e) { } catch (Throwable e) {

View File

@ -233,7 +233,7 @@ import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO; 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.template.VirtualMachineTemplate.BootloaderType;
import com.cloud.utils.NumbersUtil; import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
@ -5287,7 +5287,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
s_logger.warn(msg); s_logger.warn(msg);
return new Answer(cmd, false, 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); ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
return answer; return answer;
} catch (XenAPIException e) { } catch (XenAPIException e) {

View File

@ -25,6 +25,16 @@
<artifactId>cloud-engine-storage-image</artifactId> <artifactId>cloud-engine-storage-image</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </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> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>

View File

@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.framework.async.AsyncRpcConext;
import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.ImageStoreDriver;
import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.image.store.TemplateObject;
import org.apache.cloudstack.storage.volume.VolumeObject;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
@ -118,11 +119,10 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
TemplateObject tData = (TemplateObject)data; TemplateObject tData = (TemplateObject)data;
_downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
} else if (data.getType() == DataObjectType.VOLUME) { } else if (data.getType() == DataObjectType.VOLUME) {
VolumeVO vol = this.volumeDao.findById(data.getId()); VolumeObject volInfo = (VolumeObject)data;
VolumeInfo volInfo = (VolumeInfo)data;
RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
_downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(), _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase())); payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
} }
CreateCmdResult result = new CreateCmdResult(null, null); CreateCmdResult result = new CreateCmdResult(null, null);

View File

@ -32,6 +32,16 @@
<artifactId>cloud-engine-storage-image</artifactId> <artifactId>cloud-engine-storage-image</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </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> </dependencies>
<build> <build>
<defaultGoal>install</defaultGoal> <defaultGoal>install</defaultGoal>

View File

@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.framework.async.AsyncRpcConext;
import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.ImageStoreDriver;
import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.image.store.TemplateObject;
import org.apache.cloudstack.storage.volume.VolumeObject;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
@ -118,11 +119,10 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
TemplateObject tData = (TemplateObject)data; TemplateObject tData = (TemplateObject)data;
_downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
} else if (data.getType() == DataObjectType.VOLUME) { } else if (data.getType() == DataObjectType.VOLUME) {
VolumeVO vol = this.volumeDao.findById(data.getId()); VolumeObject volInfo = (VolumeObject)data;
VolumeInfo volInfo = (VolumeInfo)data;
RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
_downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(), _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase())); payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
} }
CreateCmdResult result = new CreateCmdResult(null, null); CreateCmdResult result = new CreateCmdResult(null, null);

View File

@ -25,6 +25,16 @@
<artifactId>cloud-engine-storage-image</artifactId> <artifactId>cloud-engine-storage-image</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </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> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>

View File

@ -25,6 +25,16 @@
<artifactId>cloud-engine-storage-image</artifactId> <artifactId>cloud-engine-storage-image</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </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> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>

View File

@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.framework.async.AsyncRpcConext;
import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.ImageStoreDriver;
import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.image.store.TemplateObject;
import org.apache.cloudstack.storage.volume.VolumeObject;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
@ -118,11 +119,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
TemplateObject tData = (TemplateObject)data; TemplateObject tData = (TemplateObject)data;
_downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback);
} else if (data.getType() == DataObjectType.VOLUME) { } else if (data.getType() == DataObjectType.VOLUME) {
VolumeVO vol = this.volumeDao.findById(data.getId()); VolumeObject volInfo = (VolumeObject)data;
VolumeInfo volInfo = (VolumeInfo)data;
RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload();
_downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(), _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(),
payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase())); payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback);
} }
CreateCmdResult result = new CreateCmdResult(null, null); CreateCmdResult result = new CreateCmdResult(null, null);

View File

@ -1993,15 +1993,15 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
_accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), store.getDataCenterId()); _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), store.getDataCenterId());
// Verify that there are no live snapshot, template, volume on the image store to be deleted // 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 ){ if ( snapshots != null && snapshots.size() > 0 ){
throw new CloudRuntimeException("Cannot delete image store with active snapshots backup!"); 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 ){ if ( volumes != null && volumes.size() > 0 ){
throw new CloudRuntimeException("Cannot delete image store with active volumes backup!"); 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 ){ if ( templates != null && templates.size() > 0 ){
throw new CloudRuntimeException("Cannot delete image store with active templates backup!"); throw new CloudRuntimeException("Cannot delete image store with active templates backup!");
} }

View File

@ -18,6 +18,7 @@ package com.cloud.storage.download;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; 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.CreateCmdResult;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; 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.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; 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.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -52,6 +59,8 @@ import com.cloud.exception.ConnectionException;
import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceAllocationException;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; 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.Storage;
import com.cloud.storage.StorageManager; import com.cloud.storage.StorageManager;
import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateHostVO;
@ -117,57 +126,68 @@ public class DownloadListener implements Listener {
public static final String DOWNLOAD_ABANDONED=Status.ABANDONED.toString(); public static final String DOWNLOAD_ABANDONED=Status.ABANDONED.toString();
private HostVO sserver; private HostVO _sserver;
private HostVO ssAgent; private HostVO _ssAgent;
private VMTemplateVO template; private VMTemplateVO _template;
private VolumeVO volume; private VolumeVO _volume;
private boolean downloadActive = true; private boolean _downloadActive = true;
private VolumeHostDao volumeHostDao; private VolumeHostDao _volumeHostDao;
private VolumeDataStoreDao _volumeStoreDao;
private VolumeDao _volumeDao; private VolumeDao _volumeDao;
private StorageManager _storageMgr; private StorageManager _storageMgr;
private VMTemplateHostDao vmTemplateHostDao; private VMTemplateHostDao _vmTemplateHostDao;
private TemplateDataStoreDao _vmTemplateStoreDao; private TemplateDataStoreDao _vmTemplateStoreDao;
private VMTemplateDao _vmTemplateDao; private VMTemplateDao _vmTemplateDao;
private ResourceLimitService _resourceLimitMgr; private ResourceLimitService _resourceLimitMgr;
private AccountManager _accountMgr; private AccountManager _accountMgr;
private AlertManager _alertMgr; 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 StatusTask _statusTask;
private TimeoutTask timeoutTask; private TimeoutTask _timeoutTask;
private Date lastUpdated = new Date(); private Date _lastUpdated = new Date();
private String jobId; private String _jobId;
private final Map<String, DownloadState> stateMap = new HashMap<String, DownloadState>(); private final Map<String, DownloadState> _stateMap = new HashMap<String, DownloadState>();
private Long templateHostId; private Long _templateHostId;
private Long volumeHostId; private Long _volumeHostId;
private DataStore sstore; private DataStore _sstore;
private Long templateStoreId; private Long _templateStoreId;
private AsyncCompletionCallback<CreateCmdResult> callback; 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) { 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._ssAgent = ssAgent;
this.sserver = host; this._sserver = host;
this.template = template; this._template = template;
this.vmTemplateHostDao = dao; this._vmTemplateHostDao = dao;
this.downloadMonitor = downloadMonitor; this._downloadMonitor = downloadMonitor;
this.cmd = cmd; this._cmd = cmd;
this.templateHostId = templHostId; this._templateHostId = templHostId;
initStateMachine(); initStateMachine();
this.currState=getState(Status.NOT_DOWNLOADED.toString()); this._currState=getState(Status.NOT_DOWNLOADED.toString());
this.timer = _timer; this._timer = _timer;
this.timeoutTask = new TimeoutTask(this); this._timeoutTask = new TimeoutTask(this);
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL); this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
this._vmTemplateDao = templateDao; this._vmTemplateDao = templateDao;
this._resourceLimitMgr = _resourceLimitMgr; this._resourceLimitMgr = _resourceLimitMgr;
this._accountMgr = _accountMgr; 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 // 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) { 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._ssAgent = ssAgent;
this.sstore = store; this._sstore = store;
this.template = template; this._template = template;
this._vmTemplateStoreDao = dao; this._vmTemplateStoreDao = dao;
this.downloadMonitor = downloadMonitor; this._downloadMonitor = downloadMonitor;
this.cmd = cmd; this._cmd = cmd;
this.templateStoreId = templStoreId; this._templateStoreId = templStoreId;
initStateMachine(); initStateMachine();
this.currState=getState(Status.NOT_DOWNLOADED.toString()); this._currState=getState(Status.NOT_DOWNLOADED.toString());
this.timer = _timer; this._timer = _timer;
this.timeoutTask = new TimeoutTask(this); this._timeoutTask = new TimeoutTask(this);
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL); this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
this._vmTemplateDao = templateDao; this._vmTemplateDao = templateDao;
this._resourceLimitMgr = _resourceLimitMgr; this._resourceLimitMgr = _resourceLimitMgr;
this._accountMgr = _accountMgr; this._accountMgr = _accountMgr;
this._alertMgr = _alertMgr; this._alertMgr = _alertMgr;
this.callback = callback; this._callback = callback;
updateDatabase(Status.NOT_DOWNLOADED, ""); 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) { 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._ssAgent = ssAgent;
this.sserver = host; this._sstore = store;
this.volume = volume; this._volume = volume;
this.volumeHostDao = dao; this._volumeStoreDao = dao;
this.downloadMonitor = downloadMonitor; this._downloadMonitor = downloadMonitor;
this.cmd = cmd; this._cmd = cmd;
this.volumeHostId = volHostId; this._volumeStoreId = volStoreId;
initStateMachine(); initStateMachine();
this.currState=getState(Status.NOT_DOWNLOADED.toString()); this._currState=getState(Status.NOT_DOWNLOADED.toString());
this.timer = _timer; this._timer = _timer;
this.timeoutTask = new TimeoutTask(this); this._timeoutTask = new TimeoutTask(this);
this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL); this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL);
this._volumeDao = volumeDao; this._volumeDao = volumeDao;
this._storageMgr = storageMgr; this._storageMgr = storageMgr;
this._resourceLimitMgr = _resourceLimitMgr; this._resourceLimitMgr = _resourceLimitMgr;
this._accountMgr = _accountMgr; this._accountMgr = _accountMgr;
this._alertMgr = _alertMgr; this._alertMgr = _alertMgr;
this._callback = callback;
updateDatabase(Status.NOT_DOWNLOADED, ""); updateDatabase(Status.NOT_DOWNLOADED, "");
} }
public void setCurrState(VMTemplateHostVO.Status currState) { public void setCurrState(VMTemplateHostVO.Status currState) {
this.currState = getState(currState.toString()); this._currState = getState(currState.toString());
} }
private void initStateMachine() { private void initStateMachine() {
stateMap.put(Status.NOT_DOWNLOADED.toString(), new NotDownloadedState(this)); _stateMap.put(Status.NOT_DOWNLOADED.toString(), new NotDownloadedState(this));
stateMap.put(Status.DOWNLOADED.toString(), new DownloadCompleteState(this)); _stateMap.put(Status.DOWNLOADED.toString(), new DownloadCompleteState(this));
stateMap.put(Status.DOWNLOAD_ERROR.toString(), new DownloadErrorState(this)); _stateMap.put(Status.DOWNLOAD_ERROR.toString(), new DownloadErrorState(this));
stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this)); _stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this));
stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this)); _stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this));
} }
private DownloadState getState(String stateName) { private DownloadState getState(String stateName) {
return stateMap.get(stateName); return _stateMap.get(stateName);
} }
public void sendCommand(RequestType reqType) { public void sendCommand(RequestType reqType) {
@ -243,10 +264,10 @@ public class DownloadListener implements Listener {
} }
try { try {
DownloadProgressCommand dcmd = new DownloadProgressCommand(getCommand(), getJobId(), reqType); DownloadProgressCommand dcmd = new DownloadProgressCommand(getCommand(), getJobId(), reqType);
if (template == null){ if (_template == null){
dcmd.setResourceType(ResourceType.VOLUME); dcmd.setResourceType(ResourceType.VOLUME);
} }
downloadMonitor.send(ssAgent.getId(), dcmd, this); _downloadMonitor.send(_ssAgent.getId(), dcmd, this);
} catch (AgentUnavailableException e) { } catch (AgentUnavailableException e) {
s_logger.debug("Send command failed", e); s_logger.debug("Send command failed", e);
setDisconnected(); setDisconnected();
@ -264,63 +285,63 @@ public class DownloadListener implements Listener {
} }
public void logDisconnect() { public void logDisconnect() {
if (template != null){ if (_template != null){
s_logger.warn("Unable to monitor download progress of " + template.getName() + " at host " + sserver.getName()); s_logger.warn("Unable to monitor download progress of " + _template.getName() + " at host " + _sserver.getName());
}else { }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) { public synchronized void updateDatabase(Status state, String errorString) {
if (template != null){ if (_template != null){
VMTemplateHostVO vo = vmTemplateHostDao.createForUpdate(); VMTemplateHostVO vo = _vmTemplateHostDao.createForUpdate();
vo.setDownloadState(state); vo.setDownloadState(state);
vo.setLastUpdated(new Date()); vo.setLastUpdated(new Date());
vo.setErrorString(errorString); vo.setErrorString(errorString);
vmTemplateHostDao.update(getTemplateHostId(), vo); _vmTemplateHostDao.update(getTemplateHostId(), vo);
}else { }else {
VolumeHostVO vo = volumeHostDao.createForUpdate(); VolumeHostVO vo = _volumeHostDao.createForUpdate();
vo.setDownloadState(state); vo.setDownloadState(state);
vo.setLastUpdated(new Date()); vo.setLastUpdated(new Date());
vo.setErrorString(errorString); vo.setErrorString(errorString);
volumeHostDao.update(getVolumeHostId(), vo); _volumeHostDao.update(getVolumeHostId(), vo);
} }
} }
public void log(String message, Level level) { public void log(String message, Level level) {
if (template != null){ if (_template != null){
s_logger.log(level, message + ", template=" + template.getName() + " at host " + sserver.getName()); s_logger.log(level, message + ", template=" + _template.getName() + " at host " + _sserver.getName());
}else { }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() { private Long getTemplateHostId() {
if (templateHostId == null){ if (_templateHostId == null){
VMTemplateHostVO templHost = vmTemplateHostDao.findByHostTemplate(sserver.getId(), template.getId()); VMTemplateHostVO templHost = _vmTemplateHostDao.findByHostTemplate(_sserver.getId(), _template.getId());
templateHostId = templHost.getId(); _templateHostId = templHost.getId();
} }
return templateHostId; return _templateHostId;
} }
private Long getTemplateStoreId() { private Long getTemplateStoreId() {
if (templateStoreId == null){ if (_templateStoreId == null){
TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(sstore.getId(), template.getId()); TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(_sstore.getId(), _template.getId());
templateStoreId = templStore.getId(); _templateStoreId = templStore.getId();
} }
return templateStoreId; return _templateStoreId;
} }
private Long getVolumeHostId() { private Long getVolumeHostId() {
if (volumeHostId == null){ if (_volumeHostId == null){
VolumeHostVO volHost = volumeHostDao.findByHostVolume(sserver.getId(), volume.getId()); VolumeHostVO volHost = _volumeHostDao.findByHostVolume(_sserver.getId(), _volume.getId());
volumeHostId = volHost.getId(); _volumeHostId = volHost.getId();
} }
return volumeHostId; return _volumeHostId;
} }
public DownloadListener(DownloadMonitorImpl monitor) { 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) { private synchronized void transition(DownloadEvent event, Object evtObj) {
if (currState == null) { if (_currState == null) {
return; return;
} }
String prevName = currState.getName(); String prevName = _currState.getName();
String nextState = currState.handleEvent(event, evtObj); String nextState = _currState.handleEvent(event, evtObj);
if (nextState != null) { if (nextState != null) {
currState = getState(nextState); _currState = getState(nextState);
if (currState != null) { if (_currState != null) {
currState.onEntry(prevName, event, evtObj); _currState.onEntry(prevName, event, evtObj);
} else { } else {
throw new CloudRuntimeException("Invalid next state: currState="+prevName+", evt="+event + ", next=" + nextState); 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) { public synchronized void updateDatabase(DownloadAnswer answer) {
if (template != null){ if (_template != null){
TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate(); TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate();
updateBuilder.setDownloadPercent(answer.getDownloadPct()); updateBuilder.setDownloadPercent(answer.getDownloadPct());
updateBuilder.setDownloadState(answer.getDownloadStatus()); updateBuilder.setDownloadState(answer.getDownloadStatus());
@ -380,40 +401,58 @@ public class DownloadListener implements Listener {
updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setSize(answer.getTemplateSize());
updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); 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); _vmTemplateStoreDao.update(getTemplateStoreId(), updateBuilder);
if (answer.getCheckSum() != null) { if (answer.getCheckSum() != null) {
VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate(); VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate();
templateDaoBuilder.setChecksum(answer.getCheckSum()); templateDaoBuilder.setChecksum(answer.getCheckSum());
_vmTemplateDao.update(template.getId(), templateDaoBuilder); _vmTemplateDao.update(_template.getId(), templateDaoBuilder);
} }
if (answer.getTemplateSize() > 0) { if (answer.getTemplateSize() > 0) {
//long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId(); //long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId();
long accountId = template.getAccountId(); long accountId = _template.getAccountId();
try { try {
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId),
com.cloud.configuration.Resource.ResourceType.secondary_storage, com.cloud.configuration.Resource.ResourceType.secondary_storage,
answer.getTemplateSize() - UriUtils.getRemoteSize(template.getUrl())); answer.getTemplateSize() - UriUtils.getRemoteSize(_template.getUrl()));
} catch (ResourceAllocationException e) { } catch (ResourceAllocationException e) {
s_logger.warn(e.getMessage()); 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()); null, e.getMessage(), e.getMessage());
} finally { } finally {
_resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(),
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); 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 { } else {
VolumeHostVO updateBuilder = volumeHostDao.createForUpdate(); VolumeHostVO updateBuilder = _volumeHostDao.createForUpdate();
updateBuilder.setDownloadPercent(answer.getDownloadPct()); updateBuilder.setDownloadPercent(answer.getDownloadPct());
updateBuilder.setDownloadState(answer.getDownloadStatus()); updateBuilder.setDownloadState(answer.getDownloadStatus());
updateBuilder.setLastUpdated(new Date()); updateBuilder.setLastUpdated(new Date());
@ -424,25 +463,25 @@ public class DownloadListener implements Listener {
updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setSize(answer.getTemplateSize());
updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
volumeHostDao.update(getVolumeHostId(), updateBuilder); _volumeHostDao.update(getVolumeHostId(), updateBuilder);
// Update volume size in Volume table. // Update volume size in Volume table.
VolumeVO updateVolume = _volumeDao.createForUpdate(); VolumeVO updateVolume = _volumeDao.createForUpdate();
updateVolume.setSize(answer.getTemplateSize()); updateVolume.setSize(answer.getTemplateSize());
_volumeDao.update(volume.getId(), updateVolume); _volumeDao.update(_volume.getId(), updateVolume);
if (answer.getTemplateSize() > 0) { if (answer.getTemplateSize() > 0) {
try { try {
String url = volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl(); String url = _volumeHostDao.findByVolumeId(_volume.getId()).getDownloadUrl();
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(_volume.getAccountId()),
com.cloud.configuration.Resource.ResourceType.secondary_storage, com.cloud.configuration.Resource.ResourceType.secondary_storage,
answer.getTemplateSize() - UriUtils.getRemoteSize(url)); answer.getTemplateSize() - UriUtils.getRemoteSize(url));
} catch (ResourceAllocationException e) { } catch (ResourceAllocationException e) {
s_logger.warn(e.getMessage()); s_logger.warn(e.getMessage());
_alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _volume.getDataCenterId(),
volume.getPodId(), e.getMessage(), e.getMessage()); _volume.getPodId(), e.getMessage(), e.getMessage());
} finally { } finally {
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), _resourceLimitMgr.recalculateResourceCount(_volume.getAccountId(), _volume.getDomainId(),
com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
} }
} }
@ -474,8 +513,12 @@ public class DownloadListener implements Listener {
@Override @Override
public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
if (cmd instanceof StartupRoutingCommand) { if (cmd instanceof StartupRoutingCommand) {
List<HypervisorType> hypers = _resourceMgr.listAvailHypervisorInZone(agent.getId(), agent.getDataCenterId());
downloadMonitor.handleSysTemplateDownload(agent); HypervisorType hostHyper = agent.getHypervisorType();
if (hypers.contains(hostHyper)) {
return;
}
_imageSrv.handleSysTemplateDownload(hostHyper, agent.getDataCenterId());
} }
/* This can be removed since /* This can be removed since
else if ( cmd instanceof StartupStorageCommand) { else if ( cmd instanceof StartupStorageCommand) {
@ -488,16 +531,20 @@ public class DownloadListener implements Listener {
} }
}*/ }*/
else if ( cmd instanceof StartupSecondaryStorageCommand ) { 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) { public void setCommand(DownloadCommand _cmd) {
this.cmd = _cmd; this._cmd = _cmd;
} }
public DownloadCommand getCommand() { public DownloadCommand getCommand() {
return cmd; return _cmd;
} }
@ -506,63 +553,63 @@ public class DownloadListener implements Listener {
} }
public void setJobId(String _jobId) { public void setJobId(String _jobId) {
this.jobId = _jobId; this._jobId = _jobId;
} }
public String getJobId() { public String getJobId() {
return jobId; return _jobId;
} }
public void scheduleStatusCheck(RequestType request) { public void scheduleStatusCheck(RequestType request) {
if (statusTask != null) statusTask.cancel(); if (_statusTask != null) _statusTask.cancel();
statusTask = new StatusTask(this, request); _statusTask = new StatusTask(this, request);
timer.schedule(statusTask, STATUS_POLL_INTERVAL); _timer.schedule(_statusTask, STATUS_POLL_INTERVAL);
} }
public void scheduleTimeoutTask(long delay) { public void scheduleTimeoutTask(long delay) {
if (timeoutTask != null) timeoutTask.cancel(); if (_timeoutTask != null) _timeoutTask.cancel();
timeoutTask = new TimeoutTask(this); _timeoutTask = new TimeoutTask(this);
timer.schedule(timeoutTask, delay); _timer.schedule(_timeoutTask, delay);
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
log("Scheduling timeout at " + delay + " ms", Level.DEBUG); log("Scheduling timeout at " + delay + " ms", Level.DEBUG);
} }
} }
public void scheduleImmediateStatusCheck(RequestType request) { public void scheduleImmediateStatusCheck(RequestType request) {
if (statusTask != null) statusTask.cancel(); if (_statusTask != null) _statusTask.cancel();
statusTask = new StatusTask(this, request); _statusTask = new StatusTask(this, request);
timer.schedule(statusTask, SMALL_DELAY); _timer.schedule(_statusTask, SMALL_DELAY);
} }
public boolean isDownloadActive() { public boolean isDownloadActive() {
return downloadActive; return _downloadActive;
} }
public void cancelStatusTask() { public void cancelStatusTask() {
if (statusTask != null) statusTask.cancel(); if (_statusTask != null) _statusTask.cancel();
} }
public Date getLastUpdated() { public Date getLastUpdated() {
return lastUpdated; return _lastUpdated;
} }
public void setLastUpdated() { public void setLastUpdated() {
lastUpdated = new Date(); _lastUpdated = new Date();
} }
public void setDownloadInactive(Status reason) { public void setDownloadInactive(Status reason) {
downloadActive=false; _downloadActive=false;
if (template != null){ if (_template != null){
downloadMonitor.handleDownloadEvent(sserver, template, reason); _downloadMonitor.handleDownloadEvent(_sserver, _template, reason);
}else { }else {
downloadMonitor.handleDownloadEvent(sserver, volume, reason); _downloadMonitor.handleDownloadEvent(_sserver, _volume, reason);
} }
} }
public void cancelTimeoutTask() { public void cancelTimeoutTask() {
if (timeoutTask != null) timeoutTask.cancel(); if (_timeoutTask != null) _timeoutTask.cancel();
} }
public void logDownloadStart() { public void logDownloadStart() {

View File

@ -16,8 +16,6 @@
// under the License. // under the License.
package com.cloud.storage.download; 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.CreateCmdResult;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback; 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.VMTemplateVO;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.template.TemplateInfo;
import com.cloud.utils.component.Manager; import com.cloud.utils.component.Manager;
/** /**
@ -37,23 +34,17 @@ import com.cloud.utils.component.Manager;
*/ */
public interface DownloadMonitor extends 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 cancelAllDownloads(Long templateId);
public void handleTemplateSync(DataStore store);
public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer) public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer)
throws StorageUnavailableException; 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); public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback<CreateCmdResult> callback);
boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format);
void handleVolumeSync(HostVO ssHost);
} }

View File

@ -18,12 +18,9 @@ package com.cloud.storage.download;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.concurrent.ConcurrentHashMap; 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.CreateCmdResult;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; 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.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.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; 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.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
import com.cloud.agent.Listener; import com.cloud.agent.Listener;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command; 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;
import com.cloud.agent.api.storage.DownloadCommand.Proxy; 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.RequestType;
import com.cloud.agent.api.storage.DownloadProgressCommand; 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.agent.manager.Commands;
import com.cloud.alert.AlertManager; import com.cloud.alert.AlertManager;
import com.cloud.configuration.Config; import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterDao;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
@ -70,9 +59,7 @@ import com.cloud.event.UsageEventUtils;
import com.cloud.event.dao.UsageEventDao; import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.StorageUnavailableException; import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.Host;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType; 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.Storage.ImageFormat;
import com.cloud.storage.StorageManager; import com.cloud.storage.StorageManager;
import com.cloud.storage.SwiftVO;
import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeHostVO;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.StoragePoolHostDao; 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.secondary.SecondaryStorageVmManager;
import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.swift.SwiftManager;
import com.cloud.storage.template.TemplateConstants; import com.cloud.storage.template.TemplateConstants;
import com.cloud.storage.template.TemplateInfo;
import com.cloud.template.TemplateManager; import com.cloud.template.TemplateManager;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.AccountManager; import com.cloud.user.AccountManager;
import com.cloud.user.ResourceLimitService; import com.cloud.user.ResourceLimitService;
import com.cloud.utils.UriUtils;
import com.cloud.utils.component.ManagerBase; import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.utils.db.JoinBuilder; 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.SecondaryStorageVm;
import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmDao; 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; import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
@ -152,6 +131,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
@Inject @Inject
VolumeHostDao _volumeHostDao; VolumeHostDao _volumeHostDao;
@Inject @Inject
VolumeDataStoreDao _volumeStoreDao;
@Inject
AlertManager _alertMgr; AlertManager _alertMgr;
@Inject @Inject
protected SwiftManager _swiftMgr; 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<TemplateDataStoreVO, DownloadListener> _listenerTemplateMap = new ConcurrentHashMap<TemplateDataStoreVO, DownloadListener>();
final Map<VMTemplateHostVO, DownloadListener> _listenerMap = new ConcurrentHashMap<VMTemplateHostVO, DownloadListener>(); final Map<VMTemplateHostVO, DownloadListener> _listenerMap = new ConcurrentHashMap<VMTemplateHostVO, DownloadListener>();
final Map<VolumeHostVO, DownloadListener> _listenerVolumeMap = new ConcurrentHashMap<VolumeHostVO, 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 { 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) { public boolean isTemplateUpdateable(Long templateId, Long storeId) {
List<TemplateDataStoreVO> downloadsInProgress = 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); return (downloadsInProgress.size() == 0);
} }
@ -370,7 +352,11 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
TemplateDataStoreVO vmTemplateStore = null; TemplateDataStoreVO vmTemplateStore = null;
vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); 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)) { if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) {
downloadJobExists = true; downloadJobExists = true;
} }
@ -420,42 +406,33 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
@Override @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(); long templateId = template.getId();
if (isTemplateUpdateable(templateId, store.getId())) { if (isTemplateUpdateable(templateId, store.getId())) {
if ( template != null && template.getUrl() != null ){ if ( template != null && template.getUrl() != null ){
initiateTemplateDownload(template, store, callback); initiateTemplateDownload(template, store, callback);
} }
} }
return true;
} }
@Override @Override
public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format) { public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback<CreateCmdResult> callback) {
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) {
boolean downloadJobExists = false; 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) { 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); "jobid0000", null, url, checkSum, format);
_volumeHostDao.persist(volumeHost); _volumeStoreDao.persist(volumeHost);
} else if ((volumeHost.getJobId() != null) && (volumeHost.getJobId().length() > 2)) { } else if ((volumeHost.getJobId() != null) && (volumeHost.getJobId().length() > 2)) {
downloadJobExists = true; downloadJobExists = true;
} }
Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes(); Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes();
String secUrl = sserver.getStorageUrl(); String secUrl = store.getUri();
if(volumeHost != null) { if(volumeHost != null) {
start(); start();
DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format); 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); dcmd.setResourceType(ResourceType.VOLUME);
} }
HostVO ssvm = _ssvmMgr.pickSsvmHost(sserver); HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
if( ssvm == null ) { if( ssAhost == null ) {
s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName()); s_logger.warn("There is no secondary storage VM for image store " + store.getName());
return; return;
} }
DownloadListener dl = new DownloadListener(ssvm, sserver, volume, _timer, _volumeHostDao, volumeHost.getId(), DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(),
this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr); this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback);
if (downloadJobExists) { if (downloadJobExists) {
dl.setCurrState(volumeHost.getDownloadState()); dl.setCurrState(volumeHost.getDownloadState());
} }
DownloadListener old = null; DownloadListener old = null;
synchronized (_listenerVolumeMap) { synchronized (_listenerVolMap) {
old = _listenerVolumeMap.put(volumeHost, dl); old = _listenerVolMap.put(volumeHost, dl);
} }
if( old != null ) { if( old != null ) {
old.abandon(); old.abandon();
} }
try { try {
send(ssvm.getId(), dcmd, dl); send(ssAhost.getId(), dcmd, dl);
} catch (AgentUnavailableException e) { } 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.setDisconnected();
dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); 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 @DB
public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) { public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) {
@ -583,62 +550,18 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
txn.commit(); 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 @Override
public void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos){ public void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateProp> templateInfos){
if ( templateInfos == null ) { if ( templateInfos == null ) {
return; return;
} }
Long hostId = host.getId(); Long hostId = host.getId();
List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates(); List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
for ( VMTemplateVO tmplt : rtngTmplts ) { for ( VMTemplateVO tmplt : rtngTmplts ) {
TemplateInfo tmpltInfo = templateInfos.get(tmplt.getUniqueName()); TemplateProp tmpltInfo = templateInfos.get(tmplt.getUniqueName());
if ( tmpltInfo == null ) { if ( tmpltInfo == null ) {
continue; 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 @Override
public void cancelAllDownloads(Long templateId) { 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);
}
}
}
} }

View File

@ -50,7 +50,7 @@ import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.template.TemplateConstants; 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 { public class DummySecondaryStorageResource extends ServerResourceBase implements ServerResource {
@ -113,7 +113,7 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements
public StartupCommand[] initialize() { public StartupCommand[] initialize() {
final StartupStorageCommand cmd = new StartupStorageCommand("dummy", final StartupStorageCommand cmd = new StartupStorageCommand("dummy",
StoragePoolType.NetworkFilesystem, 1024*1024*1024*100L, StoragePoolType.NetworkFilesystem, 1024*1024*1024*100L,
new HashMap<String, TemplateInfo>()); new HashMap<String, TemplateProp>());
cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE); cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
cmd.setIqn(null); cmd.setIqn(null);
@ -173,12 +173,12 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements
return _useServiceVm; return _useServiceVm;
} }
public Map<String, TemplateInfo> getDefaultSystemVmTemplateInfo() { public Map<String, TemplateProp> getDefaultSystemVmTemplateInfo() {
List<VMTemplateVO> tmplts = _tmpltDao.listAllSystemVMTemplates(); List<VMTemplateVO> tmplts = _tmpltDao.listAllSystemVMTemplates();
Map<String, TemplateInfo> tmpltInfo = new HashMap<String, TemplateInfo>(); Map<String, TemplateProp> tmpltInfo = new HashMap<String, TemplateProp>();
if (tmplts != null) { if (tmplts != null) {
for (VMTemplateVO tmplt : tmplts) { 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); tmpltInfo.put(tmplt.getUniqueName(), routingInfo);
} }
} }

View File

@ -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.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; 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.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.engine.subsystem.api.storage.ZoneScope;
import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -75,7 +75,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
@Inject AgentManager _agentMgr; @Inject AgentManager _agentMgr;
@Inject DataStoreManager storeMgr; @Inject DataStoreManager storeMgr;
@Inject ImageService imageService; @Inject TemplateService imageService;
@Inject ImageDataFactory imageFactory; @Inject ImageDataFactory imageFactory;
@Inject TemplateManager templateMgr; @Inject TemplateManager templateMgr;

View File

@ -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. * 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. * Prepares a template for vm creation for a certain storage pool.

View File

@ -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.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; 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.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.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; 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; import com.cloud.vm.dao.VMInstanceDao;
@Component @Component
@Local(value={TemplateManager.class, TemplateService.class}) @Local(value={TemplateManager.class, TemplateApiService.class})
public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateService { public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateApiService {
private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class); private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
@Inject VMTemplateDao _tmpltDao; @Inject VMTemplateDao _tmpltDao;
@Inject VMTemplateHostDao _tmpltHostDao; @Inject VMTemplateHostDao _tmpltHostDao;
@ -246,7 +246,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Inject @Inject
SnapshotDataFactory snapshotFactory; SnapshotDataFactory snapshotFactory;
@Inject @Inject
ImageService imageSvr; TemplateService imageSvr;
@Inject @Inject
DataStoreManager dataStoreMgr; DataStoreManager dataStoreMgr;
@Inject @Inject