You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/06/20 09:19:51 UTC
[18/50] [abbrv] Merge branch 'master' (up to commit
c30d9be3cea30339cfff40c1002906634291b373) into object_store.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/resource/ResourceManagerImpl.java
index 837fdfb,c6e8d7d..fe91cb3
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@@ -45,12 -45,6 +45,7 @@@ import org.apache.cloudstack.api.comman
import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd;
import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd;
- import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
- import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
- import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
- import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
- import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.region.dao.RegionDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
@@@ -208,59 -202,57 +202,61 @@@ public class ResourceManagerImpl extend
@Inject
protected ConfigurationDao _configDao;
@Inject
- protected HostTagsDao _hostTagsDao;
+ protected HostTagsDao _hostTagsDao;
@Inject
- protected GuestOSCategoryDao _guestOSCategoryDao;
+ protected GuestOSCategoryDao _guestOSCategoryDao;
@Inject
- protected PrimaryDataStoreDao _storagePoolDao;
+ protected PrimaryDataStoreDao _storagePoolDao;
@Inject
- protected DataCenterIpAddressDao _privateIPAddressDao;
+ protected DataCenterIpAddressDao _privateIPAddressDao;
@Inject
- protected IPAddressDao _publicIPAddressDao;
+ protected IPAddressDao _publicIPAddressDao;
@Inject
- protected VirtualMachineManager _vmMgr;
+ protected VirtualMachineManager _vmMgr;
@Inject
- protected VMInstanceDao _vmDao;
+ protected VMInstanceDao _vmDao;
@Inject
- protected HighAvailabilityManager _haMgr;
+ protected HighAvailabilityManager _haMgr;
@Inject
- protected StorageService _storageSvr;
+ protected StorageService _storageSvr;
@Inject
PlannerHostReservationDao _plannerHostReserveDao;
+ @Inject
+ protected DedicatedResourceDao _dedicatedDao;
protected List<? extends Discoverer> _discoverers;
+
public List<? extends Discoverer> getDiscoverers() {
- return _discoverers;
- }
- public void setDiscoverers(List<? extends Discoverer> _discoverers) {
- this._discoverers = _discoverers;
- }
+ return _discoverers;
+ }
+
+ public void setDiscoverers(List<? extends Discoverer> _discoverers) {
+ this._discoverers = _discoverers;
+ }
- @Inject
- protected ClusterManager _clusterMgr;
@Inject
- protected StoragePoolHostDao _storagePoolHostDao;
+ protected ClusterManager _clusterMgr;
+ @Inject
+ protected StoragePoolHostDao _storagePoolHostDao;
+
+ protected List<PodAllocator> _podAllocators;
- protected List<PodAllocator> _podAllocators;
public List<PodAllocator> getPodAllocators() {
- return _podAllocators;
- }
- public void setPodAllocators(List<PodAllocator> _podAllocators) {
- this._podAllocators = _podAllocators;
- }
+ return _podAllocators;
+ }
+
+ public void setPodAllocators(List<PodAllocator> _podAllocators) {
+ this._podAllocators = _podAllocators;
+ }
- @Inject
- protected VMTemplateDao _templateDao;
@Inject
- protected ConfigurationManager _configMgr;
+ protected VMTemplateDao _templateDao;
@Inject
- protected ClusterVSMMapDao _clusterVSMMapDao;
+ protected ConfigurationManager _configMgr;
+ @Inject
+ protected ClusterVSMMapDao _clusterVSMMapDao;
- protected long _nodeId = ManagementServerNode.getManagementServerId();
+ protected long _nodeId = ManagementServerNode.getManagementServerId();
protected HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
@@@ -391,10 -401,11 +388,10 @@@
}
Account account = UserContext.current().getCaller();
- if (Grouping.AllocationState.Disabled == zone.getAllocationState()
- && !_accountMgr.isRootAdmin(account.getType())) {
- PermissionDeniedException ex = new PermissionDeniedException(
- "Cannot perform this operation, Zone with specified id is currently disabled");
+ if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) {
+ PermissionDeniedException ex = new PermissionDeniedException(
+ "Cannot perform this operation, Zone with specified id is currently disabled");
- ex.addProxyObject(zone, dcId, "dcId");
+ ex.addProxyObject(zone.getUuid(), "dcId");
throw ex;
}
@@@ -421,15 -436,26 +419,22 @@@
}
if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) {
- throw new InvalidParameterValueException(
- "Please specify a hypervisor");
+ throw new InvalidParameterValueException("Please specify a hypervisor");
}
- Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType
- .getType(cmd.getHypervisor());
+ Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor());
if (hypervisorType == null) {
- s_logger.error("Unable to resolve " + cmd.getHypervisor()
- + " to a valid supported hypervisor type");
- throw new InvalidParameterValueException("Unable to resolve "
- + cmd.getHypervisor() + " to a supported ");
+ s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type");
+ throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported ");
}
+ if (zone.isSecurityGroupEnabled() && zone.getNetworkType().equals(NetworkType.Advanced)) {
+ if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer
+ && hypervisorType != HypervisorType.Simulator) {
+ throw new InvalidParameterValueException("Don't support hypervisor type " + hypervisorType + " in advanced security enabled zone");
+ }
+ }
+
Cluster.ClusterType clusterType = null;
if (cmd.getClusterType() != null && !cmd.getClusterType().isEmpty()) {
clusterType = Cluster.ClusterType.valueOf(cmd.getClusterType());
@@@ -473,11 -506,12 +478,11 @@@
cluster = _clusterDao.persist(cluster);
} catch (Exception e) {
// no longer tolerate exception during the cluster creation phase
- CloudRuntimeException ex = new CloudRuntimeException(
- "Unable to create cluster " + clusterName
- + " in pod and data center with specified ids", e);
+ CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName
+ + " in pod and data center with specified ids", e);
// Get the pod VO object's table name.
- ex.addProxyObject(pod, podId, "podId");
- ex.addProxyObject(zone, dcId, "dcId");
+ ex.addProxyObject(pod.getUuid(), "podId");
+ ex.addProxyObject(zone.getUuid(), "dcId");
throw ex;
}
clusterId = cluster.getId();
@@@ -600,9 -651,9 +606,9 @@@
if (cluster.getGuid() == null) {
List<HostVO> hosts = listAllHostsInCluster(clusterId);
if (!hosts.isEmpty()) {
- CloudRuntimeException ex = new CloudRuntimeException(
- "Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up");
+ CloudRuntimeException ex = new CloudRuntimeException(
+ "Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up");
- ex.addProxyObject(cluster, clusterId, "clusterId");
+ ex.addProxyObject(cluster.getUuid(), "clusterId");
throw ex;
}
}
@@@ -655,10 -705,11 +661,10 @@@
}
Account account = UserContext.current().getCaller();
- if (Grouping.AllocationState.Disabled == zone.getAllocationState()
- && !_accountMgr.isRootAdmin(account.getType())) {
- PermissionDeniedException ex = new PermissionDeniedException(
- "Cannot perform this operation, Zone with specified id is currently disabled");
+ if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) {
+ PermissionDeniedException ex = new PermissionDeniedException(
+ "Cannot perform this operation, Zone with specified id is currently disabled");
- ex.addProxyObject(zone, dcId, "dcId");
+ ex.addProxyObject(zone.getUuid(), "dcId");
throw ex;
}
@@@ -927,11 -1022,19 +939,16 @@@
}
// delete the op_host_capacity entry
- Object[] capacityTypes = { Capacity.CAPACITY_TYPE_CPU,
- Capacity.CAPACITY_TYPE_MEMORY };
- SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao
- .createSearchCriteria();
+ Object[] capacityTypes = { Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY };
+ SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
- hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN,
- capacityTypes);
+ hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
_capacityDao.remove(hostCapacitySC);
+ // remove from dedicated resources
+ DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
+ if (dr != null) {
+ _dedicatedDao.remove(dr.getId());
+ }
txn.commit();
return true;
}
@@@ -970,36 -1078,49 +987,41 @@@
List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
if (hosts.size() > 0) {
if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cluster: " + cmd.getId()
- + " still has hosts, can't remove");
+ s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
}
txn.rollback();
- throw new CloudRuntimeException("Cluster: " + cmd.getId()
- + " cannot be removed. Cluster still has hosts");
+ throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
}
- // don't allow to remove the cluster if it has non-removed storage
- // pools
- List<StoragePoolVO> storagePools = _storagePoolDao
- .listPoolsByCluster(cmd.getId());
+ // don't allow to remove the cluster if it has non-removed storage
+ // pools
+ List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
if (storagePools.size() > 0) {
if (s_logger.isDebugEnabled()) {
- s_logger.debug("Cluster: " + cmd.getId()
- + " still has storage pools, can't remove");
+ s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
}
txn.rollback();
- throw new CloudRuntimeException("Cluster: " + cmd.getId()
- + " cannot be removed. Cluster still has storage pools");
+ throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
}
- if (_clusterDao.remove(cmd.getId())) {
+ if (_clusterDao.remove(cmd.getId())) {
_capacityDao.removeBy(null, null, null, cluster.getId(), null);
- // If this cluster is of type vmware, and if the nexus vswitch
- // global parameter setting is turned
+ // If this cluster is of type vmware, and if the nexus vswitch
+ // global parameter setting is turned
// on, remove the row in cluster_vsm_map for this cluster id.
- if (hypervisorType == HypervisorType.VMware
- && Boolean.parseBoolean(_configDao
- .getValue(Config.VmwareUseNexusVSwitch
- .toString()))) {
- _clusterVSMMapDao.removeByClusterId(cmd.getId());
- }
+ if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
+ _clusterVSMMapDao.removeByClusterId(cmd.getId());
+ }
+ // remove from dedicated resources
+ DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
+ if (dr != null) {
+ _dedicatedDao.remove(dr.getId());
+ }
- }
+ }
- txn.commit();
+ txn.commit();
return true;
- } catch (CloudRuntimeException e) {
+ } catch (CloudRuntimeException e) {
throw e;
} catch (Throwable t) {
s_logger.error("Unable to delete cluster: " + cmd.getId(), t);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/server/ConfigurationServerImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/server/ManagementServerImpl.java
index 17444eb,96c72e4..5c2917f
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@@ -24,8 -29,11 +24,9 @@@ import java.util.Calendar
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
-import java.util.HashSet;
+ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/server/StatsCollector.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/server/StatsCollector.java
index 3feb10b,8d84c6c..e510435
--- a/server/src/com/cloud/server/StatsCollector.java
+++ b/server/src/com/cloud/server/StatsCollector.java
@@@ -67,14 -70,26 +73,21 @@@ import com.cloud.storage.VolumeStats
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.user.UserStatisticsVO;
-import com.cloud.user.UserStatsLogVO;
+ import com.cloud.user.VmDiskStatisticsVO;
+ import com.cloud.user.dao.VmDiskStatisticsDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ComponentMethodInterceptable;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
+ import com.cloud.utils.db.Filter;
+ import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.SearchCriteria;
+ import com.cloud.utils.db.Transaction;
+ import com.cloud.utils.net.MacAddress;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VmStats;
+ import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
/**
@@@ -94,13 -109,13 +107,15 @@@ public class StatsCollector extends Man
@Inject private UserVmDao _userVmDao;
@Inject private VolumeDao _volsDao;
@Inject private PrimaryDataStoreDao _storagePoolDao;
+ @Inject private ImageStoreDao _imageStoreDao;
@Inject private StorageManager _storageManager;
@Inject private StoragePoolHostDao _storagePoolHostDao;
- @Inject private SecondaryStorageVmManager _ssvmMgr;
+ @Inject private DataStoreManager _dataStoreMgr;
@Inject private ResourceManager _resourceMgr;
@Inject private ConfigurationDao _configDao;
+ @Inject private EndPointSelector _epSelector;
+ @Inject private VmDiskStatisticsDao _vmDiskStatsDao;
+ @Inject private ManagementServerHostDao _msHostDao;
private ConcurrentHashMap<Long, HostStats> _hostStats = new ConcurrentHashMap<Long, HostStats>();
private final ConcurrentHashMap<Long, VmStats> _VmStats = new ConcurrentHashMap<Long, VmStats>();
@@@ -112,6 -127,15 +127,15 @@@
long hostAndVmStatsInterval = -1L;
long storageStatsInterval = -1L;
long volumeStatsInterval = -1L;
+ int vmDiskStatsInterval = 0;
-
++
+ private ScheduledExecutorService _diskStatsUpdateExecutor;
+ private int _usageAggregationRange = 1440;
+ private String _usageTimeZone = "GMT";
+ private final long mgmtSrvrId = MacAddress.getMacAddress().toLong();
+ private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds
+ private static final int USAGE_AGGREGATION_RANGE_MIN = 10; // 10 minutes, same to com.cloud.usage.UsageManagerImpl.USAGE_AGGREGATION_RANGE_MIN
+ private boolean _dailyOrHourly = false;
//private final GlobalLock m_capacityCheckLock = GlobalLock.getInternLock("capacity.check");
@@@ -153,13 -178,62 +178,62 @@@
if (storageStatsInterval > 0) {
_executor.scheduleWithFixedDelay(new StorageCollector(), 15000L, storageStatsInterval, TimeUnit.MILLISECONDS);
}
-
+
+ if (vmDiskStatsInterval > 0) {
+ if (vmDiskStatsInterval < 300)
+ vmDiskStatsInterval = 300;
+ _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsInterval, vmDiskStatsInterval, TimeUnit.SECONDS);
+ }
-
++
// -1 means we don't even start this thread to pick up any data.
if (volumeStatsInterval > 0) {
_executor.scheduleWithFixedDelay(new VolumeCollector(), 15000L, volumeStatsInterval, TimeUnit.MILLISECONDS);
} else {
s_logger.info("Disabling volume stats collector");
}
-
++
+ //Schedule disk stats update task
+ _diskStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DiskStatsUpdater"));
+ String aggregationRange = configs.get("usage.stats.job.aggregation.range");
+ _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440);
+ _usageTimeZone = configs.get("usage.aggregation.timezone");
+ if(_usageTimeZone == null){
+ _usageTimeZone = "GMT";
+ }
+ TimeZone usageTimezone = TimeZone.getTimeZone(_usageTimeZone);
+ Calendar cal = Calendar.getInstance(usageTimezone);
+ cal.setTime(new Date());
+ long endDate = 0;
+ int HOURLY_TIME = 60;
+ final int DAILY_TIME = 60 * 24;
+ if (_usageAggregationRange == DAILY_TIME) {
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.roll(Calendar.DAY_OF_YEAR, true);
+ cal.add(Calendar.MILLISECOND, -1);
+ endDate = cal.getTime().getTime();
+ _dailyOrHourly = true;
+ } else if (_usageAggregationRange == HOURLY_TIME) {
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.roll(Calendar.HOUR_OF_DAY, true);
+ cal.add(Calendar.MILLISECOND, -1);
+ endDate = cal.getTime().getTime();
+ _dailyOrHourly = true;
+ } else {
+ endDate = cal.getTime().getTime();
+ _dailyOrHourly = false;
+ }
+ if (_usageAggregationRange < USAGE_AGGREGATION_RANGE_MIN) {
+ s_logger.warn("Usage stats job aggregation range is to small, using the minimum value of " + USAGE_AGGREGATION_RANGE_MIN);
+ _usageAggregationRange = USAGE_AGGREGATION_RANGE_MIN;
+ }
+ _diskStatsUpdateExecutor.scheduleAtFixedRate(new VmDiskStatsUpdaterTask(), (endDate - System.currentTimeMillis()),
+ (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS);
-
++
}
class HostCollector implements Runnable {
@@@ -254,7 -328,11 +328,11 @@@
statsInMemory.setNumCPUs(statsForCurrentIteration.getNumCPUs());
statsInMemory.setNetworkReadKBs(statsInMemory.getNetworkReadKBs() + statsForCurrentIteration.getNetworkReadKBs());
statsInMemory.setNetworkWriteKBs(statsInMemory.getNetworkWriteKBs() + statsForCurrentIteration.getNetworkWriteKBs());
+ statsInMemory.setDiskWriteKBs(statsInMemory.getDiskWriteKBs() + statsForCurrentIteration.getDiskWriteKBs());
+ statsInMemory.setDiskReadIOs(statsInMemory.getDiskReadIOs() + statsForCurrentIteration.getDiskReadIOs());
+ statsInMemory.setDiskWriteIOs(statsInMemory.getDiskWriteIOs() + statsForCurrentIteration.getDiskWriteIOs());
+ statsInMemory.setDiskReadKBs(statsInMemory.getDiskReadKBs() + statsForCurrentIteration.getDiskReadKBs());
-
+
_VmStats.put(vmId, statsInMemory);
}
}
@@@ -275,7 -353,176 +353,176 @@@
public VmStats getVmStats(long id) {
return _VmStats.get(id);
}
-
+
+ class VmDiskStatsUpdaterTask implements Runnable {
+ @Override
+ public void run() {
+ GlobalLock scanLock = GlobalLock.getInternLock("vm.disk.stats");
+ try {
+ if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+ //Check for ownership
+ //msHost in UP state with min id should run the job
+ ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
+ if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){
+ s_logger.debug("Skipping aggregate disk stats update");
+ scanLock.unlock();
+ return;
+ }
+ Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+ try {
+ txn.start();
+ //get all stats with delta > 0
+ List<VmDiskStatisticsVO> updatedVmNetStats = _vmDiskStatsDao.listUpdatedStats();
+ for(VmDiskStatisticsVO stat : updatedVmNetStats){
+ if (_dailyOrHourly) {
- //update agg bytes
++ //update agg bytes
+ stat.setAggBytesRead(stat.getCurrentBytesRead() + stat.getNetBytesRead());
+ stat.setAggBytesWrite(stat.getCurrentBytesWrite() + stat.getNetBytesWrite());
+ stat.setAggIORead(stat.getCurrentIORead() + stat.getNetIORead());
+ stat.setAggIOWrite(stat.getCurrentIOWrite() + stat.getNetIOWrite());
+ _vmDiskStatsDao.update(stat.getId(), stat);
+ }
+ }
+ s_logger.debug("Successfully updated aggregate vm disk stats");
+ txn.commit();
+ } catch (Exception e){
+ txn.rollback();
+ s_logger.debug("Failed to update aggregate disk stats", e);
+ } finally {
+ scanLock.unlock();
+ txn.close();
+ }
+ }
+ } catch (Exception e){
+ s_logger.debug("Exception while trying to acquire disk stats lock", e);
+ } finally {
+ scanLock.releaseRef();
+ }
+ }
+ }
-
++
+ class VmDiskStatsTask implements Runnable {
+ @Override
+ public void run() {
+ // collect the vm disk statistics(total) from hypervisor. added by weizhou, 2013.03.
+ Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+ try {
+ txn.start();
+ SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
+ sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
+ sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
+ sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Routing.toString());
+ List<HostVO> hosts = _hostDao.search(sc, null);
-
++
+ for (HostVO host : hosts) {
+ List<UserVmVO> vms = _userVmDao.listRunningByHostId(host.getId());
+ List<Long> vmIds = new ArrayList<Long>();
-
++
+ for (UserVmVO vm : vms) {
+ if (vm.getType() == VirtualMachine.Type.User) // user vm
+ vmIds.add(vm.getId());
+ }
-
++
+ HashMap<Long, List<VmDiskStatsEntry>> vmDiskStatsById = _userVmMgr.getVmDiskStatistics(host.getId(), host.getName(), vmIds);
+ if (vmDiskStatsById == null)
+ continue;
-
++
+ Set<Long> vmIdSet = vmDiskStatsById.keySet();
+ for(Long vmId : vmIdSet)
+ {
+ List<VmDiskStatsEntry> vmDiskStats = vmDiskStatsById.get(vmId);
+ if (vmDiskStats == null)
+ continue;
+ UserVmVO userVm = _userVmDao.findById(vmId);
+ for (VmDiskStatsEntry vmDiskStat:vmDiskStats) {
+ SearchCriteria<VolumeVO> sc_volume = _volsDao.createSearchCriteria();
+ sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath());
+ VolumeVO volume = _volsDao.search(sc_volume, null).get(0);
+ VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId());
+ VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId());
-
++
+ if ((vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0)
+ && (vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0)) {
+ s_logger.debug("IO/bytes read and write are all 0. Not updating vm_disk_statistics");
+ continue;
+ }
-
++
+ if (vmDiskStat_lock == null) {
+ s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and volumeId:" + volume.getId());
+ continue;
+ }
+
+ if (previousVmDiskStats != null
+ && ((previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead())
+ || (previousVmDiskStats.getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite())
+ || (previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead())
+ || (previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock.getCurrentIOWrite()))) {
+ s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " +
- "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
++ "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
+ " Read(Bytes): " + vmDiskStat.getBytesRead() + " write(Bytes): " + vmDiskStat.getBytesWrite() +
+ " Read(IO): " + vmDiskStat.getIORead() + " write(IO): " + vmDiskStat.getIOWrite());
+ continue;
+ }
+
+ if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Read # of bytes that's less than the last one. " +
+ "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
+ " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead());
+ }
+ vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
+ }
+ vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead());
+ if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Write # of bytes that's less than the last one. " +
+ "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
+ " Reported: " + vmDiskStat.getBytesWrite() + " Stored: " + vmDiskStat_lock.getCurrentBytesWrite());
+ }
+ vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
+ }
+ vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite());
+ if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Read # of IO that's less than the last one. " +
+ "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
+ " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead());
+ }
+ vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
+ }
+ vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead());
+ if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Write # of IO that's less than the last one. " +
+ "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
+ " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite());
+ }
+ vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
+ }
+ vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite());
-
++
+ if (! _dailyOrHourly) {
- //update agg bytes
++ //update agg bytes
+ vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
+ vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
+ vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
+ vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
+ }
+
+ _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock);
+ }
+ }
+ }
+ txn.commit();
+ } catch (Exception e) {
+ s_logger.warn("Error while collecting vm disk stats from hosts", e);
+ } finally {
+ txn.close();
+ }
-
++
+ }
+ }
+
class StorageCollector implements Runnable {
@Override
public void run() {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/StorageManagerImpl.java
index 1146179,d38b35e..687c4da
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@@ -662,11 -768,32 +662,30 @@@ public class StorageManagerImpl extend
}
if (scopeType == ScopeType.CLUSTER && clusterId == null) {
- throw new InvalidParameterValueException(
- "cluster id can't be null, if scope is cluster");
+ throw new InvalidParameterValueException("cluster id can't be null, if scope is cluster");
} else if (scopeType == ScopeType.ZONE && zoneId == null) {
- throw new InvalidParameterValueException(
- "zone id can't be null, if scope is zone");
+ throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
}
+ HypervisorType hypervisorType = HypervisorType.KVM;
+ if (scopeType == ScopeType.ZONE) {
+ String hypervisor = cmd.getHypervisor();
+ if (hypervisor != null) {
+ try {
+ hypervisorType = HypervisorType.getType(hypervisor);
+ } catch (Exception e) {
+ throw new InvalidParameterValueException("invalid hypervisor type" + hypervisor);
+ }
+ } else {
+ throw new InvalidParameterValueException(
+ "Missing parameter hypervisor. Hypervisor type is required to create zone wide primary storage.");
+ }
+ if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.VMware) {
+ throw new InvalidParameterValueException(
+ "zone wide storage pool is not suported for hypervisor type " + hypervisor);
+ }
+ }
+
Map ds = cmd.getDetails();
Map<String, String> details = new HashMap<String, String>();
if (ds != null) {
@@@ -1618,231 -1883,4 +1637,231 @@@
return null;
}
+ @Override
+ public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
+ String providerName = cmd.getProviderName();
+ DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
+
+ if (storeProvider == null) {
+ storeProvider = _dataStoreProviderMgr.getDefaultImageDataStoreProvider();
+ if (storeProvider == null) {
+ throw new InvalidParameterValueException("can't find image store provider: " + providerName);
+ }
+ providerName = storeProvider.getName(); // ignored passed provider name and use default image store provider name
+ }
+
+ Long dcId = cmd.getZoneId();
+ String url = cmd.getUrl();
+ Map details = cmd.getDetails();
+ ScopeType scopeType = ScopeType.ZONE;
+ if (dcId == null) {
+ scopeType = ScopeType.REGION;
+ }
+
+ // check if scope is supported by store provider
+ if (!((ImageStoreProvider) storeProvider).isScopeSupported(scopeType)) {
+ throw new InvalidParameterValueException("Image store provider " + providerName + " does not support scope " + scopeType);
+ }
+
+ // check if we have already image stores from other different providers,
+ // we currently are not supporting image stores from different
+ // providers co-existing
+ List<ImageStoreVO> imageStores = _imageStoreDao.listImageStores();
+ for (ImageStoreVO store : imageStores) {
+ if (!store.getProviderName().equalsIgnoreCase(providerName)) {
+ throw new InvalidParameterValueException("You can only add new image stores from the same provider " + store.getProviderName()
+ + " already added");
+ }
+ }
+
+ if (dcId != null) {
+ // Check if the zone exists in the system
+ DataCenterVO zone = _dcDao.findById(dcId);
+ if (zone == null) {
+ throw new InvalidParameterValueException("Can't find zone by id " + dcId);
+ }
+
+ Account account = UserContext.current().getCaller();
+ if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) {
+ PermissionDeniedException ex = new PermissionDeniedException(
+ "Cannot perform this operation, Zone with specified id is currently disabled");
- ex.addProxyObject(zone, dcId, "dcId");
++ ex.addProxyObject(zone.getUuid(), "dcId");
+ throw ex;
+ }
+ }
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("zoneId", dcId);
+ params.put("url", cmd.getUrl());
+ params.put("name", cmd.getName());
+ params.put("details", details);
+ params.put("scope", scopeType);
+ params.put("providerName", storeProvider.getName());
+ params.put("role", DataStoreRole.Image);
+
+ DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
+ DataStore store = null;
+ try {
+ store = lifeCycle.initialize(params);
+ } catch (Exception e) {
+ s_logger.debug("Failed to add data store", e);
+ throw new CloudRuntimeException("Failed to add data store", e);
+ }
+
+ if (((ImageStoreProvider) storeProvider).needDownloadSysTemplate()) {
+ // trigger system vm template download
+ this._imageSrv.downloadBootstrapSysTemplate(store);
+ }
+ else {
+ // populate template_store_ref table
+ this._imageSrv.addSystemVMTemplatesToSecondary(store);
+ }
+
+ // associate builtin template with zones associated with this image
+ // store
+ this.associateCrosszoneTemplatesToZone(dcId);
+
+ return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image);
+ }
+
+ private void associateCrosszoneTemplatesToZone(Long zoneId) {
+ VMTemplateZoneVO tmpltZone;
+
+ List<VMTemplateVO> allTemplates = _vmTemplateDao.listAll();
+ List<Long> dcIds = new ArrayList<Long>();
+ if (zoneId != null) {
+ dcIds.add(zoneId);
+ } else {
+ List<DataCenterVO> dcs = _dcDao.listAll();
+ if (dcs != null) {
+ for (DataCenterVO dc : dcs) {
+ dcIds.add(dc.getId());
+ }
+ }
+ }
+
+ for (VMTemplateVO vt : allTemplates) {
+ if (vt.isCrossZones()) {
+ for (Long dcId : dcIds) {
+ tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
+ if (tmpltZone == null) {
+ VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
+ _vmTemplateZoneDao.persist(vmTemplateZone);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean deleteImageStore(DeleteImageStoreCmd cmd) {
+ long storeId = cmd.getId();
+ User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId());
+ // Verify that image store exists
+ ImageStoreVO store = _imageStoreDao.findById(storeId);
+ if (store == null) {
+ throw new InvalidParameterValueException("Image store with id " + storeId + " doesn't exist");
+ }
+ _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.listByStoreId(storeId, DataStoreRole.Image);
+ if (snapshots != null && snapshots.size() > 0) {
+ throw new InvalidParameterValueException("Cannot delete image store with active snapshots backup!");
+ }
+ List<VolumeDataStoreVO> volumes = _volumeStoreDao.listByStoreId(storeId);
+ if (volumes != null && volumes.size() > 0) {
+ throw new InvalidParameterValueException("Cannot delete image store with active volumes backup!");
+ }
+
+ // search if there are user templates stored on this image store, excluding system, builtin templates
+ List<TemplateJoinVO> templates = this._templateViewDao.listActiveTemplates(storeId);
+ if (templates != null && templates.size() > 0) {
+ throw new InvalidParameterValueException("Cannot delete image store with active templates backup!");
+ }
+
+ // ready to delete
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ // first delete from image_store_details table, we need to do that since
+ // we are not actually deleting record from main
+ // image_data_store table, so delete cascade will not work
+ _imageStoreDetailsDao.deleteDetails(storeId);
+ _snapshotStoreDao.deletePrimaryRecordsForStore(storeId);
+ _volumeStoreDao.deletePrimaryRecordsForStore(storeId);
+ _templateStoreDao.deletePrimaryRecordsForStore(storeId);
+ _imageStoreDao.remove(storeId);
+ txn.commit();
+ return true;
+ }
+
+ @Override
+ public ImageStore createCacheStore(CreateCacheStoreCmd cmd) {
+ String providerName = cmd.getProviderName();
+ DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
+
+ if (storeProvider == null) {
+ storeProvider = _dataStoreProviderMgr.getDefaultCacheDataStoreProvider();
+ if (storeProvider == null) {
+ throw new InvalidParameterValueException("can't find cache store provider: " + providerName);
+ }
+ }
+
+ Long dcId = cmd.getZoneId();
+
+ ScopeType scopeType = null;
+ String scope = cmd.getScope();
+ if (scope != null) {
+ try {
+ scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase());
+
+ } catch (Exception e) {
+ throw new InvalidParameterValueException("invalid scope" + scope);
+ }
+
+ if (scopeType != ScopeType.ZONE) {
+ throw new InvalidParameterValueException("Only zone wide cache storage is supported");
+ }
+ }
+
+ if (scopeType == ScopeType.ZONE && dcId == null) {
+ throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
+ }
+
+ // Check if the zone exists in the system
+ DataCenterVO zone = _dcDao.findById(dcId);
+ if (zone == null) {
+ throw new InvalidParameterValueException("Can't find zone by id " + dcId);
+ }
+
+ Account account = UserContext.current().getCaller();
+ if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) {
+ PermissionDeniedException ex = new PermissionDeniedException(
+ "Cannot perform this operation, Zone with specified id is currently disabled");
- ex.addProxyObject(zone, dcId, "dcId");
++ ex.addProxyObject(zone.getUuid(), "dcId");
+ throw ex;
+ }
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("zoneId", dcId);
+ params.put("url", cmd.getUrl());
+ params.put("name", cmd.getUrl());
+ params.put("details", cmd.getDetails());
+ params.put("scope", scopeType);
+ params.put("providerName", storeProvider.getName());
+ params.put("role", DataStoreRole.ImageCache);
+
+ DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
+ DataStore store = null;
+ try {
+ store = lifeCycle.initialize(params);
+ } catch (Exception e) {
+ s_logger.debug("Failed to add data store", e);
+ throw new CloudRuntimeException("Failed to add data store", e);
+ }
+
+ return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/storage/VolumeManager.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/VolumeManager.java
index 5f533ca,47fbda8..ffa20d3
--- a/server/src/com/cloud/storage/VolumeManager.java
+++ b/server/src/com/cloud/storage/VolumeManager.java
@@@ -114,5 -106,7 +114,8 @@@ public interface VolumeManager extends
DiskOfferingVO offering, VMTemplateVO template, VMInstanceVO vm,
Account owner);
+
+ String getVmNameFromVolumeId(long volumeId);
+
+ String getStoragePoolOfVolume(long volumeId);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/storage/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/VolumeManagerImpl.java
index 5abd432,43f3681..eca8428
--- a/server/src/com/cloud/storage/VolumeManagerImpl.java
+++ b/server/src/com/cloud/storage/VolumeManagerImpl.java
@@@ -388,15 -368,15 +393,15 @@@ public class VolumeManagerImpl extends
String url = cmd.getUrl();
String format = cmd.getFormat();
String imageStoreUuid = cmd.getImageStoreUuid();
- DataStore store = this._tmpltMgr.getImageStore(imageStoreUuid, zoneId);
+ DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
validateVolume(caller, ownerId, zoneId, volumeName, url, format);
-
+
- VolumeVO volume = persistVolume(caller, ownerId, zoneId, volumeName,
+ VolumeVO volume = persistVolume(owner, zoneId, volumeName,
url, cmd.getFormat());
-
- VolumeInfo vol = this.volFactory.getVolume(volume.getId());
-
+
+ VolumeInfo vol = volFactory.getVolume(volume.getId());
+
RegisterVolumePayload payload = new RegisterVolumePayload(cmd.getUrl(), cmd.getChecksum(),
cmd.getFormat());
vol.addPayload(payload);
@@@ -719,17 -704,15 +724,15 @@@
public String getRandomVolumeName() {
return UUID.randomUUID().toString();
}
-
+
- private VolumeVO persistVolume(Account caller, long ownerId, Long zoneId,
+ private VolumeVO persistVolume(Account owner, Long zoneId,
String volumeName, String url, String format) {
Transaction txn = Transaction.currentTxn();
txn.start();
- VolumeVO volume = new VolumeVO(volumeName, zoneId, -1, -1, -1,
+ VolumeVO volume = new VolumeVO(volumeName, zoneId, -1L, -1L, -1,
new Long(-1), null, null, 0, Volume.Type.DATADISK);
- Account owner = (caller.getId() == ownerId) ? caller : _accountMgr
- .getActiveAccountById(ownerId);
volume.setPoolId(null);
volume.setDataCenterId(zoneId);
volume.setPodId(null);
@@@ -2547,187 -2619,16 +2560,198 @@@
}
-
-
@Override
+ public Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account) throws ResourceAllocationException {
+ VolumeInfo volume = volFactory.getVolume(volumeId);
+ if (volume == null) {
+ throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
+ }
+
+ if (volume.getState() != Volume.State.Ready) {
+ throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
+ }
+
+ CreateSnapshotPayload payload = new CreateSnapshotPayload();
+ payload.setSnapshotId(snapshotId);
+ payload.setSnapshotPolicyId(policyId);
+ payload.setAccount(account);
+ volume.addPayload(payload);
+ return volService.takeSnapshot(volume);
+ }
+
+ @Override
+ public Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException {
+ Account caller = UserContext.current().getCaller();
+
+ VolumeInfo volume = volFactory.getVolume(volumeId);
+ if (volume == null) {
+ throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
+ }
+ DataCenter zone = _dcDao.findById(volume.getDataCenterId());
+ if (zone == null) {
+ throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
+ }
+
+ if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
+ throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
+ }
+
+ if (volume.getState() != Volume.State.Ready) {
+ throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
+ }
+
+ if ( volume.getTemplateId() != null ) {
+ VMTemplateVO template = _templateDao.findById(volume.getTemplateId());
+ if( template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM ) {
+ throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
+ }
+ }
+
+ StoragePool storagePool = (StoragePool)volume.getDataStore();
+ if (storagePool == null) {
+ throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it");
+ }
+
+ return snapshotMgr.allocSnapshot(volumeId, policyId);
+ }
+
+
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true)
+ public String extractVolume(ExtractVolumeCmd cmd) {
+ Long volumeId = cmd.getId();
+ Long zoneId = cmd.getZoneId();
+ String mode = cmd.getMode();
+ Account account = UserContext.current().getCaller();
+
+ if (!_accountMgr.isRootAdmin(account.getType()) && ApiDBUtils.isExtractionDisabled()) {
+ throw new PermissionDeniedException("Extraction has been disabled by admin");
+ }
+
+ VolumeVO volume = _volumeDao.findById(volumeId);
+ if (volume == null) {
+ InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with specified volumeId");
- ex.addProxyObject(volume, volumeId, "volumeId");
++ ex.addProxyObject(volumeId.toString(), "volumeId");
+ throw ex;
+ }
+
+ // perform permission check
+ _accountMgr.checkAccess(account, null, true, volume);
+
+ if (_dcDao.findById(zoneId) == null) {
+ throw new InvalidParameterValueException("Please specify a valid zone.");
+ }
+ if (volume.getPoolId() == null) {
+ throw new InvalidParameterValueException("The volume doesnt belong to a storage pool so cant extract it");
+ }
+ // Extract activity only for detached volumes or for volumes whose
+ // instance is stopped
+ if (volume.getInstanceId() != null && ApiDBUtils.findVMInstanceById(volume.getInstanceId()).getState() != State.Stopped) {
+ s_logger.debug("Invalid state of the volume with ID: " + volumeId
+ + ". It should be either detached or the VM should be in stopped state.");
+ PermissionDeniedException ex = new PermissionDeniedException(
+ "Invalid state of the volume with specified ID. It should be either detached or the VM should be in stopped state.");
- ex.addProxyObject(volume, volumeId, "volumeId");
++ ex.addProxyObject(volume.getUuid(), "volumeId");
+ throw ex;
+ }
+
+ if (volume.getVolumeType() != Volume.Type.DATADISK) {
+ // Datadisk dont have any template dependence.
+
+ VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
+ if (template != null) { // For ISO based volumes template = null and
+ // we allow extraction of all ISO based
+ // volumes
+ boolean isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
+ if (!isExtractable && account != null && account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+ // Global admins are always allowed to extract
+ PermissionDeniedException ex = new PermissionDeniedException("The volume with specified volumeId is not allowed to be extracted");
- ex.addProxyObject(volume, volumeId, "volumeId");
++ ex.addProxyObject(volume.getUuid(), "volumeId");
+ throw ex;
+ }
+ }
+ }
+
+ Upload.Mode extractMode;
+ if (mode == null || (!mode.equals(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equals(Upload.Mode.HTTP_DOWNLOAD.toString()))) {
+ throw new InvalidParameterValueException("Please specify a valid extract Mode ");
+ } else {
+ extractMode = mode.equals(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD;
+ }
+
+ // Clean up code to remove all those previous uploadVO and uploadMonitor code. Previous code is trying to fake an async operation purely in
+ // db table with uploadVO and async_job entry, but internal implementation is actually synchronous.
+ StoragePool srcPool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
+ ImageStoreEntity secStore = (ImageStoreEntity) this.dataStoreMgr.getImageStore(zoneId);
+ String secondaryStorageURL = secStore.getUri();
+
+ String value = this._configDao.getValue(Config.CopyVolumeWait.toString());
+ int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
+ // Copy volume from primary to secondary storage
+ VolumeInfo srcVol = this.volFactory.getVolume(volume.getId());
+ AsyncCallFuture<VolumeApiResult> cvAnswer = this.volService.copyVolume(srcVol, secStore);
+ // Check if you got a valid answer.
+ VolumeApiResult cvResult = null;
+ try {
+ cvResult = cvAnswer.get();
+ } catch (InterruptedException e1) {
+ s_logger.debug("failed copy volume", e1);
+ throw new CloudRuntimeException("Failed to copy volume", e1);
+ } catch (ExecutionException e1) {
+ s_logger.debug("failed copy volume", e1);
+ throw new CloudRuntimeException("Failed to copy volume", e1);
+ }
+ if (cvResult == null || cvResult.isFailed()) {
+ String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage.";
+ throw new CloudRuntimeException(errorString);
+ }
+
+ VolumeInfo vol = cvResult.getVolume();
+ String volumeLocalPath = vol.getPath();
+ String volumeName = StringUtils.substringBeforeLast(StringUtils.substringAfterLast(volumeLocalPath, "/"), ".");
+ // volss, handle the ova special case;
+ if (getFormatForPool(srcPool) == "ova") {
+ // TODO: need to handle this for S3 as secondary storage
+ CreateVolumeOVACommand cvOVACmd = new CreateVolumeOVACommand(secondaryStorageURL, volumeLocalPath, volumeName, srcPool, copyvolumewait);
+ CreateVolumeOVAAnswer OVAanswer = null;
+
+ try {
+ cvOVACmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
+ // for extract volume, create the ova file here;
+ OVAanswer = (CreateVolumeOVAAnswer) storageMgr.sendToPool(srcPool, cvOVACmd);
+ } catch (StorageUnavailableException e) {
+ s_logger.debug("Storage unavailable");
+ }
+ }
+ return secStore.createEntityExtractUrl(vol.getPath(), vol.getFormat());
+ }
+
+ private String getFormatForPool(StoragePool pool) {
+ ClusterVO cluster = ApiDBUtils.findClusterById(pool.getClusterId());
+
+ if (cluster.getHypervisorType() == HypervisorType.XenServer) {
+ return "vhd";
+ } else if (cluster.getHypervisorType() == HypervisorType.KVM) {
+ return "qcow2";
+ } else if (cluster.getHypervisorType() == HypervisorType.VMware) {
+ return "ova";
+ } else if (cluster.getHypervisorType() == HypervisorType.Ovm) {
+ return "raw";
+ } else {
+ return null;
+ }
+ }
++
++ @Override
+ public String getVmNameFromVolumeId(long volumeId) {
+ Long instanceId;
+ VolumeVO volume = _volsDao.findById(volumeId);
+ return getVmNameOnVolume(volume);
+ }
+
+ @Override
+ public String getStoragePoolOfVolume(long volumeId) {
+ VolumeVO vol = _volsDao.findById(volumeId);
+ return dataStoreMgr.getPrimaryDataStore(vol.getPoolId()).getUuid();
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
index 586f770,c343286..954c7e9
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@@ -525,21 -537,29 +525,29 @@@ public class SecondaryStorageManagerImp
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-
+
+ NetworkVO defaultNetwork = null;
+ if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) {
+ List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId);
+ if (networks == null || networks.size() == 0) {
+ throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
+ }
+ defaultNetwork = networks.get(0);
+ } else {
- TrafficType defaultTrafficType = TrafficType.Public;
+ TrafficType defaultTrafficType = TrafficType.Public;
+
- if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) {
- defaultTrafficType = TrafficType.Guest;
- }
- List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
+ if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) {
+ defaultTrafficType = TrafficType.Guest;
+ }
-
+ List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
-
- //api should never allow this situation to happen
+ // api should never allow this situation to happen
- if (defaultNetworks.size() != 1) {
+ if (defaultNetworks.size() != 1) {
- throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+ throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type "
+ + defaultTrafficType + " when expect to find 1");
+ }
+ defaultNetwork = defaultNetworks.get(0);
}
- NetworkVO defaultNetwork = defaultNetworks.get(0);
-
List<? extends NetworkOffering> offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork, NetworkOfferingVO.SystemStorageNetwork);
List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>(offerings.size() + 1);
NicProfile defaultNic = new NicProfile();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index a7e6137,92d80ee..a1a4c90
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@@ -932,80 -1007,49 +932,84 @@@ public class SnapshotManagerImpl extend
throw new InvalidParameterValueException("Ovm won't support taking snapshot");
}
- // Verify permissions
- _accountMgr.checkAccess(caller, null, true, volume);
- Type snapshotType = getSnapshotType(policyId);
- Account owner = _accountMgr.getAccount(volume.getAccountId());
+ if (volume.getHypervisorType().equals(HypervisorType.KVM)) {
+ List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(cluster.getId());
+ if (hosts != null && !hosts.isEmpty()) {
+ HostVO host = hosts.get(0);
+ if (!hostSupportSnapsthot(host)) {
+ throw new CloudRuntimeException("KVM Snapshot is not supported on cluster: " + host.getId());
+ }
+ }
+ }
+
+ // if volume is attached to a vm in destroyed or expunging state; disallow
+ if (volume.getInstanceId() != null) {
+ UserVmVO userVm = _vmDao.findById(volume.getInstanceId());
+ if (userVm != null) {
- if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) {
- throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in "
- + userVm.getState().toString() + " state");
- }
++ if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) {
++ throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId()
++ + " is associated with vm:" + userVm.getInstanceName() + " is in "
++ + userVm.getState().toString() + " state");
++ }
- if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) {
- List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
- if(activeSnapshots.size() > 1)
- throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later");
- }
- try{
- _resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot);
- if (backup) {
- _resourceLimitMgr.checkResourceLimit(owner, ResourceType.secondary_storage, new Long(volume.getSize()));
- } else {
- _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, new Long(volume.getSize()));
++ if (userVm.getHypervisorType() == HypervisorType.VMware
++ || userVm.getHypervisorType() == HypervisorType.KVM) {
++ List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(),
++ Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
++ if (activeSnapshots.size() > 1)
++ throw new CloudRuntimeException(
++ "There is other active snapshot tasks on the instance to which the volume is attached, please try again later");
++ }
+
- List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(),
- VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging);
- if (activeVMSnapshots.size() > 0) {
- throw new CloudRuntimeException(
- "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later");
- }
++ List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(),
++ VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging);
++ if (activeVMSnapshots.size() > 0) {
++ throw new CloudRuntimeException(
++ "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later");
++ }
+ }
+ }
+
+ return true;
+ }
+ @Override
+ public SnapshotInfo takeSnapshot(VolumeInfo volume) throws ResourceAllocationException {
+ CreateSnapshotPayload payload = (CreateSnapshotPayload)volume.getpayload();
+ Long snapshotId = payload.getSnapshotId();
+ Account snapshotOwner = payload.getAccount();
+ SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotId, volume.getDataStore());
+ boolean processed = false;
+
+ try {
+ for (SnapshotStrategy strategy : snapshotStrategies) {
+ if (strategy.canHandle(snapshot)) {
+ processed = true;
+ snapshot = strategy.takeSnapshot(snapshot);
+ break;
+ }
}
- } catch (ResourceAllocationException e) {
- if (snapshotType != Type.MANUAL){
- String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots";
- s_logger.warn(msg);
- _alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg,
- "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit");
+ if (!processed) {
+ throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId);
}
- throw e;
- }
+ postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId());
- // Determine the name for this snapshot
- // Snapshot Name: VMInstancename + volumeName + timeString
- String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT);
+ UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(),
+ snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null,
+ volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
- String snapshotName = volume.getUuid() + "_" + timeString;
- // Create the Snapshot object and save it so we can return it to the
- // user
- HypervisorType hypervisorType = this._volsDao.getHypervisorType(volumeId);
- SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), null, snapshotName,
- (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType);
- SnapshotVO snapshot = _snapshotDao.persist(snapshotVO);
- if (snapshot == null) {
- throw new CloudRuntimeException("Failed to create snapshot for volume: "+volumeId);
- }
- if (backup) {
- _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage,
- new Long(volume.getSize()));
- } else {
- _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
- new Long(volume.getSize()));
+ _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
+
+ } catch(Exception e) {
+ s_logger.debug("Failed to create snapshot", e);
+ if (backup) {
+ _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage,
+ new Long(volume.getSize()));
+ } else {
+ _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.primary_storage,
+ new Long(volume.getSize()));
+ }
+ throw new CloudRuntimeException("Failed to create snapshot", e);
}
return snapshot;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/18aeef3e/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateManagerImpl.java
index c15bd6b,517d4ba..273614c
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@@ -1673,96 -2125,52 +1673,96 @@@ public class TemplateManagerImpl extend
}
@Override
- public List<HostVO> getSecondaryStorageHosts(long zoneId) {
- List<HostVO> hosts = _ssvmMgr
- .listSecondaryStorageHostsInOneZone(zoneId);
- if (hosts == null || hosts.size() == 0) {
- hosts = _ssvmMgr.listLocalSecondaryStorageHostsInOneZone(zoneId);
- if (hosts.isEmpty()) {
- return new ArrayList<HostVO>();
- }
- }
- return hosts;
+ public VMTemplateVO updateTemplate(UpdateIsoCmd cmd) {
+ return updateTemplateOrIso(cmd);
}
-
+
@Override
- public Long getTemplateSize(long templateId, long zoneId) {
- SearchCriteria<VMTemplateHostVO> sc = HostTemplateStatesSearch.create();
- sc.setParameters("id", templateId);
- sc.setParameters(
- "state",
- com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
- sc.setJoinParameters("host", "dcId", zoneId);
- List<VMTemplateSwiftVO> tsvs = _tmpltSwiftDao
- .listByTemplateId(templateId);
- Long size = null;
- if (tsvs != null && tsvs.size() > 0) {
- size = tsvs.get(0).getSize();
- }
-
- if (size == null && _s3Mgr.isS3Enabled()) {
- VMTemplateS3VO vmTemplateS3VO = _vmS3TemplateDao
- .findOneByTemplateId(templateId);
- if (vmTemplateS3VO != null) {
- size = vmTemplateS3VO.getSize();
+ public VMTemplateVO updateTemplate(UpdateTemplateCmd cmd) {
+ return updateTemplateOrIso(cmd);
+ }
+
+ private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) {
+ Long id = cmd.getId();
+ String name = cmd.getTemplateName();
+ String displayText = cmd.getDisplayText();
+ String format = cmd.getFormat();
+ Long guestOSId = cmd.getOsTypeId();
+ Boolean passwordEnabled = cmd.isPasswordEnabled();
+ Boolean bootable = cmd.isBootable();
+ Integer sortKey = cmd.getSortKey();
+ Account account = UserContext.current().getCaller();
+
+ // verify that template exists
+ VMTemplateVO template = _tmpltDao.findById(id);
+ if (template == null || template.getRemoved() != null) {
+ InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id");
- ex.addProxyObject(template, id, "templateId");
++ ex.addProxyObject(String.valueOf(id), "templateId");
+ throw ex;
+ }
+
+ // Don't allow to modify system template
+ if (id == Long.valueOf(1)) {
+ InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id");
- ex.addProxyObject(template, id, "templateId");
++ ex.addProxyObject(String.valueOf(id), "templateId");
+ throw ex;
+ }
+
+ // do a permission check
+ _accountMgr.checkAccess(account, AccessType.ModifyEntry, true, template);
+
+ boolean updateNeeded = !(name == null && displayText == null && format == null && guestOSId == null && passwordEnabled == null
+ && bootable == null && sortKey == null);
+ if (!updateNeeded) {
+ return template;
+ }
+
+ template = _tmpltDao.createForUpdate(id);
+
+ if (name != null) {
+ template.setName(name);
+ }
+
+ if (displayText != null) {
+ template.setDisplayText(displayText);
+ }
+
+ if (sortKey != null) {
+ template.setSortKey(sortKey);
+ }
+
+ ImageFormat imageFormat = null;
+ if (format != null) {
+ try {
+ imageFormat = ImageFormat.valueOf(format.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new InvalidParameterValueException("Image format: " + format + " is incorrect. Supported formats are "
+ + EnumUtils.listValues(ImageFormat.values()));
}
+
+ template.setFormat(imageFormat);
}
- if (size == null) {
- List<VMTemplateHostVO> sss = this.templateHostDao.search(sc, null);
- if (sss == null || sss.size() == 0) {
- throw new CloudRuntimeException("Template "
- + templateId
- + " has not been completely downloaded to zone "
- + zoneId);
+ if (guestOSId != null) {
+ GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
+
+ if (guestOS == null) {
+ throw new InvalidParameterValueException("Please specify a valid guest OS ID.");
+ } else {
+ template.setGuestOSId(guestOSId);
}
- size = sss.get(0).getSize();
}
- return size;
- }
+ if (passwordEnabled != null) {
+ template.setEnablePassword(passwordEnabled);
+ }
+
+ if (bootable != null) {
+ template.setBootable(bootable);
+ }
+
+ _tmpltDao.update(id, template);
+
+ return _tmpltDao.findById(id);
+ }
}