mirror of https://github.com/apache/cloudstack.git
bug CS-10789: Adding volume sync and delete functionality.
This commit is contained in:
parent
54956280e6
commit
ac2175bdbc
|
|
@ -0,0 +1,22 @@
|
|||
package com.cloud.agent.api.storage;
|
||||
|
||||
public class DeleteVolumeCommand extends ssCommand {
|
||||
private String volumePath;
|
||||
|
||||
public DeleteVolumeCommand() {
|
||||
}
|
||||
|
||||
public DeleteVolumeCommand(String secUrl, String volumePath) {
|
||||
this.setSecUrl(secUrl);
|
||||
this.volumePath = volumePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getVolumePath() {
|
||||
return volumePath;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.cloud.agent.api.storage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.storage.template.TemplateInfo;
|
||||
|
||||
public class ListVolumeAnswer extends Answer {
|
||||
private String secUrl;
|
||||
private Map<Long, TemplateInfo> templateInfos;
|
||||
|
||||
public ListVolumeAnswer() {
|
||||
|
||||
}
|
||||
|
||||
public ListVolumeAnswer(String secUrl, Map<Long, TemplateInfo> templateInfos) {
|
||||
super(null, true, "success");
|
||||
this.setSecUrl(secUrl);
|
||||
this.templateInfos = templateInfos;
|
||||
}
|
||||
|
||||
public Map<Long, TemplateInfo> getTemplateInfo() {
|
||||
return templateInfos;
|
||||
}
|
||||
|
||||
public void setTemplateInfo(Map<Long, TemplateInfo> templateInfos) {
|
||||
this.templateInfos = templateInfos;
|
||||
}
|
||||
|
||||
public void setSecUrl(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
}
|
||||
|
||||
public String getSecUrl() {
|
||||
return secUrl;
|
||||
}
|
||||
}
|
||||
|
|
@ -54,20 +54,20 @@ import com.cloud.agent.api.SecStorageSetupAnswer;
|
|||
import com.cloud.agent.api.SecStorageSetupCommand;
|
||||
import com.cloud.agent.api.SecStorageSetupCommand.Certificates;
|
||||
import com.cloud.agent.api.StartupSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
|
||||
import com.cloud.agent.api.SecStorageVMSetupCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
|
||||
import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
|
||||
import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
|
||||
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.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.api.storage.UploadCommand;
|
||||
import com.cloud.agent.api.storage.ssCommand;
|
||||
|
|
@ -156,7 +156,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
return execute((ComputeChecksumCommand)cmd);
|
||||
} else if (cmd instanceof ListTemplateCommand){
|
||||
return execute((ListTemplateCommand)cmd);
|
||||
} else if (cmd instanceof downloadSnapshotFromSwiftCommand){
|
||||
} else if (cmd instanceof ListVolumeCommand){
|
||||
return execute((ListVolumeCommand)cmd);
|
||||
}else if (cmd instanceof downloadSnapshotFromSwiftCommand){
|
||||
return execute((downloadSnapshotFromSwiftCommand)cmd);
|
||||
} else if (cmd instanceof DeleteSnapshotBackupCommand){
|
||||
return execute((DeleteSnapshotBackupCommand)cmd);
|
||||
|
|
@ -709,8 +711,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
}
|
||||
|
||||
String root = getRootDir(cmd.getSecUrl());
|
||||
Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
|
||||
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
|
||||
Map<Long, TemplateInfo> templateInfos = _dlMgr.gatherVolumeInfo(root);
|
||||
return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -893,6 +895,54 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
return new Answer(cmd, true, null);
|
||||
}
|
||||
|
||||
protected Answer execute(final DeleteVolumeCommand cmd) {
|
||||
String relativeVolumePath = cmd.getVolumePath();
|
||||
String parent = getRootDir(cmd);
|
||||
|
||||
if (relativeVolumePath.startsWith(File.separator)) {
|
||||
relativeVolumePath = relativeVolumePath.substring(1);
|
||||
}
|
||||
|
||||
if (!parent.endsWith(File.separator)) {
|
||||
parent += File.separator;
|
||||
}
|
||||
String absoluteVolumePath = parent + relativeVolumePath;
|
||||
File tmpltParent = new File(absoluteVolumePath).getParentFile();
|
||||
String details = null;
|
||||
if (!tmpltParent.exists()) {
|
||||
details = "volume parent directory " + tmpltParent.getName() + " doesn't exist";
|
||||
s_logger.debug(details);
|
||||
return new Answer(cmd, true, details);
|
||||
}
|
||||
File[] tmpltFiles = tmpltParent.listFiles();
|
||||
if (tmpltFiles == null || tmpltFiles.length == 0) {
|
||||
details = "No files under volume parent directory " + tmpltParent.getName();
|
||||
s_logger.debug(details);
|
||||
} else {
|
||||
boolean found = false;
|
||||
for (File f : tmpltFiles) {
|
||||
if (!found && f.getName().equals("volume.properties")) {
|
||||
found = true;
|
||||
}
|
||||
if (!f.delete()) {
|
||||
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path "
|
||||
+ relativeVolumePath);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
details = "Can not find volume.properties under " + tmpltParent.getName();
|
||||
s_logger.debug(details);
|
||||
}
|
||||
}
|
||||
if (!tmpltParent.delete()) {
|
||||
details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path "
|
||||
+ relativeVolumePath;
|
||||
s_logger.debug(details);
|
||||
return new Answer(cmd, false, details);
|
||||
}
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
|
||||
Answer execute(CleanupSnapshotBackupCommand cmd) {
|
||||
String parent = getRootDir(cmd.getSecondaryStoragePoolURL());
|
||||
if (!parent.endsWith(File.separator)) {
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ public interface DownloadManager extends Manager {
|
|||
/**
|
||||
* @return list of volume info for installed volumes
|
||||
*/
|
||||
public Map<String, TemplateInfo> gatherVolumeInfo(String volumeDir);
|
||||
public Map<Long, TemplateInfo> gatherVolumeInfo(String volumeDir);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -702,6 +702,8 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private List<String> listTemplates(String rootdir) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
|
||||
|
|
@ -771,6 +773,52 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, TemplateInfo> gatherVolumeInfo(String rootDir) {
|
||||
Map<Long, TemplateInfo> result = new HashMap<Long, TemplateInfo>();
|
||||
String volumeDir = rootDir + File.separator + _volumeDir;
|
||||
|
||||
if (! _storage.exists(volumeDir)) {
|
||||
_storage.mkdirs(volumeDir);
|
||||
}
|
||||
|
||||
List<String> vols = listVolumes(volumeDir);
|
||||
for (String vol : vols) {
|
||||
String path = vol.substring(0, vol.lastIndexOf(File.separator));
|
||||
TemplateLocation loc = new TemplateLocation(_storage, path);
|
||||
try {
|
||||
if (!loc.load()) {
|
||||
s_logger.warn("Post download installation was not completed for " + path);
|
||||
//loc.purge();
|
||||
_storage.cleanup(path, volumeDir);
|
||||
continue;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
s_logger.warn("Unable to load volume location " + path, e);
|
||||
continue;
|
||||
}
|
||||
|
||||
TemplateInfo vInfo = loc.getTemplateInfo();
|
||||
|
||||
if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
|
||||
try {
|
||||
Processor processor = _processors.get("VMDK Processor");
|
||||
VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
|
||||
long vSize = vmdkProcessor.getTemplateVirtualSize(path, vInfo.installPath.substring(vInfo.installPath.lastIndexOf(File.separator) + 1));
|
||||
vInfo.size = vSize;
|
||||
loc.updateVirtualSize(vSize);
|
||||
loc.save();
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Unable to get the virtual size of the volume: " + vInfo.installPath + " due to " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
result.put(vInfo.getId(), vInfo);
|
||||
s_logger.debug("Added volume name: " + vInfo.templateName + ", path: " + vol);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int deleteDownloadDirectories(File downloadPath, int deleted) {
|
||||
try {
|
||||
if (downloadPath.exists()) {
|
||||
|
|
@ -879,11 +927,11 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
}
|
||||
s_logger.info("createtmplt.sh found in " + createTmpltScr);
|
||||
|
||||
/*listVolScr = Script.findScript(scriptsDir, "listvolume.sh");
|
||||
listVolScr = Script.findScript(scriptsDir, "listvolume.sh");
|
||||
if (listVolScr == null) {
|
||||
throw new ConfigurationException("Unable to find the listvolume.sh");
|
||||
}
|
||||
s_logger.info("listvolume.sh found in " + listVolScr);*/
|
||||
s_logger.info("listvolume.sh found in " + listVolScr);
|
||||
|
||||
createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
|
||||
if (createVolScr == null) {
|
||||
|
|
@ -995,10 +1043,5 @@ public class DownloadManagerImpl implements DownloadManager {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TemplateInfo> gatherVolumeInfo(String volumeDir) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.Properties;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.storage.template.Processor.FormatInfo;
|
||||
|
|
@ -34,6 +35,7 @@ public class TemplateLocation {
|
|||
StorageLayer _storage;
|
||||
String _templatePath;
|
||||
boolean _isCorrupted;
|
||||
ResourceType _resourceType = ResourceType.TEMPLATE;
|
||||
|
||||
File _file;
|
||||
Properties _props;
|
||||
|
|
@ -48,9 +50,10 @@ public class TemplateLocation {
|
|||
}
|
||||
_formats = new ArrayList<FormatInfo>(5);
|
||||
_props = new Properties();
|
||||
//TO DO remove this hack
|
||||
//TO DO - remove this hack
|
||||
if (_templatePath.matches(".*"+"volumes"+".*")){
|
||||
_file = _storage.getFile(_templatePath + "volume.properties");
|
||||
_resourceType = ResourceType.VOLUME;
|
||||
}else {
|
||||
_file = _storage.getFile(_templatePath + Filename);
|
||||
}
|
||||
|
|
@ -153,7 +156,11 @@ public class TemplateLocation {
|
|||
TemplateInfo tmplInfo = new TemplateInfo();
|
||||
tmplInfo.id = Long.parseLong(_props.getProperty("id"));
|
||||
tmplInfo.installPath = _templatePath + File.separator + _props.getProperty("filename");
|
||||
tmplInfo.installPath = tmplInfo.installPath.substring(tmplInfo.installPath.indexOf("template"));
|
||||
if (_resourceType == ResourceType.VOLUME){
|
||||
tmplInfo.installPath = tmplInfo.installPath.substring(tmplInfo.installPath.indexOf("volumes"));
|
||||
}else {
|
||||
tmplInfo.installPath = tmplInfo.installPath.substring(tmplInfo.installPath.indexOf("template"));
|
||||
}
|
||||
tmplInfo.isCorrupted = _isCorrupted;
|
||||
tmplInfo.isPublic = Boolean.parseBoolean(_props.getProperty("public"));
|
||||
tmplInfo.templateName = _props.getProperty("uniquename");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
|
||||
#
|
||||
# This software is licensed under the GNU General Public License v3 or later.
|
||||
#
|
||||
# It is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# $Id: listvmvolume.sh 9132 2010-06-04 20:17:43Z manuel $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/storage/secondary/listvmvolume.sh $
|
||||
# listvolume.sh -- list volumes under a directory
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s: -r <root dir> \n" $(basename $0) >&2
|
||||
}
|
||||
|
||||
|
||||
#set -x
|
||||
|
||||
rflag=
|
||||
rootdir=
|
||||
|
||||
while getopts 'r:' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
r) rflag=1
|
||||
rootdir="$OPTARG"
|
||||
;;
|
||||
?) usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$rflag" != "1" ]
|
||||
then
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
|
||||
|
||||
for i in $(find /$rootdir -name volume.properties );
|
||||
do
|
||||
d=$(dirname $i)
|
||||
filename=$(grep "^filename" $i | awk -F"=" '{print $NF}')
|
||||
# size=$(grep "virtualsize" $i | awk -F"=" '{print $NF}')
|
||||
# if [ -n "$filename" ] && [ -n "$size" ]
|
||||
# then
|
||||
# d=$d/$filename/$size
|
||||
# fi
|
||||
echo ${d#/}/$filename #remove leading slash
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
package com.cloud.storage.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.storage.VolumeHostVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface VolumeHostDao extends GenericDao<VolumeHostVO, Long> {
|
||||
|
||||
VolumeHostVO findByHostVolume(long id, long id2);
|
||||
VolumeHostVO findByHostVolume(long hostId, long volumeId);
|
||||
|
||||
VolumeHostVO findByVolumeId(long volumeId);
|
||||
|
||||
List<VolumeHostVO> listBySecStorage(long sserverId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ package com.cloud.storage.dao;
|
|||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.storage.VolumeHostVO;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
|
|
@ -13,6 +15,7 @@ public class VolumeHostDaoImpl extends GenericDaoBase<VolumeHostVO, Long> implem
|
|||
|
||||
protected final SearchBuilder<VolumeHostVO> HostVolumeSearch;
|
||||
protected final SearchBuilder<VolumeHostVO> VolumeSearch;
|
||||
protected final SearchBuilder<VolumeHostVO> HostSearch;
|
||||
|
||||
VolumeHostDaoImpl(){
|
||||
HostVolumeSearch = createSearchBuilder();
|
||||
|
|
@ -21,6 +24,11 @@ public class VolumeHostDaoImpl extends GenericDaoBase<VolumeHostVO, Long> implem
|
|||
HostVolumeSearch.and("destroyed", HostVolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
HostVolumeSearch.done();
|
||||
|
||||
HostSearch = createSearchBuilder();
|
||||
HostSearch.and("host_id", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
|
||||
HostSearch.and("destroyed", HostSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
HostSearch.done();
|
||||
|
||||
VolumeSearch = createSearchBuilder();
|
||||
VolumeSearch.and("volume_id", VolumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeSearch.and("destroyed", VolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -46,4 +54,14 @@ public class VolumeHostDaoImpl extends GenericDaoBase<VolumeHostVO, Long> implem
|
|||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<VolumeHostVO> listBySecStorage(long ssHostId) {
|
||||
SearchCriteria<VolumeHostVO> sc = HostSearch.create();
|
||||
sc.setParameters("host_id", ssHostId);
|
||||
sc.setParameters("destroyed", false);
|
||||
return listAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -338,13 +338,14 @@ public class DownloadListener implements Listener {
|
|||
updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
|
||||
|
||||
volumeHostDao.update(getVolumeHostId(), updateBuilder);
|
||||
try {
|
||||
_storageMgr.stateTransitTo(volume, Event.UploadSucceeded);
|
||||
} catch (NoTransitionException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
if (answer.getDownloadStatus() == Status.DOWNLOADED){
|
||||
try {
|
||||
_storageMgr.stateTransitTo(volume, Event.UploadSucceeded);
|
||||
} catch (NoTransitionException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*if (answer.getCheckSum() != null) {
|
||||
VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate();
|
||||
templateDaoBuilder.setChecksum(answer.getCheckSum());
|
||||
|
|
@ -379,9 +380,10 @@ public class DownloadListener implements Listener {
|
|||
storage.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE ) {
|
||||
downloadMonitor.addSystemVMTemplatesToHost(agent, storage.getTemplateInfo());
|
||||
downloadMonitor.handleTemplateSync(agent);
|
||||
downloadMonitor.handleVolumeSync(agent);
|
||||
}
|
||||
} else if ( cmd instanceof StartupSecondaryStorageCommand ) {
|
||||
downloadMonitor.handleTemplateSync(agent.getDataCenterId());
|
||||
downloadMonitor.handleSync(agent.getDataCenterId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,10 +39,12 @@ public interface DownloadMonitor extends Manager{
|
|||
|
||||
void handleSysTemplateDownload(HostVO hostId);
|
||||
|
||||
void handleTemplateSync(Long dcId);
|
||||
void handleSync(Long dcId);
|
||||
|
||||
void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos);
|
||||
|
||||
boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum);
|
||||
|
||||
void handleVolumeSync(HostVO ssHost);
|
||||
|
||||
}
|
||||
|
|
@ -32,7 +32,10 @@ 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.ListVolumeAnswer;
|
||||
import com.cloud.agent.api.storage.ListVolumeCommand;
|
||||
import com.cloud.agent.api.storage.DownloadCommand.Proxy;
|
||||
import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
|
||||
import com.cloud.agent.api.storage.DownloadProgressCommand;
|
||||
|
|
@ -620,11 +623,12 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handleTemplateSync(Long dcId) {
|
||||
public void handleSync(Long dcId) {
|
||||
if (dcId != null) {
|
||||
List<HostVO> ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dcId);
|
||||
for (HostVO ssHost : ssHosts) {
|
||||
handleTemplateSync(ssHost);
|
||||
handleVolumeSync(ssHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -644,6 +648,21 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
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;
|
||||
|
|
@ -660,7 +679,88 @@ public class DownloadMonitorImpl implements DownloadMonitor {
|
|||
}
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
//Download volumes which havent 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());
|
||||
}
|
||||
}
|
||||
|
||||
//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(HostVO ssHost) {
|
||||
if (ssHost == null) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue