diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/Storage.java index c130fe222bf..c50bd7e7e87 100755 --- a/api/src/com/cloud/storage/Storage.java +++ b/api/src/com/cloud/storage/Storage.java @@ -21,13 +21,13 @@ import java.util.List; public class Storage { public static enum ImageFormat { - QCOW2(true, true, false), - RAW(false, false, false), - VHD(true, true, true), - ISO(false, false, false), + QCOW2(true, true, false, "qcow2"), + RAW(false, false, false, "raw"), + VHD(true, true, true, "vhd"), + ISO(false, false, false, "iso"), OVA(true, true, true, "ova"), - BAREMETAL(false, false, false), - TAR(false, false, false); + BAREMETAL(false, false, false, "BAREMETAL"), + TAR(false, false, false, "tar"); private final boolean thinProvisioned; private final boolean supportSparse; @@ -66,6 +66,7 @@ public class Storage { return fileExtension; } + } public static enum FileSystem { diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 4903594f0af..5d11ba9ed0d 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -173,4 +173,5 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba * @param reserv */ void setReservationId(String reserv); + Storage.ImageFormat getFormat(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index c722bbf11fd..2d72922d7dd 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -97,9 +97,6 @@ public class VolumeDataStoreVO implements StateObject, StateDao { - - List findDetachedByAccount(long accountId); - - List findByAccount(long accountId); - - Pair getCountAndTotalByPool(long poolId); - - Pair getNonDestroyedCountAndTotalByPool(long poolId); - - List findByInstance(long id); - - List findByInstanceAndType(long id, VolumeType vType); - - List findByInstanceIdDestroyed(long vmId); - - List findByAccountAndPod(long accountId, long podId); - - List findByTemplateAndZone(long templateId, long zoneId); - - void deleteVolumesByInstance(long instanceId); - - void attachVolume(long volumeId, long vmId, long deviceId); - - void detachVolume(long volumeId); - - boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId); - - List findCreatedByInstance(long id); - - List findByPoolId(long poolId); - - List findByInstanceAndDeviceId(long instanceId, long deviceId); - - List findUsableVolumesForInstance(long instanceId); - - Long countAllocatedVolumesForAccount(long accountId); - - HypervisorType getHypervisorType(long volumeId); - - List listVolumesToBeDestroyed(); - - ImageFormat getImageFormat(Long volumeId); - - List findReadyRootVolumesByInstance(long instanceId); - - List listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId); - - VolumeVO allocVolume(long size, VolumeType type, String volName, Long templateId); - - VolumeVO findByVolumeIdAndPoolId(long volumeId, long poolId); -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao2Impl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao2Impl.java deleted file mode 100644 index d8497e2f3da..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao2Impl.java +++ /dev/null @@ -1,440 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package org.apache.cloudstack.storage.volume.db; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import javax.ejb.Local; -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; -import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; -import org.apache.cloudstack.storage.volume.VolumeEvent; - -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Volume; -import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.tags.dao.ResourceTagsDaoImpl; -import com.cloud.utils.Pair; - -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GenericSearchBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.db.UpdateBuilder; -import com.cloud.utils.exception.CloudRuntimeException; - -@Local(value = VolumeDao2.class) -@Component -public class VolumeDao2Impl extends GenericDaoBase implements VolumeDao2 { - private static final Logger s_logger = Logger.getLogger(VolumeDao2Impl.class); - protected final SearchBuilder DetachedAccountIdSearch; - protected final SearchBuilder TemplateZoneSearch; - protected final GenericSearchBuilder TotalSizeByPoolSearch; - protected final GenericSearchBuilder ActiveTemplateSearch; - protected final SearchBuilder InstanceStatesSearch; - protected final SearchBuilder AllFieldsSearch; - protected GenericSearchBuilder CountByAccount; - @Inject ResourceTagDao _tagsDao = null; - protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?"; - protected static final String SELECT_HYPERTYPE_FROM_VOLUME = "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?"; - - private static final String ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT = "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? " - + " AND pool.pod_id = ? AND pool.cluster_id = ? " + " GROUP BY pool.id ORDER BY 2 ASC "; - - @Override - public List findDetachedByAccount(long accountId) { - SearchCriteria sc = DetachedAccountIdSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("destroyed", Volume.State.Destroy); - return listBy(sc); - } - - @Override - public List findByAccount(long accountId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("state", Volume.State.Ready); - return listBy(sc); - } - - @Override - public List findByInstance(long id) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", id); - return listBy(sc); - } - - @Override - public List findByInstanceAndDeviceId(long instanceId, long deviceId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", instanceId); - sc.setParameters("deviceId", deviceId); - return listBy(sc); - } - - @Override - public List findByPoolId(long poolId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("poolId", poolId); - sc.setParameters("notDestroyed", Volume.State.Destroy); - sc.setParameters("vType", new RootDisk().toString()); - return listBy(sc); - } - - @Override - public List findCreatedByInstance(long id) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", id); - sc.setParameters("state", Volume.State.Ready); - return listBy(sc); - } - - @Override - public List findUsableVolumesForInstance(long instanceId) { - SearchCriteria sc = InstanceStatesSearch.create(); - sc.setParameters("instance", instanceId); - sc.setParameters("states", Volume.State.Creating, Volume.State.Ready, Volume.State.Allocated); - - return listBy(sc); - } - - @Override - public List findByInstanceAndType(long id, VolumeType vType) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", id); - sc.setParameters("vType", vType.toString()); - return listBy(sc); - } - - @Override - public List findByInstanceIdDestroyed(long vmId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", vmId); - sc.setParameters("destroyed", Volume.State.Destroy); - return listBy(sc); - } - - @Override - public List findReadyRootVolumesByInstance(long instanceId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", instanceId); - sc.setParameters("state", Volume.State.Ready); - sc.setParameters("vType", new RootDisk().toString()); - return listBy(sc); - } - - @Override - public List findByAccountAndPod(long accountId, long podId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("pod", podId); - sc.setParameters("state", Volume.State.Ready); - - return listIncludingRemovedBy(sc); - } - - @Override - public List findByTemplateAndZone(long templateId, long zoneId) { - SearchCriteria sc = TemplateZoneSearch.create(); - sc.setParameters("template", templateId); - sc.setParameters("zone", zoneId); - - return listIncludingRemovedBy(sc); - } - - @Override - public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) { - SearchCriteria sc = ActiveTemplateSearch.create(); - sc.setParameters("template", templateId); - sc.setParameters("pool", poolId); - - List results = customSearchIncludingRemoved(sc, null); - assert results.size() > 0 : "How can this return a size of " + results.size(); - - return results.get(0) > 0; - } - - @Override - public void deleteVolumesByInstance(long instanceId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", instanceId); - expunge(sc); - } - - @Override - public void attachVolume(long volumeId, long vmId, long deviceId) { - VolumeVO volume = createForUpdate(volumeId); - volume.setInstanceId(vmId); - volume.setDeviceId(deviceId); - volume.setUpdated(new Date()); - volume.setAttached(new Date()); - update(volumeId, volume); - } - - @Override - public void detachVolume(long volumeId) { - VolumeVO volume = createForUpdate(volumeId); - volume.setInstanceId(null); - volume.setDeviceId(null); - volume.setUpdated(new Date()); - volume.setAttached(null); - update(volumeId, volume); - } - - @Override - @DB - public HypervisorType getHypervisorType(long volumeId) { - /* lookup from cluster of pool */ - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - - try { - String sql = SELECT_HYPERTYPE_FROM_VOLUME; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, volumeId); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - return HypervisorType.getType(rs.getString(1)); - } - return HypervisorType.None; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + SELECT_HYPERTYPE_FROM_VOLUME, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + SELECT_HYPERTYPE_FROM_VOLUME, e); - } - } - - @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 VolumeDao2Impl() { - AllFieldsSearch = createSearchBuilder(); - AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); - AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ); - AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ); - AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ); - AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getDeviceId(), Op.EQ); - AllFieldsSearch.and("poolId", AllFieldsSearch.entity().getPoolId(), Op.EQ); - AllFieldsSearch.and("vType", AllFieldsSearch.entity().getVolumeType(), Op.EQ); - AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); - AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getState(), Op.EQ); - AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), Op.NEQ); - AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ); - AllFieldsSearch.done(); - - DetachedAccountIdSearch = createSearchBuilder(); - DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ); - DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getState(), Op.NEQ); - DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL); - DetachedAccountIdSearch.done(); - - TemplateZoneSearch = createSearchBuilder(); - TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ); - TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ); - TemplateZoneSearch.done(); - - TotalSizeByPoolSearch = createSearchBuilder(SumCount.class); - TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize()); - TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[]) null); - TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ); - TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL); - TotalSizeByPoolSearch.and("state", TotalSizeByPoolSearch.entity().getState(), Op.NEQ); - TotalSizeByPoolSearch.done(); - - ActiveTemplateSearch = createSearchBuilder(Long.class); - ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ); - ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ); - ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL); - ActiveTemplateSearch.select(null, Func.COUNT, null); - ActiveTemplateSearch.done(); - - InstanceStatesSearch = createSearchBuilder(); - InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ); - InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN); - InstanceStatesSearch.done(); - - CountByAccount = createSearchBuilder(Long.class); - CountByAccount.select(null, Func.COUNT, null); - CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); - CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN); - CountByAccount.done(); - } - - @Override - @DB(txn = false) - public Pair getCountAndTotalByPool(long poolId) { - SearchCriteria sc = TotalSizeByPoolSearch.create(); - sc.setParameters("poolId", poolId); - List results = customSearch(sc, null); - SumCount sumCount = results.get(0); - return new Pair(sumCount.count, sumCount.sum); - } - - @Override - public Long countAllocatedVolumesForAccount(long accountId) { - SearchCriteria sc = CountByAccount.create(); - sc.setParameters("account", accountId); - sc.setParameters("state", Volume.State.Destroy); - return customSearch(sc, null).get(0); - } - - public static class SumCount { - public long sum; - public long count; - - public SumCount() { - } - } - - @Override - public List listVolumesToBeDestroyed() { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("state", Volume.State.Destroy); - - return listBy(sc); - } - - @Override - public boolean updateState(Volume.State currentState, Volume.Event event, Volume.State nextState, VolumeVO vo, Object data) { - - Long oldUpdated = vo.getUpdatedCount(); - Date oldUpdatedTime = vo.getUpdated(); - - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("id", vo.getId()); - sc.setParameters("state", currentState); - sc.setParameters("updatedCount", vo.getUpdatedCount()); - - vo.incrUpdatedCount(); - - UpdateBuilder builder = getUpdateBuilder(vo); - builder.set(vo, "state", nextState); - builder.set(vo, "updated", new Date()); - - int rows = update((VolumeVO) vo, sc); - if (rows == 0 && s_logger.isDebugEnabled()) { - VolumeVO dbVol = findByIdIncludingRemoved(vo.getId()); - if (dbVol != null) { - StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); - str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") - .append(dbVol.getUpdated()); - str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()) - .append("; updatedTime=").append(vo.getUpdated()); - str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated) - .append("; updatedTime=").append(oldUpdatedTime); - } else { - s_logger.debug("Unable to update volume: id=" + vo.getId() + ", as there is no such volume exists in the database anymore"); - } - } - return rows > 0; - } - - @Override - public List listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId) { - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - try { - String sql = ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, accountId); - pstmt.setLong(2, dcId); - pstmt.setLong(3, podId); - pstmt.setLong(4, clusterId); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - result.add(rs.getLong(1)); - } - return result; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e); - } - } - - @Override - @DB(txn = false) - public Pair getNonDestroyedCountAndTotalByPool(long poolId) { - SearchCriteria sc = TotalSizeByPoolSearch.create(); - sc.setParameters("poolId", poolId); - sc.setParameters("state", Volume.State.Destroy); - List results = customSearch(sc, null); - SumCount sumCount = results.get(0); - return new Pair(sumCount.count, sumCount.sum); - } - - @Override - @DB - public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - VolumeVO entry = findById(id); - if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.Volume); - } - boolean result = super.remove(id); - txn.commit(); - return result; - } - - @Override - @DB - public VolumeVO allocVolume(long size, VolumeType type, String volName, Long templateId) { - VolumeVO vol = new VolumeVO(size, type.toString(), volName, templateId); - vol = this.persist(vol); - return vol; - } - - @Override - public VolumeVO findByVolumeIdAndPoolId(long volumeId, long poolId) { - SearchCriteriaService sc = SearchCriteria2.create(VolumeVO.class); - sc.addAnd(sc.getEntity().getId(), Op.EQ, volumeId); - sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, poolId); - return sc.find(); - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java deleted file mode 100644 index 831022455c9..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java +++ /dev/null @@ -1,418 +0,0 @@ -//Licensed to the Apache Software Foundation (ASF) under one -//or more contributor license agreements. See the NOTICE file -//distributed with this work for additional information -//regarding copyright ownership. The ASF licenses this file -//to you under the Apache License, Version 2.0 (the -//"License"); you may not use this file except in compliance -//with the License. You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, -//software distributed under the License is distributed on an -//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -//KIND, either express or implied. See the License for the -//specific language governing permissions and limitations -//under the License. - -package org.apache.cloudstack.storage.volume.db; - -import java.util.Date; -import java.util.UUID; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.TableGenerator; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; - -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Volume; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.db.GenericDao; -import com.cloud.utils.fsm.StateObject; - -@Entity -@Table(name = "volumes") -public class VolumeVO implements Identity, StateObject { - @Id - @TableGenerator(name = "volume_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "volume_seq", allocationSize = 1) - @GeneratedValue(strategy = GenerationType.TABLE) - @Column(name = "id") - long id; - - @Column(name = "name") - String name; - - @Column(name = "pool_id") - Long poolId; - - @Column(name = "last_pool_id") - Long lastPoolId; - - @Column(name = "account_id") - long accountId; - - @Column(name = "domain_id") - long domainId; - - @Column(name = "instance_id") - Long instanceId = null; - - @Column(name = "device_id") - Long deviceId = null; - - @Column(name = "size") - long size; - - @Column(name = "folder") - String folder; - - @Column(name = "path") - String path; - - @Column(name = "pod_id") - Long podId; - - @Column(name = "created") - Date created; - - @Column(name = "attached") - @Temporal(value = TemporalType.TIMESTAMP) - Date attached; - - @Column(name = "data_center_id") - long dataCenterId; - - @Column(name = "host_ip") - String hostip; - - @Column(name = "disk_offering_id") - long diskOfferingId; - - @Column(name = "template_id") - Long templateId; - - @Column(name = "first_snapshot_backup_uuid") - String firstSnapshotBackupUuid; - - @Column(name = "volume_type") - String volumeType = "UNKNOWN"; - - @Column(name = "pool_type") - @Enumerated(EnumType.STRING) - StoragePoolType poolType; - - @Column(name = "disk_type") - DiskFormat diskType; - - @Column(name = GenericDao.REMOVED_COLUMN) - Date removed; - - @Column(name = "updated") - @Temporal(value = TemporalType.TIMESTAMP) - Date updated; - - @Column(name = "update_count", updatable = true, nullable = false) - protected long updatedCount; // This field should be updated everytime the - // state is updated. There's no set method in - // the vo object because it is done with in the - // dao code. - - @Column(name = "recreatable") - boolean recreatable; - - @Column(name = "state") - @Enumerated(value = EnumType.STRING) - private Volume.State state; - - @Column(name = "chain_info") - String chainInfo; - - @Column(name = "uuid") - String uuid; - - // Real Constructor - public VolumeVO(long size, String type, String name, Long templateId) { - this.volumeType = type; - this.size = size; - this.name = name; - this.templateId = templateId; - this.uuid = UUID.randomUUID().toString(); - this.state = Volume.State.Allocated; - } - - // Copy Constructor - public VolumeVO(VolumeVO that) { - this(that.getSize(), that.getVolumeType(), that.getName(), that.getTemplateId()); - this.recreatable = that.isRecreatable(); - this.state = that.getState(); - - this.size = that.getSize(); - this.diskOfferingId = that.getDiskOfferingId(); - this.poolId = that.getPoolId(); - this.attached = that.getAttached(); - this.chainInfo = that.getChainInfo(); - this.templateId = that.getTemplateId(); - this.deviceId = that.getDeviceId(); - this.uuid = UUID.randomUUID().toString(); - } - - public long getUpdatedCount() { - return this.updatedCount; - } - - public void incrUpdatedCount() { - this.updatedCount++; - } - - public void decrUpdatedCount() { - this.updatedCount--; - } - - public boolean isRecreatable() { - return recreatable; - } - - public void setRecreatable(boolean recreatable) { - this.recreatable = recreatable; - } - - public long getId() { - return id; - } - - public Long getPodId() { - return podId; - } - - public long getDataCenterId() { - return dataCenterId; - } - - public String getName() { - return name; - } - - public long getAccountId() { - return accountId; - } - - public void setPoolType(StoragePoolType poolType) { - this.poolType = poolType; - } - - public StoragePoolType getPoolType() { - return poolType; - } - - public long getDomainId() { - return domainId; - } - - public String getFolder() { - return folder; - } - - public String getPath() { - return path; - } - - protected VolumeVO() { - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public Long getInstanceId() { - return instanceId; - } - - public Long getDeviceId() { - return deviceId; - } - - public void setDeviceId(Long deviceId) { - this.deviceId = deviceId; - } - - public String getVolumeType() { - return volumeType; - } - - public void setName(String name) { - this.name = name; - } - - public void setFolder(String folder) { - this.folder = folder; - } - - public void setAccountId(long accountId) { - this.accountId = accountId; - } - - public void setDomainId(long domainId) { - this.domainId = domainId; - } - - public void setInstanceId(Long instanceId) { - this.instanceId = instanceId; - } - - public void setPath(String path) { - this.path = path; - } - - public String getHostIp() { - return hostip; - } - - public void setHostIp(String hostip) { - this.hostip = hostip; - } - - public void setPodId(Long podId) { - this.podId = podId; - } - - public void setDataCenterId(long dataCenterId) { - this.dataCenterId = dataCenterId; - } - - public void setVolumeType(String type) { - volumeType = type; - } - - public Date getCreated() { - return created; - } - - public Date getRemoved() { - return removed; - } - - public void setRemoved(Date removed) { - this.removed = removed; - } - - public long getDiskOfferingId() { - return diskOfferingId; - } - - public void setDiskOfferingId(long diskOfferingId) { - this.diskOfferingId = diskOfferingId; - } - - public Long getTemplateId() { - return templateId; - } - - public void setTemplateId(Long templateId) { - this.templateId = templateId; - } - - public String getFirstSnapshotBackupUuid() { - return firstSnapshotBackupUuid; - } - - public void setFirstSnapshotBackupUuid(String firstSnapshotBackupUuid) { - this.firstSnapshotBackupUuid = firstSnapshotBackupUuid; - } - - public Long getPoolId() { - return poolId; - } - - public void setPoolId(Long poolId) { - this.poolId = poolId; - } - - public Date getUpdated() { - return updated; - } - - @Override - public Volume.State getState() { - return state; - } - - public void setUpdated(Date updated) { - this.updated = updated; - } - - @Override - public String toString() { - return new StringBuilder("Vol[").append(id).append("|vm=").append(instanceId).append("|").append(volumeType).append("]").toString(); - } - - public Date getAttached() { - return this.attached; - } - - public void setAttached(Date attached) { - this.attached = attached; - } - - public String getChainInfo() { - return this.chainInfo; - } - - public void setChainInfo(String chainInfo) { - this.chainInfo = chainInfo; - } - - public Long getLastPoolId() { - return this.lastPoolId; - } - - public void setLastPoolId(Long poolId) { - this.lastPoolId = poolId; - } - - @Override - public int hashCode() { - return NumbersUtil.hash(id); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof VolumeVO) { - return id == ((VolumeVO) obj).id; - } else { - return false; - } - } - - @Override - public String getUuid() { - return this.uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public DiskFormat getDiskType() { - return diskType; - } - - public void setDiskType(DiskFormat type) { - diskType = type; - } - -} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 4a3fd3f2e05..da5e80ba6c0 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -38,6 +38,7 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; @@ -429,4 +430,9 @@ public class VolumeObject implements VolumeInfo { this.processEvent(event); } + + @Override + public ImageFormat getFormat() { + return this.volumeVO.getFormat(); + } } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 38f995930b2..9af53ee73f0 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -504,6 +504,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { newVol.setDeviceId(oldVol.getDeviceId()); newVol.setInstanceId(oldVol.getInstanceId()); newVol.setRecreatable(oldVol.isRecreatable()); + newVol.setFormat(oldVol.getFormat()); return _volsDao.persist(newVol); } @@ -690,6 +691,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { s_logger.debug("create volume failed: " + result.getResult()); throw new CloudRuntimeException("create volume failed:" + result.getResult()); } + + UsageEventVO usageEvent = new UsageEventVO( EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), @@ -732,7 +735,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { volume.setUpdated(new Date()); volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller .getDomainId()); - + volume.setFormat(ImageFormat.valueOf(format)); volume = _volsDao.persist(volume); try { stateTransitTo(volume, Event.UploadRequested); @@ -979,6 +982,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { volume.setDisplayVolume(displayVolumeEnabled); if (parentVolume != null) { volume.setTemplateId(parentVolume.getTemplateId()); + volume.setFormat(parentVolume.getFormat()); } else { volume.setTemplateId(null); } @@ -1358,7 +1362,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } else { vol.setDeviceId(1l); } - + + vol.setFormat(this.getSupportedImageFormatForCluster(vm.getHypervisorType())); vol = _volsDao.persist(vol); // Save usage event and update resource count for user vm volumes @@ -1388,6 +1393,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), size); + vol.setFormat(this.getSupportedImageFormatForCluster(template.getHypervisorType())); if (vm != null) { vol.setInstanceId(vm.getId()); } @@ -1427,17 +1433,15 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return toDiskProfile(vol, offering); } - private String getSupportedImageFormatForCluster(Long clusterId) { - ClusterVO cluster = ApiDBUtils.findClusterById(clusterId); - - 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"; + private ImageFormat getSupportedImageFormatForCluster(HypervisorType hyperType) { + if (hyperType == HypervisorType.XenServer) { + return ImageFormat.VHD; + } else if (hyperType == HypervisorType.KVM) { + return ImageFormat.QCOW2; + } else if (hyperType == HypervisorType.VMware) { + return ImageFormat.OVA; + } else if (hyperType == HypervisorType.Ovm) { + return ImageFormat.RAW; } else { return null; } @@ -1446,16 +1450,14 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { private VolumeInfo copyVolume(StoragePoolVO rootDiskPool , VolumeInfo volume, VMInstanceVO vm, VMTemplateVO rootDiskTmplt, DataCenterVO dcVO, HostPodVO pod, DiskOfferingVO diskVO, ServiceOfferingVO svo, HypervisorType rootDiskHyperType) throws NoTransitionException { - VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(volume.getDataStore().getId(), volume.getId()); - if (!volStoreVO + + if (!volume .getFormat() - .getFileExtension() .equals( - getSupportedImageFormatForCluster(rootDiskPool - .getClusterId()))) { + getSupportedImageFormatForCluster(rootDiskHyperType))) { throw new InvalidParameterValueException( "Failed to attach volume to VM since volumes format " - + volStoreVO.getFormat() + + volume.getFormat() .getFileExtension() + " is not compatible with the vm hypervisor type"); } @@ -1502,7 +1504,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { ResourceType.primary_storage, new Long(volume.getSize())); } } - return vol; + + VolumeVO volVO = this._volsDao.findById(vol.getId()); + volVO.setFormat(this.getSupportedImageFormatForCluster(rootDiskHyperType)); + this._volsDao.update(volVO.getId(), volVO); + return this.volFactory.getVolume(volVO.getId()); } private boolean needMoveVolume(VolumeVO rootVolumeOfVm, VolumeInfo volume) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 8dca6f52206..eee7e2722a3 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -290,7 +290,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if ( srcData.getObjectType() == DataObjectType.TEMPLATE){ extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension(); } else{ - extension = ((VolumeObjectTO)srcData).getDiskType().toString().toLowerCase(); + extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension(); } String templateName = UUID.randomUUID().toString(); diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index aecb93884ff..d33c070f84f 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -388,6 +388,8 @@ ALTER TABLE `cloud`.`user_vm_details` ADD COLUMN `display_detail` tinyint(1) NOT ALTER TABLE `cloud`.`volumes` ADD COLUMN `display_volume` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should volume be displayed to the end user'; +ALTER TABLE `cloud`.`volumes` ADD COLUMN `format` varchar(255) COMMENT 'volume format'; + ALTER TABLE `cloud`.`networks` ADD COLUMN `display_network` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should network be displayed to the end user'; ALTER TABLE `cloud`.`nics` ADD COLUMN `display_nic` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should nic be displayed to the end user';