CLOUDSTACK-3950:Set cross-zone flag in registerTemplate/registerIso in

case of region-wide secondary is enabled.
This commit is contained in:
Min Chen 2013-08-20 14:13:06 -07:00
parent fe012f29e8
commit 3bd2bbf59d
5 changed files with 259 additions and 215 deletions

View File

@ -31,6 +31,8 @@ public interface ImageStoreDao extends GenericDao<ImageStoreVO, Long> {
List<ImageStoreVO> findByScope(ZoneScope scope); List<ImageStoreVO> findByScope(ZoneScope scope);
List<ImageStoreVO> findRegionImageStores();
List<ImageStoreVO> findImageCacheByScope(ZoneScope scope); List<ImageStoreVO> findImageCacheByScope(ZoneScope scope);
List<ImageStoreVO> listImageStores(); List<ImageStoreVO> listImageStores();

View File

@ -38,6 +38,7 @@ import com.cloud.utils.db.SearchCriteria;
public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implements ImageStoreDao { public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implements ImageStoreDao {
private SearchBuilder<ImageStoreVO> nameSearch; private SearchBuilder<ImageStoreVO> nameSearch;
private SearchBuilder<ImageStoreVO> providerSearch; private SearchBuilder<ImageStoreVO> providerSearch;
private SearchBuilder<ImageStoreVO> regionSearch;
@Override @Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@ -50,9 +51,14 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
providerSearch = createSearchBuilder(); providerSearch = createSearchBuilder();
providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ); providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
providerSearch.and("role", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ); providerSearch.and("role", providerSearch.entity().getRole(), SearchCriteria.Op.EQ);
providerSearch.done(); providerSearch.done();
regionSearch = createSearchBuilder();
regionSearch.and("scope", regionSearch.entity().getScope(), SearchCriteria.Op.EQ);
regionSearch.and("role", regionSearch.entity().getRole(), SearchCriteria.Op.EQ);
regionSearch.done();
return true; return true;
} }
@ -86,6 +92,14 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
return listBy(sc); return listBy(sc);
} }
@Override
public List<ImageStoreVO> findRegionImageStores() {
SearchCriteria<ImageStoreVO> sc = regionSearch.create();
sc.setParameters("scope", ScopeType.REGION);
sc.setParameters("role", DataStoreRole.Image);
return listBy(sc);
}
@Override @Override
public List<ImageStoreVO> findImageCacheByScope(ZoneScope scope) { public List<ImageStoreVO> findImageCacheByScope(ZoneScope scope) {
SearchCriteria<ImageStoreVO> sc = createSearchCriteria(); SearchCriteria<ImageStoreVO> sc = createSearchCriteria();

View File

@ -431,6 +431,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.framework.config.ConfigurationVO; import org.apache.cloudstack.framework.config.ConfigurationVO;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.utils.identity.ManagementServerNode; import org.apache.cloudstack.utils.identity.ManagementServerNode;
@ -675,6 +677,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
private List<StoragePoolAllocator> _storagePoolAllocators; private List<StoragePoolAllocator> _storagePoolAllocators;
@Inject @Inject
private ResourceTagDao _resourceTagDao; private ResourceTagDao _resourceTagDao;
@Inject
private ImageStoreDao _imgStoreDao;
@Inject @Inject
ProjectManager _projectMgr; ProjectManager _projectMgr;
@ -796,7 +800,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
for (String id : availableIds) { for (String id : availableIds) {
_availableIdsMap.put(id, true); _availableIdsMap.put(id, true);
} }
_executeInSequence = Boolean.parseBoolean(_configDao.getValue(Config.ExecuteInSequence.key())); _executeInSequence = Boolean.parseBoolean(_configDao.getValue(Config.ExecuteInSequence.key()));
return true; return true;
@ -3256,6 +3260,13 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
Integer apiLimitInterval = Integer.valueOf(_configDao.getValue(Config.ApiLimitInterval.key())); Integer apiLimitInterval = Integer.valueOf(_configDao.getValue(Config.ApiLimitInterval.key()));
Integer apiLimitMax = Integer.valueOf(_configDao.getValue(Config.ApiLimitMax.key())); Integer apiLimitMax = Integer.valueOf(_configDao.getValue(Config.ApiLimitMax.key()));
// check if region-wide secondary storage is used
boolean regionSecondaryEnabled = false;
List<ImageStoreVO> imgStores = _imgStoreDao.findRegionImageStores();
if ( imgStores != null && imgStores.size() > 0){
regionSecondaryEnabled = true;
}
capabilities.put("securityGroupsEnabled", securityGroupsEnabled); capabilities.put("securityGroupsEnabled", securityGroupsEnabled);
capabilities capabilities
.put("userPublicTemplateEnabled", (userPublicTemplateEnabled == null || userPublicTemplateEnabled.equals("false") ? false : true)); .put("userPublicTemplateEnabled", (userPublicTemplateEnabled == null || userPublicTemplateEnabled.equals("false") ? false : true));
@ -3264,6 +3275,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
capabilities.put("projectInviteRequired", _projectMgr.projectInviteRequired()); capabilities.put("projectInviteRequired", _projectMgr.projectInviteRequired());
capabilities.put("allowusercreateprojects", _projectMgr.allowUserToCreateProject()); capabilities.put("allowusercreateprojects", _projectMgr.allowUserToCreateProject());
capabilities.put("customDiskOffMaxSize", diskOffMaxSize); capabilities.put("customDiskOffMaxSize", diskOffMaxSize);
capabilities.put("regionSecondaryEnabled", regionSecondaryEnabled);
if (apiLimitEnabled) { if (apiLimitEnabled) {
capabilities.put("apiLimitInterval", apiLimitInterval); capabilities.put("apiLimitInterval", apiLimitInterval);
capabilities.put("apiLimitMax", apiLimitMax); capabilities.put("apiLimitMax", apiLimitMax);

View File

@ -21,6 +21,8 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
@ -28,13 +30,11 @@ import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd; import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDBUtils;
import com.cloud.configuration.Config; import com.cloud.configuration.Config;
import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.Resource.ResourceType;
@ -71,86 +71,86 @@ import com.cloud.vm.UserVmVO;
import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDao;
public abstract class TemplateAdapterBase extends AdapterBase implements TemplateAdapter { public abstract class TemplateAdapterBase extends AdapterBase implements TemplateAdapter {
private final static Logger s_logger = Logger.getLogger(TemplateAdapterBase.class); private final static Logger s_logger = Logger.getLogger(TemplateAdapterBase.class);
protected @Inject DomainDao _domainDao; protected @Inject DomainDao _domainDao;
protected @Inject AccountDao _accountDao; protected @Inject AccountDao _accountDao;
protected @Inject ConfigurationDao _configDao; protected @Inject ConfigurationDao _configDao;
protected @Inject UserDao _userDao; protected @Inject UserDao _userDao;
protected @Inject AccountManager _accountMgr; protected @Inject AccountManager _accountMgr;
protected @Inject DataCenterDao _dcDao; protected @Inject DataCenterDao _dcDao;
protected @Inject VMTemplateDao _tmpltDao; protected @Inject VMTemplateDao _tmpltDao;
protected @Inject TemplateDataStoreDao _tmpltStoreDao; protected @Inject TemplateDataStoreDao _tmpltStoreDao;
protected @Inject VMTemplateZoneDao _tmpltZoneDao; protected @Inject VMTemplateZoneDao _tmpltZoneDao;
protected @Inject UsageEventDao _usageEventDao; protected @Inject UsageEventDao _usageEventDao;
protected @Inject HostDao _hostDao; protected @Inject HostDao _hostDao;
protected @Inject UserVmDao _userVmDao; protected @Inject UserVmDao _userVmDao;
protected @Inject GuestOSHypervisorDao _osHyperDao; protected @Inject GuestOSHypervisorDao _osHyperDao;
protected @Inject ResourceLimitService _resourceLimitMgr; protected @Inject ResourceLimitService _resourceLimitMgr;
protected @Inject DataStoreManager storeMgr; protected @Inject ImageStoreDao _imgStoreDao;
@Inject TemplateManager templateMgr; @Inject TemplateManager templateMgr;
@Inject ConfigurationServer _configServer; @Inject ConfigurationServer _configServer;
@Inject ProjectManager _projectMgr; @Inject ProjectManager _projectMgr;
@Override
public boolean stop() {
return true;
}
private static boolean isAdmin(short accountType) { @Override
return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || public boolean stop() {
(accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || return true;
(accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || }
(accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
}
@Override private static boolean isAdmin(short accountType) {
return ((accountType == Account.ACCOUNT_TYPE_ADMIN) ||
(accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) ||
(accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) ||
(accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
}
@Override
public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
String accountName, Long domainId, String chksum, Boolean bootable, Map details) throws ResourceAllocationException { String accountName, Long domainId, String chksum, Boolean bootable, Map details) throws ResourceAllocationException {
return prepare(isIso, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, guestOSId, zoneId, hypervisorType, return prepare(isIso, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, guestOSId, zoneId, hypervisorType,
chksum, bootable, null, null, details, false, null, false, TemplateType.USER); chksum, bootable, null, null, details, false, null, false, TemplateType.USER);
} }
@Override @Override
public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled, String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled,
String imageStoreUuid, Boolean isDynamicallyScalable, TemplateType templateType) throws ResourceAllocationException { String imageStoreUuid, Boolean isDynamicallyScalable, TemplateType templateType) throws ResourceAllocationException {
//Long accountId = null; //Long accountId = null;
// parameters verification // parameters verification
if (isPublic == null) { if (isPublic == null) {
isPublic = Boolean.FALSE; isPublic = Boolean.FALSE;
} }
if (zoneId.longValue() == -1) { if (zoneId.longValue() == -1) {
zoneId = null; zoneId = null;
} }
if (isIso) { if (isIso) {
if (bootable == null) { if (bootable == null) {
bootable = Boolean.TRUE; bootable = Boolean.TRUE;
} }
GuestOS noneGuestOs = ApiDBUtils.findGuestOSByDisplayName(ApiConstants.ISO_GUEST_OS_NONE); GuestOS noneGuestOs = ApiDBUtils.findGuestOSByDisplayName(ApiConstants.ISO_GUEST_OS_NONE);
if ((guestOSId == null || guestOSId == noneGuestOs.getId()) && bootable == true){ if ((guestOSId == null || guestOSId == noneGuestOs.getId()) && bootable == true){
throw new InvalidParameterValueException("Please pass a valid GuestOS Id"); throw new InvalidParameterValueException("Please pass a valid GuestOS Id");
} }
if (bootable == false){ if (bootable == false){
guestOSId = noneGuestOs.getId(); //Guest os id of None. guestOSId = noneGuestOs.getId(); //Guest os id of None.
} }
} else { } else {
if (bits == null) { if (bits == null) {
bits = Integer.valueOf(64); bits = Integer.valueOf(64);
} }
if (passwordEnabled == null) { if (passwordEnabled == null) {
passwordEnabled = false; passwordEnabled = false;
} }
if (requiresHVM == null) { if (requiresHVM == null) {
requiresHVM = true; requiresHVM = true;
} }
} }
if (isExtractable == null) { if (isExtractable == null) {
isExtractable = Boolean.FALSE; isExtractable = Boolean.FALSE;
@ -159,30 +159,30 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
sshkeyEnabled = Boolean.FALSE; sshkeyEnabled = Boolean.FALSE;
} }
boolean isAdmin = _accountDao.findById(templateOwner.getId()).getType() == Account.ACCOUNT_TYPE_ADMIN; boolean isAdmin = _accountDao.findById(templateOwner.getId()).getType() == Account.ACCOUNT_TYPE_ADMIN;
if (!isAdmin && zoneId == null) { if (!isAdmin && zoneId == null) {
throw new InvalidParameterValueException("Please specify a valid zone Id."); throw new InvalidParameterValueException("Please specify a valid zone Id.");
} }
if (url.toLowerCase().contains("file://")) { if (url.toLowerCase().contains("file://")) {
throw new InvalidParameterValueException("File:// type urls are currently unsupported"); throw new InvalidParameterValueException("File:// type urls are currently unsupported");
} }
// check whether owner can create public templates // check whether owner can create public templates
boolean allowPublicUserTemplates = Boolean.parseBoolean(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), Config.ConfigurationParameterScope.account.toString(), templateOwner.getId())); boolean allowPublicUserTemplates = Boolean.parseBoolean(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), Config.ConfigurationParameterScope.account.toString(), templateOwner.getId()));
if (!isAdmin && !allowPublicUserTemplates && isPublic) { if (!isAdmin && !allowPublicUserTemplates && isPublic) {
throw new InvalidParameterValueException("Only private templates/ISO can be created."); throw new InvalidParameterValueException("Only private templates/ISO can be created.");
} }
if (!isAdmin || featured == null) { if (!isAdmin || featured == null) {
featured = Boolean.FALSE; featured = Boolean.FALSE;
} }
ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase()); ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
if (imgfmt == null) { if (imgfmt == null) {
throw new IllegalArgumentException("Image format is incorrect " + format + ". Supported formats are " + EnumUtils.listValues(ImageFormat.values())); throw new IllegalArgumentException("Image format is incorrect " + format + ". Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
} }
// Check that the resource limit for templates/ISOs won't be exceeded // Check that the resource limit for templates/ISOs won't be exceeded
UserVO user = _userDao.findById(userId); UserVO user = _userDao.findById(userId);
@ -193,19 +193,19 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
_resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template); _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
if (templateOwner.getType() != Account.ACCOUNT_TYPE_ADMIN && zoneId == null) { if (templateOwner.getType() != Account.ACCOUNT_TYPE_ADMIN && zoneId == null) {
throw new IllegalArgumentException("Only admins can create templates in all zones"); throw new IllegalArgumentException("Only admins can create templates in all zones");
} }
// If a zoneId is specified, make sure it is valid // If a zoneId is specified, make sure it is valid
if (zoneId != null) { if (zoneId != null) {
DataCenterVO zone = _dcDao.findById(zoneId); DataCenterVO zone = _dcDao.findById(zoneId);
if (zone == null) { if (zone == null) {
throw new IllegalArgumentException("Please specify a valid zone."); throw new IllegalArgumentException("Please specify a valid zone.");
} }
Account caller = CallContext.current().getCallingAccount(); Account caller = CallContext.current().getCallingAccount();
if(Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())){ if(Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())){
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: "+ zoneId ); throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: "+ zoneId );
} }
} }
List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates(); List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates();
@ -221,146 +221,162 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
featured, isExtractable, imgfmt, guestOSId, zoneId, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), featured, isExtractable, imgfmt, guestOSId, zoneId, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(),
templateOwner.getAccountId(), chksum, bootable, templateTag, details, sshkeyEnabled, null, isDynamicallyScalable, templateType); templateOwner.getAccountId(), chksum, bootable, templateTag, details, sshkeyEnabled, null, isDynamicallyScalable, templateType);
} }
@Override @Override
public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException { public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
//check if the caller can operate with the template owner //check if the caller can operate with the template owner
Account caller = CallContext.current().getCallingAccount(); Account caller = CallContext.current().getCallingAccount();
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
_accountMgr.checkAccess(caller, null, true, owner); _accountMgr.checkAccess(caller, null, true, owner);
boolean isRouting = (cmd.isRoutingType() == null) ? false : cmd.isRoutingType(); boolean isRouting = (cmd.isRoutingType() == null) ? false : cmd.isRoutingType();
return prepare(false, CallContext.current().getCallingUserId(), cmd.getTemplateName(), cmd.getDisplayText(), Long zoneId = cmd.getZoneId();
// ignore passed zoneId if we are using region wide image store
List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
if (stores != null && stores.size() > 0) {
zoneId = -1L;
}
return prepare(false, CallContext.current().getCallingUserId(), cmd.getTemplateName(), cmd.getDisplayText(),
cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(), cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(), cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(),
cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), cmd.getZoneId(), HypervisorType.getType(cmd.getHypervisor()), cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), zoneId, HypervisorType.getType(cmd.getHypervisor()),
cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), null, cmd.isDynamicallyScalable(), cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), null, cmd.isDynamicallyScalable(),
isRouting ? TemplateType.ROUTING : TemplateType.USER); isRouting ? TemplateType.ROUTING : TemplateType.USER);
} }
@Override @Override
public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException { public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
//check if the caller can operate with the template owner //check if the caller can operate with the template owner
Account caller = CallContext.current().getCallingAccount(); Account caller = CallContext.current().getCallingAccount();
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
_accountMgr.checkAccess(caller, null, true, owner); _accountMgr.checkAccess(caller, null, true, owner);
Long zoneId = cmd.getZoneId();
// ignore passed zoneId if we are using region wide image store
List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
if (stores != null && stores.size() > 0) {
zoneId = -1L;
}
return prepare(true, CallContext.current().getCallingUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, false, return prepare(true, CallContext.current().getCallingUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, false,
true, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(), true, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(),
cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false, cmd.getImageStoreUuid(), cmd.isDynamicallyScalable(), zoneId, HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false, cmd.getImageStoreUuid(), cmd.isDynamicallyScalable(),
TemplateType.USER); TemplateType.USER);
} }
protected VMTemplateVO persistTemplate(TemplateProfile profile) { protected VMTemplateVO persistTemplate(TemplateProfile profile) {
Long zoneId = profile.getZoneId(); Long zoneId = profile.getZoneId();
VMTemplateVO template = new VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), profile.getIsPublic(), VMTemplateVO template = new VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), profile.getIsPublic(),
profile.getFeatured(), profile.getIsExtractable(), profile.getTemplateType(), profile.getUrl(), profile.getRequiresHVM(), profile.getFeatured(), profile.getIsExtractable(), profile.getTemplateType(), profile.getUrl(), profile.getRequiresHVM(),
profile.getBits(), profile.getAccountId(), profile.getCheckSum(), profile.getDisplayText(), profile.getBits(), profile.getAccountId(), profile.getCheckSum(), profile.getDisplayText(),
profile.getPasswordEnabled(), profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), profile.getTemplateTag(), profile.getPasswordEnabled(), profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), profile.getTemplateTag(),
profile.getDetails(), profile.getSshKeyEnabled(), profile.IsDynamicallyScalable()); profile.getDetails(), profile.getSshKeyEnabled(), profile.IsDynamicallyScalable());
if (zoneId == null || zoneId.longValue() == -1) { if (zoneId == null || zoneId.longValue() == -1) {
List<DataCenterVO> dcs = _dcDao.listAll(); List<DataCenterVO> dcs = _dcDao.listAll();
if (dcs.isEmpty()) { if (dcs.isEmpty()) {
throw new CloudRuntimeException("No zones are present in the system, can't add template"); throw new CloudRuntimeException("No zones are present in the system, can't add template");
} }
template.setCrossZones(true); template.setCrossZones(true);
for (DataCenterVO dc: dcs) { for (DataCenterVO dc: dcs) {
_tmpltDao.addTemplateToZone(template, dc.getId()); _tmpltDao.addTemplateToZone(template, dc.getId());
} }
} else { } else {
_tmpltDao.addTemplateToZone(template, zoneId); _tmpltDao.addTemplateToZone(template, zoneId);
} }
return _tmpltDao.findById(template.getId()); return _tmpltDao.findById(template.getId());
} }
private Long accountAndUserValidation(Account account, long userId, UserVmVO vmInstanceCheck, VMTemplateVO template, String msg) private Long accountAndUserValidation(Account account, long userId, UserVmVO vmInstanceCheck, VMTemplateVO template, String msg)
throws PermissionDeniedException { throws PermissionDeniedException {
if (account != null) { if (account != null) {
if (!isAdmin(account.getType())) { if (!isAdmin(account.getType())) {
if ((vmInstanceCheck != null) && (account.getId() != vmInstanceCheck.getAccountId())) { if ((vmInstanceCheck != null) && (account.getId() != vmInstanceCheck.getAccountId())) {
throw new PermissionDeniedException(msg + ". Permission denied."); throw new PermissionDeniedException(msg + ". Permission denied.");
} }
if ((template != null) if ((template != null)
&& (!template.isPublicTemplate() && (account.getId() != template.getAccountId()) && (template.getTemplateType() != TemplateType.PERHOST))) { && (!template.isPublicTemplate() && (account.getId() != template.getAccountId()) && (template.getTemplateType() != TemplateType.PERHOST))) {
//special handling for the project case //special handling for the project case
Account owner = _accountMgr.getAccount(template.getAccountId()); Account owner = _accountMgr.getAccount(template.getAccountId());
if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) { if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
if (!_projectMgr.canAccessProjectAccount(account, owner.getId())) { if (!_projectMgr.canAccessProjectAccount(account, owner.getId())) {
throw new PermissionDeniedException(msg + ". Permission denied. The caller can't access project's template"); throw new PermissionDeniedException(msg + ". Permission denied. The caller can't access project's template");
} }
} else { } else {
throw new PermissionDeniedException(msg + ". Permission denied."); throw new PermissionDeniedException(msg + ". Permission denied.");
} }
} }
} else { } else {
if ((vmInstanceCheck != null) && !_domainDao.isChildDomain(account.getDomainId(), vmInstanceCheck.getDomainId())) { if ((vmInstanceCheck != null) && !_domainDao.isChildDomain(account.getDomainId(), vmInstanceCheck.getDomainId())) {
throw new PermissionDeniedException(msg + ". Permission denied."); throw new PermissionDeniedException(msg + ". Permission denied.");
} }
// FIXME: if template/ISO owner is null we probably need to // FIXME: if template/ISO owner is null we probably need to
// throw some kind of exception // throw some kind of exception
if (template != null) { if (template != null) {
Account templateOwner = _accountDao.findById(template.getAccountId()); Account templateOwner = _accountDao.findById(template.getAccountId());
if ((templateOwner != null) && !_domainDao.isChildDomain(account.getDomainId(), templateOwner.getDomainId())) { if ((templateOwner != null) && !_domainDao.isChildDomain(account.getDomainId(), templateOwner.getDomainId())) {
throw new PermissionDeniedException(msg + ". Permission denied."); throw new PermissionDeniedException(msg + ". Permission denied.");
} }
} }
} }
} }
return userId; return userId;
} }
@Override @Override
public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) { public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
Long templateId = cmd.getId(); Long templateId = cmd.getId();
Long userId = CallContext.current().getCallingUserId(); Long userId = CallContext.current().getCallingUserId();
Account account = CallContext.current().getCallingAccount(); Account account = CallContext.current().getCallingAccount();
Long zoneId = cmd.getZoneId(); Long zoneId = cmd.getZoneId();
VMTemplateVO template = _tmpltDao.findById(templateId.longValue()); VMTemplateVO template = _tmpltDao.findById(templateId.longValue());
if (template == null) { if (template == null) {
throw new InvalidParameterValueException("unable to find template with id " + templateId); throw new InvalidParameterValueException("unable to find template with id " + templateId);
} }
userId = accountAndUserValidation(account, userId, null, template, "Unable to delete template "); userId = accountAndUserValidation(account, userId, null, template, "Unable to delete template ");
UserVO user = _userDao.findById(userId); UserVO user = _userDao.findById(userId);
if (user == null) { if (user == null) {
throw new InvalidParameterValueException("Please specify a valid user."); throw new InvalidParameterValueException("Please specify a valid user.");
} }
if (template.getFormat() == ImageFormat.ISO) { if (template.getFormat() == ImageFormat.ISO) {
throw new InvalidParameterValueException("Please specify a valid template."); throw new InvalidParameterValueException("Please specify a valid template.");
} }
return new TemplateProfile(userId, template, zoneId); return new TemplateProfile(userId, template, zoneId);
} }
public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd cmd) { @Override
Long templateId = cmd.getId(); public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd cmd) {
Long userId = CallContext.current().getCallingUserId(); Long templateId = cmd.getId();
Long zoneId = cmd.getZoneId(); Long userId = CallContext.current().getCallingUserId();
Long zoneId = cmd.getZoneId();
VMTemplateVO template = _tmpltDao.findById(templateId.longValue()); VMTemplateVO template = _tmpltDao.findById(templateId.longValue());
if (template == null) { if (template == null) {
throw new InvalidParameterValueException("unable to find template with id " + templateId); throw new InvalidParameterValueException("unable to find template with id " + templateId);
} }
return new TemplateProfile(userId, template, zoneId); return new TemplateProfile(userId, template, zoneId);
} }
public TemplateProfile prepareDelete(DeleteIsoCmd cmd) { @Override
Long templateId = cmd.getId(); public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
Long templateId = cmd.getId();
Long userId = CallContext.current().getCallingUserId(); Long userId = CallContext.current().getCallingUserId();
Account account = CallContext.current().getCallingAccount(); Account account = CallContext.current().getCallingAccount();
Long zoneId = cmd.getZoneId(); Long zoneId = cmd.getZoneId();
@ -372,20 +388,20 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
userId = accountAndUserValidation(account, userId, null, template, "Unable to delete iso " ); userId = accountAndUserValidation(account, userId, null, template, "Unable to delete iso " );
UserVO user = _userDao.findById(userId); UserVO user = _userDao.findById(userId);
if (user == null) { if (user == null) {
throw new InvalidParameterValueException("Please specify a valid user."); throw new InvalidParameterValueException("Please specify a valid user.");
} }
if (template.getFormat() != ImageFormat.ISO) { if (template.getFormat() != ImageFormat.ISO) {
throw new InvalidParameterValueException("Please specify a valid iso."); throw new InvalidParameterValueException("Please specify a valid iso.");
} }
return new TemplateProfile(userId, template, zoneId); return new TemplateProfile(userId, template, zoneId);
} }
@Override @Override
abstract public VMTemplateVO create(TemplateProfile profile); abstract public VMTemplateVO create(TemplateProfile profile);
@Override @Override
abstract public boolean delete(TemplateProfile profile); abstract public boolean delete(TemplateProfile profile);
} }

