Swift: add listtemplate for swift

add swift configuration
This commit is contained in:
anthony 2011-10-25 20:21:27 -07:00
parent 510d1dbef7
commit b91dce4f8a
18 changed files with 388 additions and 37 deletions

View File

@ -17,16 +17,25 @@
*/
package com.cloud.agent.api.storage;
import com.cloud.agent.api.to.SwiftTO;
public class ListTemplateCommand extends StorageCommand {
private String secUrl;
private SwiftTO swift;
public ListTemplateCommand() {
}
public ListTemplateCommand(String secUrl) {
this.secUrl = secUrl;
this.swift = null;
}
public ListTemplateCommand(SwiftTO swift) {
this.secUrl = null;
this.swift = swift;
}
@Override
public boolean executeInSequence() {
return true;
@ -36,8 +45,8 @@ public class ListTemplateCommand extends StorageCommand {
return secUrl;
}
public void setSecUrl(String secUrl) {
this.secUrl = secUrl;
public SwiftTO getSwift() {
return swift;
}
}

View File

@ -17,9 +17,12 @@
*/
package com.cloud.storage;
import com.cloud.agent.api.to.SwiftTO;
public interface Swift {
public String getUrl();
public String getAccount();
public String getUserName();
public String getKey();
public SwiftTO toSwiftTO();
}

View File

@ -24,6 +24,8 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.agent.api.to.SwiftTO;
@Entity
@Table(name="swift")
@ -75,4 +77,8 @@ public class SwiftVO implements Swift {
return key;
}
@Override
public SwiftTO toSwiftTO() {
return new SwiftTO(getId(), getUrl(), getAccount(), getUserName(), getKey());
}
}

View File

@ -78,12 +78,14 @@ 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.TemplateLocation;
import com.cloud.storage.template.UploadManager;
import com.cloud.storage.template.UploadManagerImpl;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.Script;
import com.cloud.vm.SecondaryStorageVm;
@ -112,6 +114,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
private String _eth1mask;
private String _eth1ip;
final private String _parent = "/mnt/SecStorage";
final private String _tmpltDir = "/var/cloudstack/template";
final private String _tmpltpp = "template.properties";
@Override
public void disconnected() {
}
@ -235,6 +239,28 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
return null;
}
String[] swiftList(SwiftTO swift, String container, String rFilename) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K "
+ swift.getKey() + " list " + container + " " + rFilename);
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
String result = command.execute(parser);
if (result == null && parser.getLines() != null) {
String[] lines = parser.getLines().split("\\n");
return lines;
} else {
if (result != null) {
String errMsg = "swiftList failed , err=" + result;
s_logger.warn(errMsg);
} else {
String errMsg = "swiftList, no lines returns";
s_logger.warn(errMsg);
}
}
return null;
}
String swiftDelete(SwiftTO swift, String container, String rFilename) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
@ -374,7 +400,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
}
return new Answer(cmd, false, checksum);
}
}
}
return new Answer(cmd, true, checksum);
}
@ -451,14 +477,51 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
}
}
Map<String, TemplateInfo> swiftListTemplate(SwiftTO swift) {
String[] containers = swiftList(swift, "", "");
if (containers == null) {
return null;
}
Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>();
for( String container : containers) {
if ( container.startsWith("T-")) {
String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
createLocalDir(ldir);
String lFullPath = ldir + "/" + _tmpltpp;
swiftDownload(swift, container, _tmpltpp, lFullPath);
TemplateLocation loc = new TemplateLocation(_storage, ldir);
try {
if (!loc.load()) {
s_logger.warn("Can not parse template.properties file for template " + container);
continue;
}
} catch (IOException e) {
s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
continue;
}
TemplateInfo tInfo = loc.getTemplateInfo();
tInfo.setInstallPath(container);
tmpltInfos.put(tInfo.getTemplateName(), tInfo);
loc.purge();
deleteLocalDir(ldir);
}
}
return tmpltInfos;
}
private Answer execute(ListTemplateCommand cmd) {
if (!_inSystemVM){
return new Answer(cmd, true, null);
}
String root = getRootDir(cmd.getSecUrl());
Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
if (cmd.getSwift() != null) {
Map<String, TemplateInfo> templateInfos = swiftListTemplate(cmd.getSwift());
return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
} else {
String root = getRootDir(cmd.getSecUrl());
Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
}
}
private Answer execute(SecStorageVMSetupCommand cmd) {
@ -513,6 +576,19 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
return null;
}
private String deleteLocalDir(String folder) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("rmdir " + folder);
String result = command.execute();
if (result != null) {
String errMsg = "Delete local path " + folder + " failed , err=" + result;
s_logger.warn(errMsg);
return errMsg;
}
return null;
}
private String deleteLocalFile(String fullPath) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");

