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