View File

@ -123,7 +123,6 @@ import com.cloud.server.ConfigurationServer;
import com.cloud.storage.DataStoreRole; import com.cloud.storage.DataStoreRole;
import com.cloud.storage.GuestOSVO; import com.cloud.storage.GuestOSVO;
import com.cloud.storage.LaunchPermissionVO; import com.cloud.storage.LaunchPermissionVO;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO; import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
@ -397,7 +396,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
if (template == null) { if (template == null) {
throw new InvalidParameterValueException("unable to find template with id " + templateId); throw new InvalidParameterValueException("unable to find template with id " + templateId);
} }
return extract(caller, templateId, url, zoneId, mode, eventId, false); return extract(caller, templateId, url, zoneId, mode, eventId, false);
} }
@ -698,6 +697,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new InvalidParameterValueException("Unable to find template with id"); throw new InvalidParameterValueException("Unable to find template with id");
} }
if (template.isCrossZones()){
s_logger.debug("Template " + templateId + " is cross-zone, don't need to copy");
return template;
}
DataStore dstSecStore = getImageStore(destZoneId, templateId); DataStore dstSecStore = getImageStore(destZoneId, templateId);
if (dstSecStore != null) { if (dstSecStore != null) {
s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() + " in zone " + destZoneId s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() + " in zone " + destZoneId
@ -709,10 +713,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
if (srcSecStore == null) { if (srcSecStore == null) {
throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId); throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId);
} }
if (srcSecStore.getScope().getScopeType() == ScopeType.REGION) {
s_logger.debug("Template " + templateId + " is in region-wide secondary storage " + srcSecStore.getName() + " , don't need to copy");
return template;
}
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
@ -1266,7 +1266,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
} }
_tmpltDao.update(template.getId(), updatedTemplate); _tmpltDao.update(template.getId(), updatedTemplate);
//when operation is add/remove, accountNames can not be null //when operation is add/remove, accountNames can not be null
if (("add".equalsIgnoreCase(operation) || "remove".equalsIgnoreCase(operation)) && accountNames == null) { if (("add".equalsIgnoreCase(operation) || "remove".equalsIgnoreCase(operation)) && accountNames == null) {
throw new InvalidParameterValueException("Operation " + operation + " requires accounts or projectIds to be passed in"); throw new InvalidParameterValueException("Operation " + operation + " requires accounts or projectIds to be passed in");