View File

@ -640,12 +640,6 @@ public class DownloadManagerImpl implements DownloadManager {
}
} catch (IOException e) {
s_logger.warn("Unable to load template location " + path, e);
//loc.purge();
try {
_storage.cleanup(path, templateDir);
} catch (IOException e1) {
s_logger.warn("Unable to cleanup " + path, e1);
}
continue;
}

View File

@ -27,8 +27,8 @@ import java.util.Properties;
import org.apache.log4j.Logger;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.StorageLayer;
import com.cloud.storage.template.Processor.FormatInfo;
import com.cloud.utils.NumbersUtil;
@ -192,7 +192,7 @@ public class TemplateLocation {
}
protected boolean checkFormatValidity(FormatInfo info) {
return (info.format != null && info.size > 0 && info.virtualSize > 0 && info.filename != null && _storage.exists(_templatePath + info.filename) && _storage.getSize(_templatePath + info.filename) == info.size);
return (info.format != null && info.size > 0 && info.virtualSize > 0 && info.filename != null);
}
protected FormatInfo deleteFormat(ImageFormat format) {

View File

@ -258,7 +258,7 @@ public interface AgentManager extends Manager {
Answer sendToSecStorage(HostVO ssHost, Command cmd);
Answer sendToSSVM(final long dcId, final Command cmd);
Answer sendToSSVM(Long dcId, final Command cmd);
HostVO getSSAgent(HostVO ssHost);

View File

@ -550,14 +550,12 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
}
@Override
public Answer sendToSSVM(final long dcId, final Command cmd) {
List<HostVO> ssAHosts = _hostDao.listSecondaryStorageVM(dcId);
if (ssAHosts == null || ssAHosts.isEmpty() ) {
public Answer sendToSSVM(final Long dcId, final Command cmd) {
HostVO ssAHost = _hostDao.findSecondaryStorageVM(dcId);
if (ssAHost == null) {
return new Answer(cmd, false, "can not find secondary storage VM agent for data center " + dcId);
}
Collections.shuffle(ssAHosts);
HostVO ssAhost = ssAHosts.get(0);
return easySend(ssAhost.getId(), cmd);
return easySend(ssAHost.getId(), cmd);
}
@Override

View File

@ -130,6 +130,8 @@ public enum Config {
// Advanced
JobExpireMinutes("Advanced", ManagementServer.class, String.class, "job.expire.minutes", "1440", "Time (in minutes) for async-jobs to be kept in system", null),
JobCancelThresholdMinutes("Advanced", ManagementServer.class, String.class, "job.cancel.threshold.minutes", "60", "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", null),
SwiftEnable(
"Advanced", ManagementServer.class, Boolean.class, "swift.enable", "false", "enable swift ", null),
AccountCleanupInterval("Advanced", ManagementServer.class, Integer.class, "account.cleanup.interval", "86400", "The interval (in seconds) between cleanup for removed accounts", null),
AllowPublicUserTemplates("Advanced", ManagementServer.class, Integer.class, "allow.public.user.templates", "true", "If false, users will not be able to create public templates.", null),

View File

@ -93,6 +93,8 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network;
@ -115,7 +117,9 @@ import com.cloud.projects.ProjectManager;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.SwiftVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.SwiftDao;
import com.cloud.test.IPRangeConfig;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
@ -163,6 +167,10 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
@Inject
DomainDao _domainDao;
@Inject
HostDao _hostDao;
@Inject
SwiftDao _swiftDao;
@Inject
ServiceOfferingDao _serviceOfferingDao;
@Inject
DiskOfferingDao _diskOfferingDao;
@ -441,6 +449,16 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
s_logger.error("Configuration variable " + name + " is expecting true or false in stead of " + value);
return "Please enter either 'true' or 'false'.";
}
if (Config.SwiftEnable.key().equals(name)) {
HostVO host = _hostDao.findSecondaryStorageHost(null);
if (host != null) {
return " can not change " + Config.SwiftEnable.key() + " after you have added secondary storage";
}
SwiftVO swift = _swiftDao.findById(1L);
if (swift != null) {
return " can not change " + Config.SwiftEnable.key() + " after you have added Swift";
}
}
return null;
}

View File

@ -43,7 +43,8 @@ public interface HostDao extends GenericDao<HostVO, Long> {
List<HostVO> listByStatus(Status... status);
List<HostVO> listBy(Host.Type type, long dcId);
List<HostVO> listAllBy(Host.Type type, long dcId);
HostVO findSecondaryStorageHost(long dcId);
HostVO findSecondaryStorageHost(Long dcId);
List<HostVO> listByCluster(long clusterId);
/**
* Lists all secondary storage hosts, across all zones
@ -178,5 +179,7 @@ public interface HostDao extends GenericDao<HostVO, Long> {
List<HostVO> listByInAllStatus(Type type, Long clusterId, Long podId, long dcId);
List<HostVO> listByClusterStatus(long clusterId, Status status);
List<HostVO> listByClusterStatus(long clusterId, Status status);
HostVO findSecondaryStorageVM(Long dcId);
}

View File

@ -311,10 +311,29 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
}
@Override
public HostVO findSecondaryStorageHost(long dcId) {
public HostVO findSecondaryStorageHost(Long dcId) {
SearchCriteria<HostVO> sc = TypeDcSearch.create();
sc.setParameters("type", Host.Type.SecondaryStorage);
sc.setParameters("dc", dcId);
if (dcId != null) {
sc.setParameters("dc", dcId);
}
List<HostVO> storageHosts = listBy(sc);
if (storageHosts == null || storageHosts.size() < 1) {
return null;
} else {
Collections.shuffle(storageHosts);
return storageHosts.get(0);
}
}
@Override
public HostVO findSecondaryStorageVM(Long dcId) {
SearchCriteria<HostVO> sc = SecondaryStorageVMSearch.create();
sc.setParameters("type", Host.Type.SecondaryStorageVM);
sc.setParameters("status", Status.Up);
if (dcId != null) {
sc.setParameters("dc", dcId);
}
List<HostVO> storageHosts = listBy(sc);
if (storageHosts == null || storageHosts.size() < 1) {
return null;

View File

@ -197,6 +197,7 @@ import com.cloud.storage.dao.UploadDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.storage.upload.UploadMonitor;
import com.cloud.template.TemplateManager;
import com.cloud.template.VirtualMachineTemplate;
@ -310,6 +311,8 @@ public class ManagementServerImpl implements ManagementServer {
private final HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
private final Adapters<HostAllocator> _hostAllocators;
@Inject ProjectManager _projectMgr;
@Inject
SnapshotManager _snapshotMgr;
private final KeystoreManager _ksMgr;
@ -1382,7 +1385,14 @@ public class ManagementServerImpl implements ManagementServer {
Set<Pair<Long, Long>> templateZonePairSet = new HashSet<Pair<Long, Long>>();
if (template == null) {
templateZonePairSet = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller);
Boolean swiftEnable = Boolean.valueOf(_configDao.getValue(Config.SwiftEnable.key()));
if (swiftEnable) {
templateZonePairSet = _templateDao.searchSwiftTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr,
permittedAccounts, caller);
} else {
templateZonePairSet = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr,
permittedAccounts, caller);
}
} else {
// if template is not public, perform permission check here
if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {

View File

@ -61,6 +61,9 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long> {
public Set<Pair<Long, Long>> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List<HypervisorType> hypers, Boolean bootable,
DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List<Account> permittedAccounts, Account caller);
public Set<Pair<Long, Long>> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List<HypervisorType> hypers, Boolean bootable, DomainVO domain,
Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List<Account> permittedAccounts, Account caller);
public long addTemplateToZone(VMTemplateVO tmplt, long zoneId);
public List<VMTemplateVO> listAllInZone(long dataCenterId);

View File

@ -81,7 +81,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
private final String SELECT_TEMPLATE_ZONE_REF = "SELECT t.id, tzr.zone_id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " +
"t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t INNER JOIN template_zone_ref tzr on (t.id = tzr.template_id) ";
protected SearchBuilder<VMTemplateVO> TemplateNameSearch;
protected SearchBuilder<VMTemplateVO> UniqueNameSearch;
protected SearchBuilder<VMTemplateVO> tmpltTypeSearch;
@ -302,6 +302,149 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
public String getRoutingTemplateUniqueName() {
return routerTmpltName;
}
@Override
public Set<Pair<Long, Long>> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List<HypervisorType> hypers, Boolean bootable, DomainVO domain,
Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List<Account> permittedAccounts, Account caller) {
StringBuilder builder = new StringBuilder();
if (!permittedAccounts.isEmpty()) {
for (Account permittedAccount : permittedAccounts) {
builder.append(permittedAccount.getAccountId() + ",");
}
}
String permittedAccountsStr = builder.toString();
if (permittedAccountsStr.length() > 0) {
// chop the "," off
permittedAccountsStr = permittedAccountsStr.substring(0, permittedAccountsStr.length() - 1);
}
Transaction txn = Transaction.currentTxn();
txn.start();
Set<Pair<Long, Long>> templateZonePairList = new HashSet<Pair<Long, Long>>();
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = SELECT_TEMPLATE_HOST_REF;
String groupByClause = "";
try {
// short accountType;
// String accountId = null;
String guestOSJoin = "";
StringBuilder templateHostRefJoin = new StringBuilder();
String dataCenterJoin = "";
if (isIso && !hyperType.equals(HypervisorType.None)) {
guestOSJoin = " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) ";
}
if (onlyReady) {
templateHostRefJoin.append(" INNER JOIN template_swift_ref tsr on (t.id = tsr.template_id)");
}
sql += guestOSJoin + templateHostRefJoin + dataCenterJoin;
String whereClause = "";
if (!isIso) {
if (hypers.isEmpty()) {
return templateZonePairList;
} else {
StringBuilder relatedHypers = new StringBuilder();
for (HypervisorType hyper : hypers) {
relatedHypers.append("'");
relatedHypers.append(hyper.toString());
relatedHypers.append("'");
relatedHypers.append(",");
}
relatedHypers.setLength(relatedHypers.length() - 1);
whereClause += " AND t.hypervisor_type IN (" + relatedHypers + ")";
}
}
if (templateFilter == TemplateFilter.featured) {
whereClause += " WHERE t.public = 1 AND t.featured = 1";
} else if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
whereClause += " INNER JOIN account a on (t.account_id = a.id) INNER JOIN domain d on (a.domain_id = d.id) WHERE d.path LIKE '" + domain.getPath() + "%'";
} else {
whereClause += " WHERE t.account_id IN (" + permittedAccountsStr + ")";
}
} else if (templateFilter == TemplateFilter.sharedexecutable && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
whereClause += " LEFT JOIN launch_permission lp ON t.id = lp.template_id WHERE" + " (t.account_id IN (" + permittedAccountsStr + ") OR" + " lp.account_id IN ("
+ permittedAccountsStr + "))";
} else {
whereClause += " INNER JOIN account a on (t.account_id = a.id) ";
}
} else if (templateFilter == TemplateFilter.executable && !permittedAccounts.isEmpty()) {
whereClause += " WHERE (t.public = 1 OR t.account_id IN (" + permittedAccountsStr + "))";
} else if (templateFilter == TemplateFilter.community) {
whereClause += " WHERE t.public = 1 AND t.featured = 0";
} else if (templateFilter == TemplateFilter.all && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {
whereClause += " WHERE ";
} else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
return templateZonePairList;
}
if (whereClause.equals("")) {
whereClause += " WHERE ";
} else if (!whereClause.equals(" WHERE ")) {
whereClause += " AND ";
}
sql += whereClause + getExtrasWhere(templateFilter, name, keyword, isIso, bootable, hyperType, zoneId, onlyReady, showDomr) + groupByClause + getOrderByLimit(pageSize, startIndex);
pstmt = txn.prepareStatement(sql);
rs = pstmt.executeQuery();
while (rs.next()) {
Pair<Long, Long> templateZonePair = new Pair<Long, Long>(rs.getLong(1), rs.getLong(2));
templateZonePairList.add(templateZonePair);
}
// for now, defaulting pageSize to a large val if null; may need to
// revisit post 2.2RC2
if (isIso && templateZonePairList.size() < (pageSize != null ? pageSize : 500) && templateFilter != TemplateFilter.community
&& !(templateFilter == TemplateFilter.self && !BaseCmd.isRootAdmin(caller.getType()))) { // evaluates
// to
// true
// If
// root
// admin
// and
// filter=self
List<VMTemplateVO> publicIsos = publicIsoSearch(bootable);
for (int i = 0; i < publicIsos.size(); i++) {
if (keyword != null && publicIsos.get(i).getName().contains(keyword)) {
templateZonePairList.add(new Pair<Long, Long>(publicIsos.get(i).getId(), null));
continue;
} else if (name != null && publicIsos.get(i).getName().contains(name)) {
templateZonePairList.add(new Pair<Long, Long>(publicIsos.get(i).getId(), null));
continue;
} else if (keyword == null && name == null) {
templateZonePairList.add(new Pair<Long, Long>(publicIsos.get(i).getId(), null));
}
}
}
} catch (Exception e) {
s_logger.warn("Error listing templates", e);
} finally {
try {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
txn.commit();
} catch (SQLException sqle) {
s_logger.warn("Error in cleaning up", sqle);
}
}
return templateZonePairList;
}
@Override
public Set<Pair<Long, Long>> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List<HypervisorType> hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr,List<Account> permittedAccounts, Account caller) {

View File

@ -18,7 +18,6 @@
package com.cloud.storage.download;
import java.util.List;
import java.util.Map;
import com.cloud.exception.StorageUnavailableException;
@ -46,7 +45,7 @@ public interface DownloadMonitor extends Manager{
/*When new host added, take a look at if there are templates needed to be downloaded for the same hypervisor as the host*/
void handleSysTemplateDownload(HostVO hostId);
void handleTemplateSync(long dcId);
void handleTemplateSync(Long dcId);
void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos);

View File

@ -41,6 +41,7 @@ import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
import com.cloud.agent.api.storage.ListTemplateAnswer;
import com.cloud.agent.api.storage.ListTemplateCommand;
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;
@ -55,15 +56,19 @@ import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.SwiftVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateSwiftVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.SwiftDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VMTemplateSwiftDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.template.TemplateConstants;
@ -99,6 +104,8 @@ public class DownloadMonitorImpl implements DownloadMonitor {
@Inject
VMTemplatePoolDao _vmTemplatePoolDao;
@Inject
VMTemplateSwiftDao _vmTemplateSwiftlDao;
@Inject
StoragePoolHostDao _poolHostDao;
@Inject
SecondaryStorageVmDao _secStorageVmDao;
@ -125,6 +132,8 @@ public class DownloadMonitorImpl implements DownloadMonitor {
private ClusterDao _clusterDao;
@Inject
private HostDao _hostDao;
@Inject
private SwiftDao _swiftDao;
private String _name;
private Boolean _sslCopy = new Boolean(false);
@ -480,10 +489,19 @@ public class DownloadMonitorImpl implements DownloadMonitor {
}
@Override
public void handleTemplateSync(long dcId) {
List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(dcId);
for ( HostVO ssHost : ssHosts ) {
handleTemplateSync(ssHost);
public void handleTemplateSync(Long dcId) {
if ( dcId != null ) {
List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(dcId);
for ( HostVO ssHost : ssHosts ) {
handleTemplateSync(ssHost);
}
}
Boolean swiftEnable = Boolean.getBoolean(_configDao.getValue(Config.SwiftEnable.key()));
if (swiftEnable) {
List<SwiftVO> swifts = _swiftDao.listAll();
for (SwiftVO swift : swifts) {
handleTemplateSync(swift);
}
}
}
@ -502,6 +520,53 @@ public class DownloadMonitorImpl implements DownloadMonitor {
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;
}
public void handleTemplateSync(SwiftVO swift) {
if (swift == null) {
s_logger.warn("Huh? swift is null");
return;
}
Map<String, TemplateInfo> templateInfos = listTemplate(swift);
if (templateInfos == null) {
return;
}
List<VMTemplateVO> allTemplates = _templateDao.listAll();
for (VMTemplateVO tmplt : allTemplates) {
String uniqueName = tmplt.getUniqueName();
VMTemplateSwiftVO tmpltSwift = _vmTemplateSwiftlDao.findBySwiftTemplate(swift.getId(), tmplt.getId());
if (templateInfos.containsKey(uniqueName)) {
TemplateInfo tmpltInfo = templateInfos.remove(uniqueName);
if (tmpltSwift != null) {
s_logger.info("Template Sync found " + uniqueName + " already in the template swift table");
continue;
} else {
tmpltSwift = new VMTemplateSwiftVO(swift.getId(), tmplt.getId(), new Date(), tmpltInfo.getSize(), tmpltInfo.getPhysicalSize());
_vmTemplateSwiftlDao.persist(tmpltSwift);
s_logger.info("Template Sync added " + uniqueName + " to the template swift table");
}
}
}
for (TemplateInfo tmpltInfo : templateInfos.values()) {
s_logger.warn("Template Sync found template " + tmpltInfo.getInstallPath() + " in Swift description, but not in template table, please");
}
}
@Override
public void handleTemplateSync(HostVO ssHost) {

View File

@ -296,9 +296,12 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
if( snapshots != null && !snapshots.isEmpty()) {
throw new CloudRuntimeException("Can not delete this secondary storage due to there are still snapshots on it ");
}
List<Long> list = _templateDao.listPrivateTemplatesByHost(hostId);
if( list != null && !list.isEmpty()) {
throw new CloudRuntimeException("Can not delete this secondary storage due to there are still private template on it ");
Boolean swiftEnable = Boolean.getBoolean(_configDao.getValue(Config.SwiftEnable.key()));
if (!swiftEnable) {
List<Long> list = _templateDao.listPrivateTemplatesByHost(hostId);
if (list != null && !list.isEmpty()) {
throw new CloudRuntimeException("Can not delete this secondary storage due to there are still private template on it ");
}
}
_vmTemplateHostDao.deleteByHost(hostId);
HostVO host = _hostDao.findById(hostId);