mirror of https://github.com/apache/cloudstack.git
bug 8714: support paraleel recursive snapshot
snapshot doesn't depend on volume any more, volume can be removed even there are snapshots on this volume status 8714: resolved fixed
This commit is contained in:
parent
913903cbe6
commit
1970161844
|
|
@ -26,7 +26,20 @@ public interface Snapshot {
|
|||
public enum Type {
|
||||
MANUAL,
|
||||
RECURRING,
|
||||
TEMPLATE;
|
||||
TEMPLATE,
|
||||
HOURLY,
|
||||
DAILY,
|
||||
WEEKLY,
|
||||
MONTHLY;
|
||||
private int max = 8;
|
||||
|
||||
public void setMax(int max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name();
|
||||
|
|
@ -52,7 +65,7 @@ public interface Snapshot {
|
|||
}
|
||||
}
|
||||
|
||||
public static final long MANUAL_POLICY_ID = 1L;
|
||||
public static final long MANUAL_POLICY_ID = 0L;
|
||||
|
||||
Long getId();
|
||||
long getAccountId();
|
||||
|
|
@ -60,7 +73,10 @@ public interface Snapshot {
|
|||
String getPath();
|
||||
String getName();
|
||||
Date getCreated();
|
||||
short getSnapshotType();
|
||||
Type getType();
|
||||
Status getStatus();
|
||||
HypervisorType getHypervisorType();
|
||||
boolean isRecursive();
|
||||
short getsnapshotType();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class DiskProfile {
|
|||
}
|
||||
|
||||
public DiskProfile(Volume vol, DiskOffering offering, HypervisorType hyperType) {
|
||||
this(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(), offering.getUseLocalStorage(), vol.getSize());
|
||||
this(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(), offering.isCustomized(), null);
|
||||
this.hyperType = hyperType;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import javax.persistence.Id;
|
|||
import javax.persistence.Table;
|
||||
|
||||
import com.cloud.storage.snapshot.SnapshotPolicy;
|
||||
import com.cloud.utils.DateUtil.IntervalType;
|
||||
|
||||
@Entity
|
||||
@Table(name="snapshot_policy")
|
||||
|
|
@ -56,11 +57,11 @@ public class SnapshotPolicyVO implements SnapshotPolicy {
|
|||
|
||||
public SnapshotPolicyVO() { }
|
||||
|
||||
public SnapshotPolicyVO(long volumeId, String schedule, String timezone, short interval, int maxSnaps) {
|
||||
public SnapshotPolicyVO(long volumeId, String schedule, String timezone, IntervalType intvType, int maxSnaps) {
|
||||
this.volumeId = volumeId;
|
||||
this.schedule = schedule;
|
||||
this.timezone = timezone;
|
||||
this.interval = interval;
|
||||
this.interval = (short)intvType.ordinal();
|
||||
this.maxSnaps = maxSnaps;
|
||||
this.active = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public class SnapshotScheduleVO implements SnapshotSchedule {
|
|||
return asyncJobId;
|
||||
}
|
||||
|
||||
public void setAsyncJobId(long asyncJobId) {
|
||||
public void setAsyncJobId(Long asyncJobId) {
|
||||
this.asyncJobId = asyncJobId;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
package com.cloud.storage;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
|
@ -29,7 +28,6 @@ import javax.persistence.GeneratedValue;
|
|||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.TableGenerator;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
|
@ -42,10 +40,16 @@ public class SnapshotVO implements Snapshot {
|
|||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
@Column(name="id")
|
||||
private long id = -1;
|
||||
private long id = -1;
|
||||
|
||||
@Column(name="data_center_id")
|
||||
long dataCenterId;
|
||||
|
||||
@Column(name="account_id")
|
||||
long accountId;
|
||||
long accountId;
|
||||
|
||||
@Column(name="domain_id")
|
||||
long domainId;
|
||||
|
||||
@Column(name="volume_id")
|
||||
Long volumeId;
|
||||
|
|
@ -67,8 +71,11 @@ public class SnapshotVO implements Snapshot {
|
|||
short snapshotType;
|
||||
|
||||
@Column(name="type_description")
|
||||
String typeDescription;
|
||||
|
||||
String typeDescription;
|
||||
|
||||
@Column(name="size")
|
||||
long size;
|
||||
|
||||
@Column(name=GenericDao.CREATED_COLUMN)
|
||||
Date created;
|
||||
|
||||
|
|
@ -87,13 +94,16 @@ public class SnapshotVO implements Snapshot {
|
|||
|
||||
public SnapshotVO() { }
|
||||
|
||||
public SnapshotVO(long accountId, Long volumeId, String path, String name, short snapshotType, String typeDescription, HypervisorType hypervisorType) {
|
||||
this.accountId = accountId;
|
||||
public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, String path, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType) {
|
||||
this.dataCenterId = dcId;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.volumeId = volumeId;
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.snapshotType = snapshotType;
|
||||
this.typeDescription = typeDescription;
|
||||
this.typeDescription = typeDescription;
|
||||
this.size = size;
|
||||
this.status = Status.Creating;
|
||||
this.prevSnapshotId = 0;
|
||||
this.hypervisorType = hypervisorType;
|
||||
|
|
@ -104,11 +114,19 @@ public class SnapshotVO implements Snapshot {
|
|||
return id;
|
||||
}
|
||||
|
||||
public long getDataCenterId() {
|
||||
return dataCenterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVolumeId() {
|
||||
return volumeId;
|
||||
|
|
@ -131,12 +149,19 @@ public class SnapshotVO implements Snapshot {
|
|||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getSnapshotType() {
|
||||
return snapshotType;
|
||||
@Override
|
||||
public short getsnapshotType() {
|
||||
return snapshotType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
if (snapshotType < 0 || snapshotType >= Type.values().length) {
|
||||
return null;
|
||||
}
|
||||
return Type.values()[snapshotType];
|
||||
}
|
||||
|
||||
@Override
|
||||
public HypervisorType getHypervisorType() {
|
||||
return hypervisorType;
|
||||
|
|
@ -144,8 +169,20 @@ public class SnapshotVO implements Snapshot {
|
|||
|
||||
public void setSnapshotType(short snapshotType) {
|
||||
this.snapshotType = snapshotType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecursive(){
|
||||
if ( snapshotType >= Type.DAILY.ordinal() && snapshotType <= Type.MONTHLY.ordinal() ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String getTypeDescription() {
|
||||
return typeDescription;
|
||||
}
|
||||
|
|
@ -185,25 +222,14 @@ public class SnapshotVO implements Snapshot {
|
|||
public void setPrevSnapshotId(long prevSnapshotId){
|
||||
this.prevSnapshotId = prevSnapshotId;
|
||||
}
|
||||
|
||||
public static Type getSnapshotType(Long policyId) {
|
||||
if (policyId.equals(MANUAL_POLICY_ID)) {
|
||||
return Type.MANUAL;
|
||||
} else {
|
||||
return Type.RECURRING;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Type getSnapshotType(String snapshotType) {
|
||||
if (Type.MANUAL.equals(snapshotType)) {
|
||||
return Type.MANUAL;
|
||||
}
|
||||
if (Type.RECURRING.equals(snapshotType)) {
|
||||
return Type.RECURRING;
|
||||
}
|
||||
if (Type.TEMPLATE.equals(snapshotType)) {
|
||||
return Type.TEMPLATE;
|
||||
for ( Type type : Type.values()) {
|
||||
if ( type.equals(snapshotType)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -428,54 +428,6 @@ public class VolumeVO implements Volume {
|
|||
this.updated = updated;
|
||||
}
|
||||
|
||||
public Lun getLun() {
|
||||
return new Lun(hostip, iscsiName);
|
||||
}
|
||||
|
||||
public class Lun {
|
||||
private final String ip;
|
||||
private String iqn;
|
||||
private String lun;
|
||||
|
||||
protected Lun(String ip, String iscsiName) {
|
||||
this.ip = ip;
|
||||
String[] str = iscsiName.split(":lu:");
|
||||
if (str != null && str.length == 2) {
|
||||
iqn = str[0];
|
||||
lun = str[1];
|
||||
} else {
|
||||
iqn = null;
|
||||
lun = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Lun(String ip, String iqn, String lun) {
|
||||
this.ip = ip;
|
||||
this.iqn = iqn;
|
||||
this.lun = lun;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public String getIqn() {
|
||||
return iqn;
|
||||
}
|
||||
|
||||
public String getLun() {
|
||||
return lun;
|
||||
}
|
||||
|
||||
public boolean isIscsi() {
|
||||
return lun != null;
|
||||
}
|
||||
|
||||
protected String getIscsiName() {
|
||||
return iqn + ":lu:" + lun;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("Vol[").append(id).append("|vm=").append(instanceId).append("|").append(volumeType).append("]").toString();
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public interface SnapshotSchedule {
|
|||
|
||||
Long getAsyncJobId();
|
||||
|
||||
void setAsyncJobId(long asyncJobId);
|
||||
void setAsyncJobId(Long asyncJobId);
|
||||
|
||||
Long getSnapshotId();
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import com.cloud.host.HostStats;
|
|||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.host.Status.Event;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
|
|
@ -226,4 +227,6 @@ public interface AgentManager extends Manager {
|
|||
|
||||
boolean isHostNativeHAEnabled(long hostId);
|
||||
|
||||
Answer sendTo(Long dcId, HypervisorType type, Command cmd);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ import com.cloud.exception.DiscoveryException;
|
|||
import com.cloud.exception.InsufficientServerCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
import com.cloud.exception.UnsupportedVersionException;
|
||||
import com.cloud.ha.HighAvailabilityManager;
|
||||
import com.cloud.ha.HighAvailabilityManager.WorkType;
|
||||
|
|
@ -138,9 +139,11 @@ import com.cloud.service.ServiceOfferingVO;
|
|||
import com.cloud.storage.GuestOSCategoryVO;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
|
|
@ -961,6 +964,30 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory,
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer sendTo(Long dcId, HypervisorType type, Command cmd) {
|
||||
List<ClusterVO> clusters = _clusterDao.listByDcHyType(dcId, type.toString());
|
||||
int retry = 0;
|
||||
for( ClusterVO cluster : clusters ) {
|
||||
List<HostVO> hosts = _hostDao.listBy(Host.Type.Routing, cluster.getId(), null, dcId);
|
||||
for ( HostVO host : hosts ) {
|
||||
retry++;
|
||||
if ( retry > _retry ) {
|
||||
return null;
|
||||
}
|
||||
Answer answer = null;
|
||||
try {
|
||||
answer = easySend( host.getId(), cmd);
|
||||
} catch (Exception e ) {
|
||||
}
|
||||
if ( answer != null ) {
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public boolean deleteHost(long hostId) {
|
||||
|
|
|
|||
|
|
@ -258,25 +258,8 @@ public class ApiDBUtils {
|
|||
}
|
||||
|
||||
public static String getSnapshotIntervalTypes(long snapshotId) {
|
||||
String intervalTypes = "";
|
||||
|
||||
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
|
||||
if (snapshot.getSnapshotType() == Snapshot.Type.MANUAL.ordinal()) {
|
||||
return "MANUAL";
|
||||
}
|
||||
|
||||
List<SnapshotPolicyVO> policies = _snapMgr.listPoliciesforVolume(snapshot.getVolumeId());
|
||||
for (SnapshotPolicyVO policy : policies) {
|
||||
if (!intervalTypes.isEmpty()) {
|
||||
intervalTypes += ",";
|
||||
}
|
||||
if (policy.getId() == Snapshot.MANUAL_POLICY_ID) {
|
||||
intervalTypes += "MANUAL";
|
||||
} else {
|
||||
intervalTypes += DateUtil.getIntervalType(policy.getInterval()).toString();
|
||||
}
|
||||
}
|
||||
return intervalTypes;
|
||||
return snapshot.getType().name();
|
||||
}
|
||||
|
||||
public static String getStoragePoolTags(long poolId) {
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
}
|
||||
|
||||
VolumeVO volume = findVolumeById(snapshot.getVolumeId());
|
||||
String snapshotTypeStr = Type.values()[snapshot.getSnapshotType()].name();
|
||||
String snapshotTypeStr = snapshot.getType().name();
|
||||
snapshotResponse.setSnapshotType(snapshotTypeStr);
|
||||
snapshotResponse.setVolumeId(snapshot.getVolumeId());
|
||||
if( volume != null ) {
|
||||
|
|
|
|||
|
|
@ -29,4 +29,5 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
|||
List<ClusterVO> listByHyTypeWithoutGuid(String hyType);
|
||||
List<ClusterVO> listByZoneId(long zoneId);
|
||||
List<HypervisorType> getAvailableHypervisorInZone(long zoneId);
|
||||
List<ClusterVO> listByDcHyType(long dcId, String hyType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
protected final SearchBuilder<ClusterVO> HyTypeWithoutGuidSearch;
|
||||
protected final SearchBuilder<ClusterVO> AvailHyperSearch;
|
||||
protected final SearchBuilder<ClusterVO> ZoneSearch;
|
||||
protected final SearchBuilder<ClusterVO> ZoneHyTypeSearch;
|
||||
protected ClusterDaoImpl() {
|
||||
super();
|
||||
|
||||
|
|
@ -43,6 +44,11 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
HyTypeWithoutGuidSearch.and("guid", HyTypeWithoutGuidSearch.entity().getGuid(), SearchCriteria.Op.NULL);
|
||||
HyTypeWithoutGuidSearch.done();
|
||||
|
||||
ZoneHyTypeSearch = createSearchBuilder();
|
||||
ZoneHyTypeSearch.and("hypervisorType", ZoneHyTypeSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
ZoneHyTypeSearch.and("dataCenterId", ZoneHyTypeSearch.entity().getPodId(), SearchCriteria.Op.EQ);
|
||||
ZoneHyTypeSearch.done();
|
||||
|
||||
PodSearch = createSearchBuilder();
|
||||
PodSearch.and("pod", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
|
||||
PodSearch.and("name", PodSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -90,6 +96,14 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClusterVO> listByDcHyType(long dcId, String hyType) {
|
||||
SearchCriteria<ClusterVO> sc = ZoneHyTypeSearch.create();
|
||||
sc.setParameters("dataCenterId", dcId);
|
||||
sc.setParameters("hypervisorType", hyType);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HypervisorType> getAvailableHypervisorInZone(long zoneId) {
|
||||
SearchCriteria<ClusterVO> sc = AvailHyperSearch.create();
|
||||
|
|
|
|||
|
|
@ -299,15 +299,17 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
@Override
|
||||
public List<HostVO> listBy(Host.Type type, Long clusterId, Long podId, long dcId) {
|
||||
SearchCriteria<HostVO> sc = TypePodDcStatusSearch.create();
|
||||
sc.setParameters("type", type.toString());
|
||||
if (podId != null) {
|
||||
sc.setParameters("pod", podId);
|
||||
SearchCriteria<HostVO> sc = TypePodDcStatusSearch.create();
|
||||
if ( type != null ) {
|
||||
sc.setParameters("type", type.toString());
|
||||
}
|
||||
if (clusterId != null) {
|
||||
sc.setParameters("cluster", clusterId);
|
||||
}
|
||||
sc.setParameters("dc", dcId);
|
||||
}
|
||||
if (podId != null ) {
|
||||
sc.setParameters("pod", podId);
|
||||
}
|
||||
sc.setParameters("dc", dcId);
|
||||
sc.setParameters("status", Status.Up.toString());
|
||||
|
||||
return listBy(sc);
|
||||
|
|
@ -333,7 +335,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
sc.setParameters("cluster", clusterId);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listBy(Host.Type type, long dcId) {
|
||||
|
|
|
|||
|
|
@ -184,10 +184,6 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
|||
createDiskOffering(DomainVO.ROOT_DOMAIN, "Large", "Large Disk, 100 GB", 100, null);
|
||||
//_configMgr.createDiskOffering(User.UID_SYSTEM, DomainVO.ROOT_DOMAIN, "Private", "Private Disk", 0, null);
|
||||
|
||||
//Add default manual snapshot policy
|
||||
SnapshotPolicyVO snapPolicy = new SnapshotPolicyVO(0L, "00", "GMT", (short)4, 0);
|
||||
_snapPolicyDao.persist(snapPolicy);
|
||||
|
||||
// Save the mount parent to the configuration table
|
||||
String mountParent = getMountParent();
|
||||
if (mountParent != null) {
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
}
|
||||
|
||||
@DB
|
||||
protected Pair<VolumeVO, String> createVolumeFromSnapshot(VolumeVO volume, SnapshotVO snapshot, long virtualsize) {
|
||||
protected Pair<VolumeVO, String> createVolumeFromSnapshot(VolumeVO volume, SnapshotVO snapshot) {
|
||||
VolumeVO createdVolume = null;
|
||||
Long volumeId = volume.getId();
|
||||
|
||||
|
|
@ -466,7 +466,6 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
s_logger.warn("Unable to create volume on pool " + pool.getName() + ", reason: " + details);
|
||||
}
|
||||
|
||||
|
|
@ -515,18 +514,20 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
// By default, assume failure.
|
||||
VolumeVO createdVolume = null;
|
||||
SnapshotVO snapshot = _snapshotDao.findById(snapshotId); // Precondition: snapshot is not null and not removed.
|
||||
Long origVolumeId = snapshot.getVolumeId();
|
||||
VolumeVO originalVolume = _volsDao.findById(origVolumeId); // NOTE: Original volume could be destroyed and removed.
|
||||
|
||||
Pair<VolumeVO, String> volumeDetails = createVolumeFromSnapshot(volume, snapshot, originalVolume.getSize());
|
||||
Pair<VolumeVO, String> volumeDetails = createVolumeFromSnapshot(volume, snapshot);
|
||||
createdVolume = volumeDetails.first();
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
<<<<<<< Updated upstream
|
||||
// Create an event
|
||||
Long templateId = originalVolume.getTemplateId();
|
||||
;
|
||||
Long diskOfferingId = originalVolume.getDiskOfferingId();
|
||||
=======
|
||||
Long diskOfferingId = volume.getDiskOfferingId();
|
||||
>>>>>>> Stashed changes
|
||||
|
||||
if (createdVolume.getPath() != null) {
|
||||
Long offeringId = null;
|
||||
|
|
@ -537,9 +538,15 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
}
|
||||
}
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
// UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(),
|
||||
// volume.getId(), volume.getName(), offeringId, templateId, createdVolume.getSize());
|
||||
// _usageEventDao.persist(usageEvent);
|
||||
=======
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(),
|
||||
volume.getId(), volume.getName(), offeringId, null, createdVolume.getSize());
|
||||
_usageEventDao.persist(usageEvent);
|
||||
>>>>>>> Stashed changes
|
||||
}
|
||||
txn.commit();
|
||||
return createdVolume;
|
||||
|
|
@ -809,17 +816,15 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
Long vmId = volume.getInstanceId();
|
||||
if (vmId != null) {
|
||||
UserVm vm = _userVmDao.findById(vmId);
|
||||
|
||||
if (vm == null) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!vm.getState().equals(State.Stopped)) {
|
||||
return false;
|
||||
State state = vm.getState();
|
||||
if (state.equals(State.Stopped) || state.equals(State.Destroyed) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1449,17 +1454,28 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
}
|
||||
} else {
|
||||
Long snapshotId = cmd.getSnapshotId();
|
||||
<<<<<<< Updated upstream
|
||||
Snapshot snapshotCheck = _snapshotDao.findById(snapshotId);
|
||||
|
||||
=======
|
||||
SnapshotVO snapshotCheck = _snapshotDao.findById(snapshotId);
|
||||
diskOfferingId = cmd.getDiskOfferingId();
|
||||
>>>>>>> Stashed changes
|
||||
if (snapshotCheck == null) {
|
||||
throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId);
|
||||
}
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
VolumeVO vol = _volsDao.findByIdIncludingRemoved(snapshotCheck.getVolumeId());
|
||||
zoneId = vol.getDataCenterId();
|
||||
size = vol.getSize(); //we maintain size from org vol ; disk offering is used for tags purposes
|
||||
diskOfferingId = vol.getDiskOfferingId();
|
||||
|
||||
=======
|
||||
zoneId = snapshotCheck.getDataCenterId();
|
||||
size = snapshotCheck.getSize(); //we maintain size from org vol ; disk offering is used for tags purposes
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
if (account != null) {
|
||||
if (isAdmin(account.getType())) {
|
||||
Account snapshotOwner = _accountDao.findById(snapshotCheck.getAccountId());
|
||||
|
|
@ -1531,7 +1547,6 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
|
|||
if (cmd.getSnapshotId() != null) {
|
||||
return createVolumeFromSnapshot(volume, cmd.getSnapshotId());
|
||||
} else {
|
||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(cmd.getDiskOfferingId());
|
||||
_accountMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume);
|
||||
volume.setStatus(AsyncInstanceCreateStatus.Created);
|
||||
_volsDao.update(volume.getId(), volume);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package com.cloud.storage.dao;
|
|||
import java.util.List;
|
||||
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.Snapshot.Type;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ public interface SnapshotDao extends GenericDao<SnapshotVO, Long> {
|
|||
List<SnapshotVO> listByVolumeId(Filter filter, long volumeId);
|
||||
SnapshotVO findNextSnapshot(long parentSnapId);
|
||||
long getLastSnapshot(long volumeId, long snapId);
|
||||
List<SnapshotVO> listByVolumeIdType(long volumeId, String type);
|
||||
List<SnapshotVO> listByVolumeIdType(long volumeId, Type type);
|
||||
List<SnapshotVO> listByVolumeIdIncludingRemoved(long volumeId);
|
||||
List<SnapshotVO> listByBackupUuid(long volumeId, String backupUuid);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import javax.ejb.Local;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.Snapshot.Type;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
|
|
@ -58,7 +59,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<SnapshotVO> listByVolumeIdType(long volumeId, String type ) {
|
||||
public List<SnapshotVO> listByVolumeIdType(long volumeId, Type type ) {
|
||||
return listByVolumeIdType(null, volumeId, type);
|
||||
}
|
||||
|
||||
|
|
@ -81,10 +82,10 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
|||
return listIncludingRemovedBy(sc, null);
|
||||
}
|
||||
|
||||
public List<SnapshotVO> listByVolumeIdType(Filter filter, long volumeId, String type ) {
|
||||
public List<SnapshotVO> listByVolumeIdType(Filter filter, long volumeId, Type type ) {
|
||||
SearchCriteria<SnapshotVO> sc = VolumeIdTypeSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters("type", type);
|
||||
sc.setParameters("type", type.ordinal());
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +96,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
|||
|
||||
VolumeIdTypeSearch = createSearchBuilder();
|
||||
VolumeIdTypeSearch.and("volumeId", VolumeIdTypeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeSearch.and("type", VolumeIdTypeSearch.entity().getTypeDescription(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeSearch.and("type", VolumeIdTypeSearch.entity().getsnapshotType(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeSearch.done();
|
||||
|
||||
ParentIdSearch = createSearchBuilder();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package com.cloud.storage.dao;
|
|||
import java.util.List;
|
||||
|
||||
import com.cloud.storage.SnapshotPolicyVO;
|
||||
import com.cloud.utils.DateUtil.IntervalType;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ import com.cloud.utils.db.GenericDao;
|
|||
public interface SnapshotPolicyDao extends GenericDao<SnapshotPolicyVO, Long> {
|
||||
List<SnapshotPolicyVO> listByVolumeId(long volumeId);
|
||||
List<SnapshotPolicyVO> listByVolumeId(long volumeId, Filter filter);
|
||||
SnapshotPolicyVO findOneByVolumeInterval(long volumeId, short interval);
|
||||
SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType);
|
||||
List<SnapshotPolicyVO> listActivePolicies();
|
||||
SnapshotPolicyVO findOneByVolume(long volumeId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
import javax.ejb.Local;
|
||||
|
||||
import com.cloud.storage.SnapshotPolicyVO;
|
||||
import com.cloud.utils.DateUtil.IntervalType;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
|
|
@ -36,11 +37,11 @@ public class SnapshotPolicyDaoImpl extends GenericDaoBase<SnapshotPolicyVO, Long
|
|||
private final SearchBuilder<SnapshotPolicyVO> ActivePolicySearch;
|
||||
|
||||
@Override
|
||||
public SnapshotPolicyVO findOneByVolumeInterval(long volumeId, short interval) {
|
||||
public SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType) {
|
||||
SearchCriteria<SnapshotPolicyVO> sc = VolumeIdIntervalSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters("interval", interval);
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
sc.setParameters("interval", intvType.ordinal());
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -39,4 +39,6 @@ public interface SnapshotScheduleDao extends GenericDao<SnapshotScheduleVO, Long
|
|||
|
||||
SnapshotScheduleVO findOneByVolume(long volumeId);
|
||||
|
||||
SnapshotScheduleVO findOneByVolumePolicy(long volumeId, long policyId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public class SnapshotScheduleDaoImpl extends GenericDaoBase<SnapshotScheduleVO,
|
|||
protected final SearchBuilder<SnapshotScheduleVO> executableSchedulesSearch;
|
||||
protected final SearchBuilder<SnapshotScheduleVO> coincidingSchedulesSearch;
|
||||
private final SearchBuilder<SnapshotScheduleVO> VolumeIdSearch;
|
||||
private final SearchBuilder<SnapshotScheduleVO> VolumeIdPolicyIdSearch;
|
||||
// DB constraint: For a given volume and policyId, there will only be one entry in this table.
|
||||
|
||||
|
||||
|
|
@ -57,6 +58,11 @@ public class SnapshotScheduleDaoImpl extends GenericDaoBase<SnapshotScheduleVO,
|
|||
VolumeIdSearch = createSearchBuilder();
|
||||
VolumeIdSearch.and("volumeId", VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdSearch.done();
|
||||
|
||||
VolumeIdPolicyIdSearch = createSearchBuilder();
|
||||
VolumeIdPolicyIdSearch.and("volumeId", VolumeIdPolicyIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdPolicyIdSearch.and("policyId", VolumeIdPolicyIdSearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdPolicyIdSearch.done();
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +86,15 @@ public class SnapshotScheduleDaoImpl extends GenericDaoBase<SnapshotScheduleVO,
|
|||
sc.setParameters("volumeId", volumeId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SnapshotScheduleVO findOneByVolumePolicy(long volumeId, long policyId) {
|
||||
SearchCriteria<SnapshotScheduleVO> sc = VolumeIdPolicyIdSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters("policyId", policyId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
@ -87,8 +102,6 @@ public class SnapshotScheduleDaoImpl extends GenericDaoBase<SnapshotScheduleVO,
|
|||
public List<SnapshotScheduleVO> getSchedulesToExecute(Date currentTimestamp) {
|
||||
SearchCriteria<SnapshotScheduleVO> sc = executableSchedulesSearch.create();
|
||||
sc.setParameters("scheduledTimestamp", currentTimestamp);
|
||||
// Don't return manual snapshots. They will be executed through another code path.
|
||||
sc.addAnd("policyId", SearchCriteria.Op.NEQ, 1L);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
public List<StoragePoolVO> listByDataCenterId(long datacenterId) {
|
||||
SearchCriteria<StoragePoolVO> sc = DatacenterSearch.create();
|
||||
sc.setParameters("datacenterId", datacenterId);
|
||||
return listIncludingRemovedBy(sc);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.cloud.exception.ConcurrentOperationException;
|
|||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
|
|
@ -55,4 +56,5 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long> {
|
|||
HypervisorType getHypervisorType(long volumeId);
|
||||
|
||||
List<VolumeVO> listVolumesToBeDestroyed();
|
||||
ImageFormat getImageFormat(Long volumeId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,12 @@ import javax.ejb.Local;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.async.AsyncInstanceCreateStatus;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Volume.VolumeType;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.utils.Pair;
|
||||
|
|
@ -264,6 +267,21 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageFormat getImageFormat(Long volumeId) {
|
||||
HypervisorType type = getHypervisorType(volumeId);
|
||||
if ( type.equals(HypervisorType.KVM)) {
|
||||
return ImageFormat.QCOW2;
|
||||
} else if ( type.equals(HypervisorType.XenServer)) {
|
||||
return ImageFormat.VHD;
|
||||
} else if ( type.equals(HypervisorType.VMware)) {
|
||||
return ImageFormat.OVA;
|
||||
} else {
|
||||
s_logger.warn("Do not support hypervisor " + type.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected VolumeDaoImpl() {
|
||||
AllFieldsSearch = createSearchBuilder();
|
||||
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import com.cloud.storage.SnapshotPolicyVO;
|
|||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.utils.db.Filter;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -35,7 +36,7 @@ public interface SnapshotManager {
|
|||
public static final int HOURLYMAX = 8;
|
||||
public static final int DAILYMAX = 8;
|
||||
public static final int WEEKLYMAX = 8;
|
||||
public static final int MONTHLYMAX = 8;
|
||||
public static final int MONTHLYMAX = 12;
|
||||
public static final int DELTAMAX = 16;
|
||||
|
||||
/**
|
||||
|
|
@ -101,8 +102,6 @@ public interface SnapshotManager {
|
|||
*/
|
||||
List<SnapshotVO> listSnapsforVolume(long volumeId);
|
||||
|
||||
SnapshotPolicyVO getPolicyForVolumeByInterval(long volumeId, short interval);
|
||||
|
||||
void deletePoliciesForVolume(Long volumeId);
|
||||
|
||||
/**
|
||||
|
|
@ -116,11 +115,9 @@ public interface SnapshotManager {
|
|||
|
||||
void validateSnapshot(Long userId, SnapshotVO snapshot);
|
||||
|
||||
ImageFormat getImageFormat(Long volumeId);
|
||||
|
||||
SnapshotPolicyVO getPolicyForVolume(long volumeId);
|
||||
|
||||
boolean destroySnapshotBackUp(long snapshotId, long policyId);
|
||||
boolean destroySnapshotBackUp(long snapshotId);
|
||||
|
||||
/**
|
||||
* Create a snapshot of a volume
|
||||
|
|
@ -128,4 +125,8 @@ public interface SnapshotManager {
|
|||
* @return the Snapshot that was created
|
||||
*/
|
||||
SnapshotVO createSnapshotOnPrimary(VolumeVO volume, Long polocyId, Long snapshotId) throws ResourceAllocationException;
|
||||
|
||||
List<SnapshotPolicyVO> listPoliciesforSnapshot(long snapshotId);
|
||||
|
||||
List<SnapshotVO> listSnapsforPolicy(long policyId, Filter filter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import java.util.TimeZone;
|
|||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.persistence.EntityExistsException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -74,11 +73,9 @@ import com.cloud.storage.Snapshot.Type;
|
|||
import com.cloud.storage.SnapshotPolicyVO;
|
||||
import com.cloud.storage.SnapshotScheduleVO;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
|
|
@ -86,9 +83,6 @@ import com.cloud.storage.dao.SnapshotDao;
|
|||
import com.cloud.storage.dao.SnapshotPolicyDao;
|
||||
import com.cloud.storage.dao.SnapshotScheduleDao;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplateHostDao;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
|
|
@ -133,9 +127,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
@Inject protected SnapshotPolicyDao _snapshotPolicyDao = null;
|
||||
@Inject protected SnapshotScheduleDao _snapshotScheduleDao;
|
||||
@Inject protected DetailsDao _detailsDao;
|
||||
@Inject protected VMTemplateDao _templateDao;
|
||||
@Inject protected VMTemplatePoolDao _templatePoolDao;
|
||||
@Inject protected VMTemplateHostDao _templateHostDao;
|
||||
@Inject protected DomainDao _domainDao;
|
||||
@Inject protected StorageManager _storageMgr;
|
||||
@Inject protected AgentManager _agentMgr;
|
||||
|
|
@ -188,19 +179,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
|
||||
return runSnap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageFormat getImageFormat(Long volumeId) {
|
||||
ImageFormat format = null;
|
||||
VolumeVO volume = _volsDao.findById(volumeId);
|
||||
Long templateId = volume.getTemplateId();
|
||||
if (templateId != null) {
|
||||
VMTemplateVO template = _templateDao.findById(templateId);
|
||||
format = template.getFormat();
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
|
||||
protected Answer sendToPool(Volume vol, Command cmd) {
|
||||
StoragePool pool = _storagePoolDao.findById(vol.getPoolId());
|
||||
VMInstanceVO vm = _vmDao.findById(vol.getInstanceId());
|
||||
|
|
@ -523,25 +502,18 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), volume.getDataCenterId(), snapshotId, snapshot.getName(), null, null, volume.getSize());
|
||||
_usageEventDao.persist(usageEvent);
|
||||
|
||||
if (snapshot.getSnapshotType() == Type.RECURRING.ordinal()) {
|
||||
if (snapshot.getType() == Type.RECURRING ) {
|
||||
_accountMgr.incrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// Just mark it as removed in the database. When the next snapshot it taken,
|
||||
// validate previous snapshot will fix the state.
|
||||
// It will
|
||||
// 1) Call backupSnapshotToSecondaryStorage and try again.
|
||||
// 2) Create the next Snapshot pretending this is a valid snapshot.
|
||||
// 3) backupSnapshotToSecondaryStorage of the next snapshot
|
||||
// will take care of cleaning up the state of this snapshot
|
||||
|
||||
if (snapshot.getSnapshotType() == Type.RECURRING.ordinal()) {
|
||||
if (snapshot.getType() == Type.MANUAL ) {
|
||||
_accountMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot);
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), 0L, snapshotId, snapshot.getName(), null, null, 0L);
|
||||
_usageEventDao.persist(usageEvent);
|
||||
}
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), 0L, snapshotId, snapshot.getName(), null, null, 0L);
|
||||
_usageEventDao.persist(usageEvent);
|
||||
_snapshotDao.remove(snapshotId);
|
||||
}
|
||||
txn.commit();
|
||||
|
|
@ -566,45 +538,42 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
@DB
|
||||
public void postCreateSnapshot(Long volumeId, Long snapshotId, Long policyId, boolean backedUp) {
|
||||
Long userId = getSnapshotUserId();
|
||||
SnapshotVO snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId);
|
||||
// Update the snapshot_policy_ref table with the created snapshot
|
||||
// Get the list of policies for this snapshot
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
if (backedUp) {
|
||||
// This is a manual create, so increment the count of snapshots for
|
||||
// this account
|
||||
if (policyId == Snapshot.MANUAL_POLICY_ID) {
|
||||
Snapshot snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId);
|
||||
if ( snapshot.getType() == Type.MANUAL) {
|
||||
_accountMgr.incrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
// Even if the current snapshot failed, we should schedule the next
|
||||
// recurring snapshot for this policy.
|
||||
if (policyId != Snapshot.MANUAL_POLICY_ID) {
|
||||
if ( snapshot.isRecursive()) {
|
||||
postCreateRecurringSnapshotForPolicy(userId, volumeId, snapshotId, policyId);
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
private void postCreateRecurringSnapshotForPolicy(long userId, long volumeId, long snapshotId, long policyId) {
|
||||
//Use count query
|
||||
List<SnapshotVO> snaps = listSnapsforVolumeType(volumeId, Type.RECURRING.name());
|
||||
SnapshotVO spstVO = _snapshotDao.findById(snapshotId);
|
||||
Type type = spstVO.getType();
|
||||
int maxSnaps = type.getMax();
|
||||
|
||||
List<SnapshotVO> snaps = listSnapsforVolumeType(volumeId, type);
|
||||
SnapshotPolicyVO policy = _snapshotPolicyDao.findById(policyId);
|
||||
|
||||
while(snaps.size() > policy.getMaxSnaps() && snaps.size() > 1) {
|
||||
//Delete the oldest snap ref in snap_policy_ref
|
||||
if ( policy != null && policy.getMaxSnaps() < maxSnaps ) {
|
||||
maxSnaps = policy.getMaxSnaps();
|
||||
}
|
||||
while(snaps.size() > maxSnaps && snaps.size() > 1) {
|
||||
SnapshotVO oldestSnapshot = snaps.get(0);
|
||||
long oldSnapId = oldestSnapshot.getId();
|
||||
s_logger.debug("Max snaps: "+ policy.getMaxSnaps() + " exceeded for snapshot policy with Id: " + policyId + ". Deleting oldest snapshot: " + oldSnapId);
|
||||
// Excess snapshot. delete it asynchronously
|
||||
//destroySnapshotAsync(userId, volumeId, oldSnapId, policyId);
|
||||
// create the event
|
||||
deleteSnapshotInternal(oldSnapId, policyId);
|
||||
deleteSnapshotInternal(oldSnapId);
|
||||
snaps.remove(oldestSnapshot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Long checkAccountPermissions(long targetAccountId, long targetDomainId, String targetDesc, long targetId) {
|
||||
|
|
@ -648,33 +617,18 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
}
|
||||
checkAccountPermissions(snapshotOwner.getId(), snapshotOwner.getDomainId(), "snapshot", snapshotId);
|
||||
|
||||
boolean status = true;
|
||||
if (Type.MANUAL.ordinal() == snapshotCheck.getSnapshotType()) {
|
||||
status = deleteSnapshotInternal(snapshotId, Snapshot.MANUAL_POLICY_ID);
|
||||
|
||||
if (!status) {
|
||||
s_logger.warn("Failed to delete snapshot");
|
||||
throw new CloudRuntimeException("Failed to delete snapshot:"+snapshotId);
|
||||
}
|
||||
} else {
|
||||
List<SnapshotPolicyVO> policies = listPoliciesforVolume(snapshotCheck.getVolumeId());
|
||||
|
||||
for (SnapshotPolicyVO policy : policies) {
|
||||
status = deleteSnapshotInternal(snapshotId, policy.getId());
|
||||
|
||||
if (!status) {
|
||||
s_logger.warn("Failed to delete snapshot");
|
||||
throw new CloudRuntimeException("Failed to delete snapshot:"+snapshotId);
|
||||
}
|
||||
}
|
||||
boolean status = deleteSnapshotInternal(snapshotId);
|
||||
if (!status) {
|
||||
s_logger.warn("Failed to delete snapshot");
|
||||
throw new CloudRuntimeException("Failed to delete snapshot:" + snapshotId);
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
private boolean deleteSnapshotInternal(Long snapshotId, Long policyId) {
|
||||
private boolean deleteSnapshotInternal(Long snapshotId) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId + " and policyId " + policyId);
|
||||
s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId );
|
||||
}
|
||||
SnapshotVO lastSnapshot = null;
|
||||
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
|
||||
|
|
@ -713,7 +667,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
lastSnapshot.setBackupSnapshotId(null);
|
||||
_snapshotDao.update(lastSnapshot.getId(), lastSnapshot);
|
||||
} else {
|
||||
if (destroySnapshotBackUp(lastId, policyId)) {
|
||||
if (destroySnapshotBackUp(lastId)) {
|
||||
|
||||
} else {
|
||||
s_logger.debug("Destroying snapshot backup failed " + lastSnapshot);
|
||||
|
|
@ -721,7 +675,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
}
|
||||
}
|
||||
}
|
||||
postDeleteSnapshot(lastId, policyId);
|
||||
postDeleteSnapshot(lastId);
|
||||
lastId = lastSnapshot.getPrevSnapshotId();
|
||||
if (lastId == 0) {
|
||||
break;
|
||||
|
|
@ -738,60 +692,58 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
}
|
||||
|
||||
@Override @DB
|
||||
public boolean destroySnapshotBackUp(long snapshotId, long policyId) {
|
||||
public boolean destroySnapshotBackUp(long snapshotId) {
|
||||
boolean success = false;
|
||||
String details = null;
|
||||
String details;
|
||||
SnapshotVO snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId);
|
||||
|
||||
VolumeVO volume = _volsDao.findByIdIncludingRemoved(snapshot.getVolumeId());
|
||||
if ( volume == null ) {
|
||||
throw new CloudRuntimeException("Destroying snapshot " + snapshotId + " backup failed due to unable to find volume " + snapshot.getVolumeId());
|
||||
if ( snapshot == null ) {
|
||||
throw new CloudRuntimeException("Destroying snapshot " + snapshotId + " backup failed due to unable to find snapshot ");
|
||||
}
|
||||
String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume);
|
||||
String secondaryStoragePoolUrl = _storageMgr.getSecondaryStorageURL(volume.getDataCenterId());
|
||||
Long dcId = volume.getDataCenterId();
|
||||
Long accountId = volume.getAccountId();
|
||||
Long volumeId = volume.getId();
|
||||
|
||||
String secondaryStoragePoolUrl = _storageMgr.getSecondaryStorageURL(snapshot.getDataCenterId());
|
||||
Long dcId = snapshot.getDataCenterId();
|
||||
Long accountId = snapshot.getAccountId();
|
||||
Long volumeId = snapshot.getVolumeId();
|
||||
HypervisorType hvType = snapshot.getHypervisorType();
|
||||
|
||||
String backupOfSnapshot = snapshot.getBackupSnapshotId();
|
||||
if ( backupOfSnapshot == null ) {
|
||||
return true;
|
||||
}
|
||||
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(primaryStoragePoolNameLabel,
|
||||
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(null,
|
||||
secondaryStoragePoolUrl, dcId, accountId, volumeId, backupOfSnapshot, snapshot.getName());
|
||||
|
||||
snapshot.setBackupSnapshotId(null);
|
||||
_snapshotDao.update(snapshotId, snapshot);
|
||||
details = "Failed to destroy snapshot id:" + snapshotId + " for volume: " + volume.getId();
|
||||
Answer answer = sendToPool(volume, cmd);
|
||||
|
||||
Answer answer = _agentMgr.sendTo(dcId, hvType, cmd);
|
||||
|
||||
if ((answer != null) && answer.getResult()) {
|
||||
|
||||
// This is not the last snapshot.
|
||||
success = true;
|
||||
details = "Successfully deleted snapshot " + snapshotId + " for volumeId: " + volumeId + " and policyId "
|
||||
+ policyId;
|
||||
details = "Successfully deleted snapshot " + snapshotId + " for volumeId: " + volumeId ;
|
||||
s_logger.debug(details);
|
||||
} else if (answer != null) {
|
||||
details = "Failed to destroy snapshot id:" + snapshotId + " for volume: " + volumeId + " due to ";
|
||||
if (answer.getDetails() != null) {
|
||||
details = answer.getDetails();
|
||||
details += answer.getDetails();
|
||||
}
|
||||
s_logger.error(details);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void postDeleteSnapshot(long snapshotId, long policyId) {
|
||||
protected void postDeleteSnapshot(long snapshotId) {
|
||||
// Remove the snapshot from the snapshots table and the snap_policy_ref table.
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
SnapshotVO snapshot = _snapshotDao.findByIdIncludingRemoved(snapshotId);
|
||||
// If this is a manual delete, decrement the count of snapshots for this account
|
||||
if (policyId == Snapshot.MANUAL_POLICY_ID) {
|
||||
if (snapshot.getType() == Type.MANUAL) {
|
||||
_accountMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot);
|
||||
}
|
||||
|
||||
|
|
@ -807,10 +759,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
// Verify parameters
|
||||
if(volumeId != null){
|
||||
VolumeVO volume = _volsDao.findById(volumeId);
|
||||
if (volume == null) {
|
||||
throw new InvalidParameterValueException("unable to find a volume with id " + volumeId);
|
||||
if (volume != null) {
|
||||
checkAccountPermissions(volume.getAccountId(), volume.getDomainId(), "volume", volumeId);
|
||||
}
|
||||
checkAccountPermissions(volume.getAccountId(), volume.getDomainId(), "volume", volumeId);
|
||||
|
||||
}
|
||||
|
||||
Account account = UserContext.current().getCaller();
|
||||
|
|
@ -855,8 +807,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
|
||||
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
|
||||
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
sb.and("snapshotTypeEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.EQ);
|
||||
sb.and("snapshotTypeNEQ", sb.entity().getSnapshotType(), SearchCriteria.Op.NEQ);
|
||||
sb.and("snapshotTypeEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.IN);
|
||||
sb.and("snapshotTypeNEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.NEQ);
|
||||
|
||||
if ((accountId == null) && (domainId != null)) {
|
||||
// if accountId isn't specified, we can do a domain match for the admin case
|
||||
|
|
@ -912,9 +864,17 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
if (snapshotType == null) {
|
||||
throw new InvalidParameterValueException("Unsupported snapshot type " + snapshotTypeStr);
|
||||
}
|
||||
sc.setParameters("snapshotTypeEQ", snapshotType.ordinal());
|
||||
if ( snapshotType == Type.RECURRING ) {
|
||||
sc.setParameters("snapshotTypeEQ", Type.HOURLY.ordinal(), Type.DAILY.ordinal(), Type.WEEKLY.ordinal(), Type.MONTHLY.ordinal() );
|
||||
} else {
|
||||
sc.setParameters("snapshotTypeEQ", snapshotType.ordinal());
|
||||
}
|
||||
} else if (intervalTypeStr != null && volumeId != null) {
|
||||
sc.setParameters("snapshotTypeEQ", Snapshot.Type.RECURRING.ordinal());
|
||||
Type type = SnapshotVO.getSnapshotType((String)intervalTypeStr);
|
||||
if ( type == null ) {
|
||||
throw new InvalidParameterValueException("Unsupported snapstho interval type " + intervalTypeStr);
|
||||
}
|
||||
sc.setParameters("snapshotTypeEQ", type.ordinal());
|
||||
} else {
|
||||
// Show only MANUAL and RECURRING snapshot types
|
||||
sc.setParameters("snapshotTypeNEQ", Snapshot.Type.TEMPLATE.ordinal());
|
||||
|
|
@ -973,7 +933,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
List<SnapshotVO> snapshots = listSnapsforVolume(volumeId);
|
||||
for (SnapshotVO snapshot: snapshots) {
|
||||
if(_snapshotDao.expunge(snapshot.getId())){
|
||||
_accountMgr.decrementResourceCount(accountId, ResourceType.snapshot);
|
||||
if ( snapshot.getType() == Type.MANUAL ) {
|
||||
_accountMgr.decrementResourceCount(accountId, ResourceType.snapshot);
|
||||
}
|
||||
|
||||
//Log event after successful deletion
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), volume.getDataCenterId(), snapshot.getId(), snapshot.getName(), null, null, volume.getSize());
|
||||
|
|
@ -1008,32 +970,32 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
throw new InvalidParameterValueException("Failed to create snapshot policy, snapshots of volumes attached to System or router VM are not allowed");
|
||||
}
|
||||
}
|
||||
IntervalType type = DateUtil.IntervalType.getIntervalType(cmd.getIntervalType());
|
||||
if (type == null) {
|
||||
IntervalType intvType = DateUtil.IntervalType.getIntervalType(cmd.getIntervalType());
|
||||
if (intvType == null) {
|
||||
throw new InvalidParameterValueException("Unsupported interval type " + cmd.getIntervalType());
|
||||
}
|
||||
Type type = getSnapshotType(intvType);
|
||||
|
||||
TimeZone timeZone = TimeZone.getTimeZone(cmd.getTimezone());
|
||||
String timezoneId = timeZone.getID();
|
||||
if (!timezoneId.equals(cmd.getTimezone())) {
|
||||
s_logger.warn("Using timezone: " + timezoneId + " for running this snapshot policy as an equivalent of " + cmd.getTimezone());
|
||||
}
|
||||
|
||||
try {
|
||||
DateUtil.getNextRunTime(type, cmd.getSchedule(), timezoneId, null);
|
||||
DateUtil.getNextRunTime(intvType, cmd.getSchedule(), timezoneId, null);
|
||||
} catch (Exception e){
|
||||
throw new InvalidParameterValueException("Invalid schedule: "+ cmd.getSchedule() +" for interval type: " + cmd.getIntervalType());
|
||||
}
|
||||
|
||||
if (cmd.getMaxSnaps() <=0) {
|
||||
throw new InvalidParameterValueException("maxSnaps should be greater than 0");
|
||||
}
|
||||
|
||||
int intervalMaxSnaps = type.getMax();
|
||||
if (cmd.getMaxSnaps() > intervalMaxSnaps) {
|
||||
throw new InvalidParameterValueException("maxSnaps exceeds limit: " + intervalMaxSnaps + " for interval type: " + cmd.getIntervalType());
|
||||
}
|
||||
|
||||
if (cmd.getMaxSnaps() <=0) {
|
||||
throw new InvalidParameterValueException("maxSnaps should be greater than 0");
|
||||
}
|
||||
|
||||
//Verify that max doesn't exceed domain and account snapshot limits
|
||||
long accountLimit = _accountMgr.findCorrectResourceLimit(owner, ResourceType.snapshot);
|
||||
long domainLimit = _accountMgr.findCorrectResourceLimit(domain, ResourceType.snapshot);
|
||||
|
|
@ -1042,17 +1004,17 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
throw new InvalidParameterValueException("Max number of snapshots shouldn't exceed the domain/account level snapshot limit");
|
||||
}
|
||||
|
||||
SnapshotPolicyVO policy = new SnapshotPolicyVO(volumeId, cmd.getSchedule(), timezoneId, (short)type.ordinal(), cmd.getMaxSnaps());
|
||||
// Create an event
|
||||
try{
|
||||
SnapshotPolicyVO policy = _snapshotPolicyDao.findOneByVolumeInterval(volumeId, intvType);
|
||||
if ( policy == null ) {
|
||||
policy = new SnapshotPolicyVO(volumeId, cmd.getSchedule(), timezoneId, intvType, cmd.getMaxSnaps());
|
||||
policy = _snapshotPolicyDao.persist(policy);
|
||||
} catch (EntityExistsException e ) {
|
||||
policy = _snapshotPolicyDao.findOneByVolume(volumeId);
|
||||
_snapSchedMgr.scheduleNextSnapshotJob(policy);
|
||||
} else {
|
||||
try {
|
||||
policy = _snapshotPolicyDao.acquireInLockTable(policy.getId());
|
||||
policy.setSchedule(cmd.getSchedule());
|
||||
policy.setTimezone(timezoneId);
|
||||
policy.setInterval((short)type.ordinal());
|
||||
policy.setInterval((short) type.ordinal());
|
||||
policy.setMaxSnaps(cmd.getMaxSnaps());
|
||||
policy.setActive(true);
|
||||
_snapshotPolicyDao.update(policy.getId(), policy);
|
||||
|
|
@ -1061,8 +1023,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
_snapshotPolicyDao.releaseFromLockTable(policy.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
_snapSchedMgr.scheduleNextSnapshotJob(policy);
|
||||
return policy;
|
||||
}
|
||||
|
||||
|
|
@ -1088,7 +1050,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
public List<SnapshotPolicyVO> listPoliciesforVolume(long volumeId) {
|
||||
return _snapshotPolicyDao.listByVolumeId(volumeId);
|
||||
}
|
||||
/*
|
||||
|
||||
@Override
|
||||
public List<SnapshotPolicyVO> listPoliciesforSnapshot(long snapshotId) {
|
||||
SearchCriteria<SnapshotPolicyVO> sc = PoliciesForSnapSearch.create();
|
||||
|
|
@ -1102,14 +1064,14 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
sc.setJoinParameters("policy", "policyId", policyId);
|
||||
return _snapshotDao.search(sc, filter);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@Override
|
||||
public List<SnapshotVO> listSnapsforVolume(long volumeId) {
|
||||
return _snapshotDao.listByVolumeId(volumeId);
|
||||
}
|
||||
|
||||
public List<SnapshotVO> listSnapsforVolumeType(long volumeId, String type) {
|
||||
public List<SnapshotVO> listSnapsforVolumeType(long volumeId, Type type) {
|
||||
return _snapshotDao.listByVolumeIdType(volumeId, type);
|
||||
}
|
||||
|
||||
|
|
@ -1170,16 +1132,35 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
return snapshotSchedules;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SnapshotPolicyVO getPolicyForVolumeByInterval(long volumeId, short interval) {
|
||||
return _snapshotPolicyDao.findOneByVolumeInterval(volumeId, interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SnapshotPolicyVO getPolicyForVolume(long volumeId) {
|
||||
return _snapshotPolicyDao.findOneByVolume(volumeId);
|
||||
}
|
||||
|
||||
|
||||
public Type getSnapshotType(Long policyId) {
|
||||
if (policyId.equals(Snapshot.MANUAL_POLICY_ID)) {
|
||||
return Type.MANUAL;
|
||||
} else {
|
||||
SnapshotPolicyVO spstPolicyVO = _snapshotPolicyDao.findById(policyId);
|
||||
IntervalType intvType = DateUtil.getIntervalType(spstPolicyVO.getInterval());
|
||||
return getSnapshotType(intvType);
|
||||
}
|
||||
}
|
||||
|
||||
public Type getSnapshotType(IntervalType intvType) {
|
||||
if (intvType.equals(IntervalType.HOURLY)) {
|
||||
return Type.HOURLY;
|
||||
} else if (intvType.equals(IntervalType.DAILY)) {
|
||||
return Type.DAILY;
|
||||
} else if (intvType.equals(IntervalType.WEEKLY)) {
|
||||
return Type.WEEKLY;
|
||||
} else if (intvType.equals(IntervalType.MONTHLY)) {
|
||||
return Type.MONTHLY;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SnapshotVO allocSnapshot(CreateSnapshotCmd cmd) {
|
||||
Long volumeId = cmd.getVolumeId();
|
||||
|
|
@ -1208,10 +1189,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
|
||||
// Create the Snapshot object and save it so we can return it to the
|
||||
// user
|
||||
Type snapshotType = SnapshotVO.getSnapshotType(policyId);
|
||||
Type snapshotType = getSnapshotType(policyId);
|
||||
HypervisorType hypervisorType = this._volsDao.getHypervisorType(volumeId);
|
||||
SnapshotVO snapshotVO = new SnapshotVO(volume.getAccountId(), volume.getId(), null, snapshotName,
|
||||
(short) snapshotType.ordinal(), snapshotType.name(), hypervisorType);
|
||||
SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), null, snapshotName,
|
||||
(short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType);
|
||||
return _snapshotDao.persist(snapshotVO);
|
||||
}
|
||||
|
||||
|
|
@ -1226,10 +1207,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
|
|||
throw new ConfigurationException("Unable to get the configuration dao.");
|
||||
}
|
||||
|
||||
DateUtil.IntervalType.HOURLY.setMax(NumbersUtil.parseInt(configDao.getValue("snapshot.max.hourly"), HOURLYMAX));
|
||||
DateUtil.IntervalType.DAILY.setMax(NumbersUtil.parseInt(configDao.getValue("snapshot.max.daily"), DAILYMAX));
|
||||
DateUtil.IntervalType.WEEKLY.setMax(NumbersUtil.parseInt(configDao.getValue("snapshot.max.weekly"), WEEKLYMAX));
|
||||
DateUtil.IntervalType.MONTHLY.setMax(NumbersUtil.parseInt(configDao.getValue("snapshot.max.monthly"), MONTHLYMAX));
|
||||
Type.HOURLY.setMax(NumbersUtil.parseInt(configDao.getValue("snapshot.max.hourly"), HOURLYMAX));
|
||||
Type.DAILY.setMax(NumbersUtil.parseInt(configDao.getValue("snapshot.max.daily"), DAILYMAX));
|
||||
Type.WEEKLY.setMax(NumbersUtil.parseInt(configDao.getValue("snapshot.max.weekly"), WEEKLYMAX));
|
||||
Type.MONTHLY.setMax(NumbersUtil.parseInt(configDao.getValue("snapshot.max.monthly"), MONTHLYMAX));
|
||||
_deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), DELTAMAX);
|
||||
_totalRetries = NumbersUtil.parseInt(configDao.getValue("total.retries"), 4);
|
||||
_pauseInterval = 2*NumbersUtil.parseInt(configDao.getValue("ping.interval"), 60);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import java.util.TimerTask;
|
|||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.persistence.EntityExistsException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -133,7 +132,7 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
|
|||
}
|
||||
} finally {
|
||||
scanLock.releaseRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkStatusOfCurrentlyExecutingSnapshots() {
|
||||
|
|
@ -182,7 +181,7 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
|
|||
// If the snapshot was taken successfully on primary, it will retry backing it up.
|
||||
// and cleanup the previous snapshot
|
||||
// Set the userId to that of system.
|
||||
_snapshotManager.validateSnapshot(1L, snapshot);
|
||||
//_snapshotManager.validateSnapshot(1L, snapshot);
|
||||
// In all cases, schedule the next snapshot job
|
||||
scheduleNextSnapshotJob(snapshotSchedule);
|
||||
}
|
||||
|
|
@ -222,6 +221,9 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
|
|||
// this volume is not attached
|
||||
continue;
|
||||
}
|
||||
if ( _snapshotPolicyDao.findById(policyId) == null ) {
|
||||
_snapshotScheduleDao.remove(snapshotToBeExecuted.getId());
|
||||
}
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
Date scheduledTimestamp = snapshotToBeExecuted.getScheduledTimestamp();
|
||||
displayTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, scheduledTimestamp);
|
||||
|
|
@ -270,38 +272,46 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
|
|||
}
|
||||
|
||||
private Date scheduleNextSnapshotJob(SnapshotScheduleVO snapshotSchedule) {
|
||||
Long policyId = snapshotSchedule.getPolicyId();
|
||||
Long expectedId = snapshotSchedule.getId();
|
||||
if (_snapshotScheduleDao.findById(expectedId) != null) {
|
||||
// We need to acquire a lock and delete it, then release the lock.
|
||||
// But I don't know how to.
|
||||
_snapshotScheduleDao.expunge(expectedId);
|
||||
if ( snapshotSchedule == null ) {
|
||||
return null;
|
||||
}
|
||||
Long policyId = snapshotSchedule.getPolicyId();
|
||||
if (policyId.longValue() == Snapshot.MANUAL_POLICY_ID) {
|
||||
// Don't need to schedule the next job for this.
|
||||
return null;
|
||||
}
|
||||
SnapshotPolicyVO snapshotPolicy = _snapshotPolicyDao.findById(policyId);
|
||||
if ( snapshotPolicy == null ) {
|
||||
_snapshotScheduleDao.expunge(snapshotSchedule.getId());
|
||||
}
|
||||
return scheduleNextSnapshotJob(snapshotPolicy);
|
||||
}
|
||||
|
||||
@Override @DB
|
||||
public Date scheduleNextSnapshotJob(SnapshotPolicyVO policyInstance) {
|
||||
long policyId = policyInstance.getId();
|
||||
Date nextSnapshotTimestamp = getNextScheduledTime(policyId, new Date());
|
||||
SnapshotScheduleVO snapshotScheduleVO = new SnapshotScheduleVO(policyInstance.getVolumeId(), policyId, nextSnapshotTimestamp);
|
||||
try{
|
||||
_snapshotScheduleDao.persist(snapshotScheduleVO);
|
||||
} catch (EntityExistsException e ) {
|
||||
snapshotScheduleVO = _snapshotScheduleDao.findOneByVolume(policyInstance.getVolumeId());
|
||||
try {
|
||||
snapshotScheduleVO = _snapshotScheduleDao.acquireInLockTable(snapshotScheduleVO.getId());
|
||||
snapshotScheduleVO.setPolicyId(policyId);
|
||||
snapshotScheduleVO.setScheduledTimestamp(nextSnapshotTimestamp);
|
||||
_snapshotScheduleDao.update(snapshotScheduleVO.getId(), snapshotScheduleVO);
|
||||
public Date scheduleNextSnapshotJob(SnapshotPolicyVO policy) {
|
||||
if ( policy == null) {
|
||||
return null;
|
||||
}
|
||||
long policyId = policy.getId();
|
||||
if ( policyId == Snapshot.MANUAL_POLICY_ID ) {
|
||||
return null;
|
||||
}
|
||||
Date nextSnapshotTimestamp = getNextScheduledTime(policyId, _currentTimestamp);
|
||||
SnapshotScheduleVO spstSchedVO = _snapshotScheduleDao.findOneByVolumePolicy(policy.getVolumeId(), policy.getId());
|
||||
if ( spstSchedVO == null ) {
|
||||
spstSchedVO = new SnapshotScheduleVO(policy.getVolumeId(), policyId, nextSnapshotTimestamp);
|
||||
_snapshotScheduleDao.persist(spstSchedVO);
|
||||
} else {
|
||||
try{
|
||||
spstSchedVO = _snapshotScheduleDao.acquireInLockTable(spstSchedVO.getId());
|
||||
spstSchedVO.setPolicyId(policyId);
|
||||
spstSchedVO.setScheduledTimestamp(nextSnapshotTimestamp);
|
||||
spstSchedVO.setAsyncJobId(null);
|
||||
spstSchedVO.setSnapshotId(null);
|
||||
_snapshotScheduleDao.update(spstSchedVO.getId(), spstSchedVO);
|
||||
} finally {
|
||||
if(snapshotScheduleVO != null ) {
|
||||
_snapshotScheduleDao.releaseFromLockTable(snapshotScheduleVO.getId());
|
||||
if(spstSchedVO != null ) {
|
||||
_snapshotScheduleDao.releaseFromLockTable(spstSchedVO.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -316,7 +326,7 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
|
|||
SnapshotScheduleVO schedule = _snapshotScheduleDao.getCurrentSchedule(volumeId, policyId, false);
|
||||
boolean success = true;
|
||||
if (schedule != null) {
|
||||
success = _snapshotScheduleDao.expunge(schedule.getId());
|
||||
success = _snapshotScheduleDao.remove(schedule.getId());
|
||||
}
|
||||
if(!success){
|
||||
s_logger.debug("Error while deleting Snapshot schedule with Id: "+schedule.getId());
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package com.cloud.vm;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -133,7 +132,6 @@ import com.cloud.storage.Storage.StoragePoolType;
|
|||
import com.cloud.storage.Storage.StorageResourceType;
|
||||
import com.cloud.storage.Storage.TemplateType;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateHostVO;
|
||||
|
|
@ -1194,106 +1192,107 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
|
||||
if (user == null) {
|
||||
throw new InvalidParameterValueException("User " + userId + " does not exist");
|
||||
}
|
||||
|
||||
Long volumeId = cmd.getVolumeId();
|
||||
Long snapshotId = cmd.getSnapshotId();
|
||||
if (volumeId == null) {
|
||||
if (snapshotId == null) {
|
||||
throw new InvalidParameterValueException("Failed to create private template record, neither volume ID nor snapshot ID were specified.");
|
||||
}
|
||||
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
|
||||
if (snapshot == null) {
|
||||
throw new InvalidParameterValueException("Failed to create private template record, unable to find snapshot " + snapshotId);
|
||||
}
|
||||
volumeId = snapshot.getVolumeId();
|
||||
} else {
|
||||
if (snapshotId != null) {
|
||||
throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId + ") and snapshot ID (" + snapshotId + ")");
|
||||
}
|
||||
}
|
||||
|
||||
VolumeVO volume = _volsDao.findById(volumeId);
|
||||
if (volume == null) {
|
||||
throw new InvalidParameterValueException("Volume with ID: " + volumeId + " does not exist");
|
||||
}
|
||||
|
||||
if (!isAdmin) {
|
||||
if (account.getId() != volume.getAccountId()) {
|
||||
throw new PermissionDeniedException("Unable to create a template from volume with id " + volumeId + ", permission denied.");
|
||||
}
|
||||
} else if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), volume.getDomainId())) {
|
||||
throw new PermissionDeniedException("Unable to create a template from volume with id " + volumeId + ", permission denied.");
|
||||
}
|
||||
}
|
||||
|
||||
String name = cmd.getTemplateName();
|
||||
if ((name == null) || (name.length() > 32)) {
|
||||
throw new InvalidParameterValueException("Template name cannot be null and should be less than 32 characters");
|
||||
}
|
||||
|
||||
String uniqueName = Long.valueOf((userId == null)?1:userId).toString() + Long.valueOf(volumeId).toString() + UUID.nameUUIDFromBytes(name.getBytes()).toString();
|
||||
|
||||
VMTemplateVO existingTemplate = _templateDao.findByTemplateNameAccountId(name, volume.getAccountId());
|
||||
if (existingTemplate != null) {
|
||||
throw new InvalidParameterValueException("Failed to create private template " + name + ", a template with that name already exists.");
|
||||
}
|
||||
|
||||
AccountVO ownerAccount = _accountDao.findById(volume.getAccountId());
|
||||
if (_accountMgr.resourceLimitExceeded(ownerAccount, ResourceType.template)) {
|
||||
ResourceAllocationException rae = new ResourceAllocationException("Maximum number of templates and ISOs for account: " + account.getAccountName() + " has been exceeded.");
|
||||
rae.setResourceType("template");
|
||||
throw rae;
|
||||
}
|
||||
// do some parameter defaulting
|
||||
Integer bits = cmd.getBits();
|
||||
Boolean requiresHvm = cmd.getRequiresHvm();
|
||||
Boolean passwordEnabled = cmd.isPasswordEnabled();
|
||||
Boolean isPublic = cmd.isPublic();
|
||||
Boolean featured = cmd.isFeatured();
|
||||
|
||||
HypervisorType hyperType = _volsDao.getHypervisorType(volumeId);
|
||||
int bitsValue = ((bits == null) ? 64 : bits.intValue());
|
||||
boolean requiresHvmValue = ((requiresHvm == null) ? true : requiresHvm.booleanValue());
|
||||
boolean passwordEnabledValue = ((passwordEnabled == null) ? false : passwordEnabled.booleanValue());
|
||||
Integer bits = cmd.getBits();
|
||||
Boolean requiresHvm = cmd.getRequiresHvm();
|
||||
Boolean passwordEnabled = cmd.isPasswordEnabled();
|
||||
Boolean isPublic = cmd.isPublic();
|
||||
Boolean featured = cmd.isFeatured();
|
||||
int bitsValue = ((bits == null) ? 64 : bits.intValue());
|
||||
boolean requiresHvmValue = ((requiresHvm == null) ? true : requiresHvm.booleanValue());
|
||||
boolean passwordEnabledValue = ((passwordEnabled == null) ? false : passwordEnabled.booleanValue());
|
||||
if (isPublic == null) {
|
||||
isPublic = Boolean.FALSE;
|
||||
}
|
||||
|
||||
if (!isAdmin || featured == null) {
|
||||
featured = Boolean.FALSE;
|
||||
}
|
||||
|
||||
boolean allowPublicUserTemplates = Boolean.parseBoolean(_configDao.getValue("allow.public.user.templates"));
|
||||
if (!isAdmin && !allowPublicUserTemplates && isPublic) {
|
||||
throw new PermissionDeniedException("Failed to create template " + name + ", only private templates can be created.");
|
||||
}
|
||||
|
||||
// if the volume is a root disk, try to find out requiresHvm and bits if possible
|
||||
if (Volume.VolumeType.ROOT.equals(volume.getVolumeType())) {
|
||||
Long instanceId = volume.getInstanceId();
|
||||
if (instanceId != null) {
|
||||
UserVm vm = _vmDao.findById(instanceId);
|
||||
if (vm != null) {
|
||||
VMTemplateVO origTemplate = _templateDao.findById(vm.getTemplateId());
|
||||
if (!ImageFormat.ISO.equals(origTemplate.getFormat()) && !ImageFormat.RAW.equals(origTemplate.getFormat())) {
|
||||
bitsValue = origTemplate.getBits();
|
||||
requiresHvmValue = origTemplate.requiresHvm();
|
||||
}
|
||||
}
|
||||
|
||||
Long volumeId = cmd.getVolumeId();
|
||||
Long snapshotId = cmd.getSnapshotId();
|
||||
if ( (volumeId == null) && (snapshotId == null) ) {
|
||||
throw new InvalidParameterValueException("Failed to create private template record, neither volume ID nor snapshot ID were specified.");
|
||||
}
|
||||
if ( (volumeId != null) && (snapshotId != null) ) {
|
||||
throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId + ") and snapshot ID (" + snapshotId + ")");
|
||||
}
|
||||
|
||||
long domainId;
|
||||
long accountId;
|
||||
HypervisorType hyperType;
|
||||
VolumeVO volume = null;
|
||||
if (volumeId != null) { // create template from volume
|
||||
volume = _volsDao.findById(volumeId);
|
||||
if (volume == null) {
|
||||
throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId);
|
||||
}
|
||||
// If private template is created from Volume, check that the volume will not be active when the private template is created
|
||||
if (!_storageMgr.volumeInactive(volume)) {
|
||||
String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM, please stop the VM first" ;
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info(msg);
|
||||
}
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
domainId = volume.getDomainId();
|
||||
accountId = volume.getAccountId();
|
||||
hyperType = _volsDao.getHypervisorType(volumeId);
|
||||
} else { // create template from snapshot
|
||||
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
|
||||
if (snapshot == null) {
|
||||
throw new InvalidParameterValueException("Failed to create private template record, unable to find snapshot " + snapshotId);
|
||||
}
|
||||
domainId = snapshot.getDomainId();
|
||||
accountId = snapshot.getAccountId();
|
||||
hyperType = snapshot.getHypervisorType();
|
||||
volume = _volsDao.findById(snapshot.getVolumeId());
|
||||
}
|
||||
|
||||
if (!isAdmin) {
|
||||
if (account.getId() != accountId) {
|
||||
throw new PermissionDeniedException("Unable to create a template permission denied.");
|
||||
}
|
||||
} else if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) {
|
||||
throw new PermissionDeniedException("Unable to create a template permission denied.");
|
||||
}
|
||||
|
||||
VMTemplateVO existingTemplate = _templateDao.findByTemplateNameAccountId(name, accountId);
|
||||
if (existingTemplate != null) {
|
||||
throw new InvalidParameterValueException("Failed to create private template " + name + ", a template with that name already exists.");
|
||||
}
|
||||
|
||||
AccountVO ownerAccount = _accountDao.findById(accountId);
|
||||
if (_accountMgr.resourceLimitExceeded(ownerAccount, ResourceType.template)) {
|
||||
ResourceAllocationException rae = new ResourceAllocationException("Maximum number of templates and ISOs for account: " + account.getAccountName() + " has been exceeded.");
|
||||
rae.setResourceType("template");
|
||||
throw rae;
|
||||
}
|
||||
|
||||
if (!isAdmin || featured == null) {
|
||||
featured = Boolean.FALSE;
|
||||
}
|
||||
Long guestOSId = cmd.getOsTypeId();
|
||||
GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
|
||||
if (guestOS == null) {
|
||||
throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist.");
|
||||
}
|
||||
|
||||
|
||||
String uniqueName = Long.valueOf((userId == null)?1:userId).toString() + UUID.nameUUIDFromBytes(name.getBytes()).toString();
|
||||
Long nextTemplateId = _templateDao.getNextInSequence(Long.class, "id");
|
||||
String description = cmd.getDisplayText();
|
||||
VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
|
||||
boolean isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM ;
|
||||
|
||||
boolean isExtractable = false;
|
||||
if ( volume != null ) {
|
||||
VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
|
||||
isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM ;
|
||||
}
|
||||
privateTemplate = new VMTemplateVO(nextTemplateId,
|
||||
uniqueName,
|
||||
name,
|
||||
|
|
@ -1306,7 +1305,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
null,
|
||||
requiresHvmValue,
|
||||
bitsValue,
|
||||
volume.getAccountId(),
|
||||
accountId,
|
||||
null,
|
||||
description,
|
||||
passwordEnabledValue,
|
||||
|
|
@ -1326,66 +1325,48 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
long templateId = command.getEntityId();
|
||||
Long volumeId = command.getVolumeId();
|
||||
Long snapshotId = command.getSnapshotId();
|
||||
SnapshotVO snapshot = null;
|
||||
|
||||
// Verify input parameters
|
||||
if (snapshotId != null) {
|
||||
snapshot = _snapshotDao.findById(snapshotId);
|
||||
|
||||
// Set the volumeId to that of the snapshot. All further input parameter checks will be done w.r.t the volume.
|
||||
volumeId = snapshot.getVolumeId();
|
||||
}
|
||||
|
||||
// The volume below could be destroyed or removed.
|
||||
VolumeVO volume = _volsDao.findById(volumeId);
|
||||
String vmName = _storageMgr.getVmNameOnVolume(volume);
|
||||
|
||||
// If private template is created from Volume, check that the volume will not be active when the private template is created
|
||||
if (snapshotId == null && !_storageMgr.volumeInactive(volume)) {
|
||||
String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM.";
|
||||
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info(msg);
|
||||
}
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
SnapshotCommand cmd = null;
|
||||
VMTemplateVO privateTemplate = null;
|
||||
long zoneId = volume.getDataCenterId();
|
||||
|
||||
String uniqueName = getRandomPrivateTemplateName();
|
||||
|
||||
HostVO secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
|
||||
String secondaryStorageURL = _storageMgr.getSecondaryStorageURL(zoneId);
|
||||
if (secondaryStorageHost == null || secondaryStorageURL == null) {
|
||||
throw new CloudRuntimeException("Did not find the secondary storage URL in the database for zoneId "
|
||||
+ zoneId);
|
||||
}
|
||||
|
||||
if (snapshotId != null) {
|
||||
volume = _volsDao.findById(volumeId);
|
||||
StringBuilder userFolder = new StringBuilder();
|
||||
Formatter userFolderFormat = new Formatter(userFolder);
|
||||
userFolderFormat.format("u%06d", snapshot.getAccountId());
|
||||
StoragePoolVO pool = null;
|
||||
HostVO secondaryStorageHost = null;
|
||||
long zoneId;
|
||||
Long accountId = null;
|
||||
if (snapshotId != null) { // create template from snapshot
|
||||
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
|
||||
if( snapshot == null ) {
|
||||
throw new CloudRuntimeException("Unable to find Snapshot for Id " + snapshotId);
|
||||
}
|
||||
zoneId = snapshot.getDataCenterId();
|
||||
secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
|
||||
if ( secondaryStorageHost == null ) {
|
||||
throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
|
||||
}
|
||||
String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
|
||||
|
||||
String name = command.getTemplateName();
|
||||
String backupSnapshotUUID = snapshot.getBackupSnapshotId();
|
||||
if (backupSnapshotUUID == null) {
|
||||
throw new CloudRuntimeException("Unable to create private template from snapshot " + snapshotId + " due to there is no backupSnapshotUUID for this snapshot");
|
||||
}
|
||||
|
||||
// We are creating a private template from a snapshot which has been
|
||||
// backed up to secondary storage.
|
||||
Long dcId = volume.getDataCenterId();
|
||||
Long accountId = volume.getAccountId();
|
||||
|
||||
Long dcId = snapshot.getDataCenterId();
|
||||
accountId = snapshot.getAccountId();
|
||||
volumeId = snapshot.getVolumeId();
|
||||
|
||||
String origTemplateInstallPath = null;
|
||||
|
||||
cmd = new CreatePrivateTemplateFromSnapshotCommand(_storageMgr.getPrimaryStorageNameLabel(volume),
|
||||
List<StoragePoolVO> storagePools = _storagePoolDao.listByDataCenterId(zoneId);
|
||||
if( storagePools == null || storagePools.size() == 0) {
|
||||
throw new CloudRuntimeException("Unable to find storage pools in zone " + zoneId);
|
||||
}
|
||||
pool = storagePools.get(0);
|
||||
cmd = new CreatePrivateTemplateFromSnapshotCommand(pool.getUuid(),
|
||||
secondaryStorageURL, dcId, accountId, snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
|
||||
origTemplateInstallPath, templateId, name);
|
||||
} else if (volumeId != null) {
|
||||
volume = _volsDao.findById(volumeId);
|
||||
} else if (volumeId != null) {
|
||||
VolumeVO volume = _volsDao.findById(volumeId);
|
||||
if( volume == null ) {
|
||||
throw new CloudRuntimeException("Unable to find volume for Id " + volumeId);
|
||||
}
|
||||
|
|
@ -1393,14 +1374,15 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
_templateDao.remove(templateId);
|
||||
throw new CloudRuntimeException("Volume " + volumeId + " is empty, can't create template on it");
|
||||
}
|
||||
Long instanceId = volume.getInstanceId();
|
||||
if (instanceId != null){
|
||||
VMInstanceVO vm = _vmDao.findById(instanceId);
|
||||
State vmState = vm.getState();
|
||||
if( !vmState.equals(State.Stopped) && !vmState.equals(State.Destroyed)) {
|
||||
throw new CloudRuntimeException("Please put VM " + vm.getName() + " into Stopped state first");
|
||||
}
|
||||
}
|
||||
String vmName = _storageMgr.getVmNameOnVolume(volume);
|
||||
zoneId = volume.getDataCenterId();
|
||||
secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
|
||||
if ( secondaryStorageHost == null ) {
|
||||
throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
|
||||
}
|
||||
String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
|
||||
|
||||
pool = _storagePoolDao.findById(volume.getPoolId());
|
||||
cmd = new CreatePrivateTemplateFromVolumeCommand(secondaryStorageURL, templateId, volume.getAccountId(),
|
||||
command.getTemplateName(), uniqueName, volume.getPath(), vmName);
|
||||
|
||||
|
|
@ -1411,35 +1393,18 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
// on the storage server to create the template
|
||||
|
||||
// This can be sent to a KVM host too.
|
||||
StoragePool pool = _storagePoolDao.findById(volume.getPoolId());
|
||||
CreatePrivateTemplateAnswer answer = null;
|
||||
volume = _volsDao.acquireInLockTable(volumeId, 10);
|
||||
if( volume == null ) {
|
||||
if( ! _volsDao.lockInLockTable(volumeId.toString(), 10)) {
|
||||
throw new CloudRuntimeException("Creating template failed due to volume:" + volumeId + " is being used, try it later ");
|
||||
}
|
||||
try {
|
||||
answer = (CreatePrivateTemplateAnswer)_storageMgr.sendToPool(pool, cmd);
|
||||
} catch (StorageUnavailableException e) {
|
||||
} finally {
|
||||
_volsDao.releaseFromLockTable(volumeId);
|
||||
_volsDao.unlockFromLockTable(volumeId.toString());
|
||||
}
|
||||
|
||||
if ((answer != null) && answer.getResult()) {
|
||||
privateTemplate = _templateDao.findById(templateId);
|
||||
Long origTemplateId = volume.getTemplateId();
|
||||
VMTemplateVO origTemplate = null;
|
||||
if (origTemplateId != null) {
|
||||
origTemplate = _templateDao.findById(origTemplateId);
|
||||
}
|
||||
|
||||
if ((origTemplate != null) && !Storage.ImageFormat.ISO.equals(origTemplate.getFormat())) {
|
||||
privateTemplate.setRequiresHvm(origTemplate.requiresHvm());
|
||||
privateTemplate.setBits(origTemplate.getBits());
|
||||
} else {
|
||||
privateTemplate.setRequiresHvm(true);
|
||||
privateTemplate.setBits(64);
|
||||
}
|
||||
|
||||
String answerUniqueName = answer.getUniqueName();
|
||||
if (answerUniqueName != null) {
|
||||
privateTemplate.setUniqueName(answerUniqueName);
|
||||
|
|
@ -1454,11 +1419,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
// Specify RAW format makes it unusable for snapshots.
|
||||
privateTemplate.setFormat(ImageFormat.RAW);
|
||||
}
|
||||
|
||||
if(snapshot != null) {
|
||||
privateTemplate.setHypervisorType(snapshot.getHypervisorType());
|
||||
}
|
||||
|
||||
|
||||
_templateDao.update(templateId, privateTemplate);
|
||||
|
||||
// add template zone ref for this template
|
||||
|
|
@ -1476,7 +1437,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
_usageEventDao.persist(usageEvent);
|
||||
|
||||
// Increment the number of templates
|
||||
_accountMgr.incrementResourceCount(volume.getAccountId(), ResourceType.template);
|
||||
_accountMgr.incrementResourceCount(accountId, ResourceType.template);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
|
|||
|
|
@ -351,7 +351,6 @@ INSERT INTO `cloud`.`sequence` (name, value) VALUES ('private_mac_address_seq',
|
|||
INSERT INTO `cloud`.`sequence` (name, value) VALUES ('storage_pool_seq', 200);
|
||||
INSERT INTO `cloud`.`sequence` (name, value) VALUES ('volume_seq', 1);
|
||||
INSERT INTO `cloud`.`sequence` (name, value) VALUES ('networks_seq', 200);
|
||||
INSERT INTO `cloud`.`sequence` (name, value) VALUES ('snapshots_seq', 1);
|
||||
|
||||
CREATE TABLE `cloud`.`volumes` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
|
||||
|
|
@ -398,13 +397,16 @@ CREATE TABLE `cloud`.`volumes` (
|
|||
|
||||
CREATE TABLE `cloud`.`snapshots` (
|
||||
`id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
|
||||
`data_center_id` bigint unsigned NOT NULL,
|
||||
`account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table',
|
||||
`domain_id` bigint unsigned NOT NULL COMMENT 'the domain that the owner belongs to',
|
||||
`volume_id` bigint unsigned NOT NULL COMMENT 'volume it belongs to. foreign key to volume table',
|
||||
`status` varchar(32) COMMENT 'snapshot creation status',
|
||||
`path` varchar(255) COMMENT 'Path',
|
||||
`name` varchar(255) NOT NULL COMMENT 'snapshot name',
|
||||
`snapshot_type` int(4) NOT NULL COMMENT 'type of snapshot, e.g. manual, recurring',
|
||||
`type_description` varchar(25) COMMENT 'description of the type of snapshot, e.g. manual, recurring',
|
||||
`size` bigint unsigned NOT NULL COMMENT 'original disk size of snapshot',
|
||||
`created` datetime COMMENT 'Date Created',
|
||||
`removed` datetime COMMENT 'Date removed. not null if removed',
|
||||
`backup_snap_id` varchar(255) COMMENT 'Back up uuid of the snapshot',
|
||||
|
|
@ -1242,7 +1244,7 @@ CREATE TABLE `cloud`.`launch_permission` (
|
|||
|
||||
CREATE TABLE `cloud`.`snapshot_policy` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`volume_id` bigint unsigned NOT NULL unique,
|
||||
`volume_id` bigint unsigned NOT NULL,
|
||||
`schedule` varchar(100) NOT NULL COMMENT 'schedule time of execution',
|
||||
`timezone` varchar(100) NOT NULL COMMENT 'the timezone in which the schedule time is specified',
|
||||
`interval` int(4) NOT NULL default 4 COMMENT 'backup schedule, e.g. hourly, daily, etc.',
|
||||
|
|
@ -1260,11 +1262,12 @@ CREATE TABLE `cloud`.`snapshot_policy_ref` (
|
|||
|
||||
CREATE TABLE `cloud`.`snapshot_schedule` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`volume_id` bigint unsigned NOT NULL unique COMMENT 'The volume for which this snapshot is being taken',
|
||||
`volume_id` bigint unsigned NOT NULL COMMENT 'The volume for which this snapshot is being taken',
|
||||
`policy_id` bigint unsigned NOT NULL COMMENT 'One of the policyIds for which this snapshot was taken',
|
||||
`scheduled_timestamp` datetime NOT NULL COMMENT 'Time at which the snapshot was scheduled for execution',
|
||||
`async_job_id` bigint unsigned COMMENT 'If this schedule is being executed, it is the id of the create aysnc_job. Before that it is null',
|
||||
`snapshot_id` bigint unsigned COMMENT 'If this schedule is being executed, then the corresponding snapshot has this id. Before that it is null',
|
||||
UNIQUE (volume_id, policy_id),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
-- Schema upgrade from 2.1 to 2.2;
|
||||
--;
|
||||
ALTER TABLE `cloud`.`template_host_ref` ADD COLUMN `physical_size` bigint unsigned NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `cloud`.`snapshots` MODIFY COLUMN `id` bigint unsigned UNIQUE NOT NULL;
|
||||
ALTER TABLE `cloud`.`vm_instance` DROP COLUMN `group`;
|
||||
ALTER TABLE `cloud`.`cluster` ADD COLUMN `guid` varchar(255) UNIQUE DEFAULT NULL;
|
||||
ALTER TABLE `cloud`.`cluster` ADD COLUMN `cluster_type` varchar(64) DEFAULT 'CloudManaged';
|
||||
|
|
@ -335,6 +334,10 @@ CREATE TABLE `cloud`.`upload` (
|
|||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `cloud`.`snapshots` ADD COLUMN `data_center_id` bigint unsigned NOT NULL;
|
||||
ALTER TABLE `cloud`.`snapshots` ADD COLUMN `domain_id` bigint unsigned NOT NULL;
|
||||
ALTER TABLE `cloud`.`snapshots` ADD COLUMN `size` bigint unsigned NOT NULL ;
|
||||
|
||||
ALTER TABLE `cloud`.`template_host_ref` ADD COLUMN `physical size` bigint unsigned DEFAULT 0;
|
||||
|
||||
ALTER TABLE `cloud`.`console_proxy` MODIFY COLUMN `public_mac_address` varchar(17);
|
||||
|
|
@ -518,4 +521,3 @@ CREATE TABLE `cloud`.`storage_pool_work` (
|
|||
-- Insert stuff?;
|
||||
INSERT INTO `cloud`.`sequence` (name, value) VALUES ('volume_seq', (SELECT max(id) + 1 or 200 from volumes));
|
||||
INSERT INTO `cloud`.`sequence` (name, value) VALUES ('networks_seq', 200);
|
||||
INSERT INTO `cloud`.`sequence` (name, value) VALUES ('snapshots_seq', (SELECT max(id) + 1 or 200 from snapshots));
|
||||
|
|
|
|||
|
|
@ -91,17 +91,7 @@ public class DateUtil {
|
|||
DAILY,
|
||||
WEEKLY,
|
||||
MONTHLY;
|
||||
|
||||
private int max = 8;
|
||||
|
||||
public void setMax(int max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
boolean equals(String intervalType) {
|
||||
return super.toString().equalsIgnoreCase(intervalType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,5 +228,11 @@ public interface GenericDao<T, ID extends Serializable> {
|
|||
boolean configure(String name, Map<String, Object> params) throws ConfigurationException;
|
||||
|
||||
<M> List<M> customSearch(SearchCriteria<M> sc, Filter filter);
|
||||
|
||||
boolean lockInLockTable(String id);
|
||||
|
||||
boolean lockInLockTable(String id, int seconds);
|
||||
|
||||
boolean unlockFromLockTable(String id);
|
||||
|
||||
}
|
||||
|
|
@ -923,6 +923,23 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
|
|||
final Transaction txn = Transaction.currentTxn();
|
||||
return txn.release(_table + id);
|
||||
}
|
||||
|
||||
@Override @DB(txn=false)
|
||||
public boolean lockInLockTable(final String id) {
|
||||
return lockInLockTable(id, _timeoutSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lockInLockTable(final String id, int seconds) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
return txn.lock(_table + id, seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlockFromLockTable(final String id) {
|
||||
final Transaction txn = Transaction.currentTxn();
|
||||
return txn.release(_table + id);
|
||||
}
|
||||
|
||||
@Override @DB(txn=false)
|
||||
public List<T> listAllIncludingRemoved() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue