mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
add volumeorchestra
This commit is contained in:
parent
2300310243
commit
cc73f2a8f2
@ -147,4 +147,14 @@ public interface Volume extends ControlledEntity, BasedOn, StateObject<Volume.St
|
||||
public void incrUpdatedCount();
|
||||
|
||||
public Date getUpdated();
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
String getReservationId();
|
||||
|
||||
/**
|
||||
* @param reserv
|
||||
*/
|
||||
void setReservationId(String reserv);
|
||||
}
|
||||
|
||||
@ -131,6 +131,9 @@ public class VolumeVO implements Volume, Identity {
|
||||
@Column(name = "uuid")
|
||||
String uuid;
|
||||
|
||||
@Column(name="reservation")
|
||||
String reservationId;
|
||||
|
||||
// Real Constructor
|
||||
public VolumeVO(Type type, String name, long dcId, long domainId, long accountId, long diskOfferingId, long size) {
|
||||
this.volumeType = type;
|
||||
@ -429,6 +432,16 @@ public class VolumeVO implements Volume, Identity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReservationId() {
|
||||
return this.reservationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReservationId(String reserv) {
|
||||
this.reservationId = reserv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return this.uuid;
|
||||
|
||||
@ -44,6 +44,7 @@ public interface DataStore {
|
||||
long getZoneId();
|
||||
StoreType getType();
|
||||
StoreScope getScope();
|
||||
boolean isSharedStorage();
|
||||
Long getId();
|
||||
DataStoreDriver getDataStoreDriver();
|
||||
DataStoreEndPointSelector getEndPointSelector();
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
package org.apache.cloudstack.platform.subsystem.api.storage;
|
||||
|
||||
import com.cloud.storage.Volume;
|
||||
|
||||
public interface VolumeStrategy {
|
||||
Volume createVolume(Volume vol);
|
||||
Volume createVolume(Volume vol, DataStore store);
|
||||
Volume copyVolume(Volume srcVol, Volume destVol);
|
||||
Volume createVolumeFromSnapshot(Volume vol, Snapshot snapshot);
|
||||
Volume createVolumeFromTemplate(Volume vol, Template template);
|
||||
Volume migrateVolume(Volume srcVol, Volume destVol);
|
||||
Volume migrateVolume(Volume srcVol, DataStore srcStore, Volume destVol, DataStore destStore);
|
||||
boolean deleteVolume(Volume vol);
|
||||
}
|
||||
|
||||
@ -20,6 +20,8 @@ package org.apache.cloudstack.storage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
|
||||
public interface StorageOrchestrator {
|
||||
|
||||
/**
|
||||
@ -27,7 +29,7 @@ public interface StorageOrchestrator {
|
||||
* @param vm
|
||||
* @param reservationId
|
||||
*/
|
||||
void prepare(String vm, String reservationId);
|
||||
void prepare(long vmId, DeploymentPlan plan, String reservationId);
|
||||
|
||||
/**
|
||||
* Releases all storage that were used for a VM shutdown
|
||||
@ -35,18 +37,23 @@ public interface StorageOrchestrator {
|
||||
* @param disks
|
||||
* @param reservationId
|
||||
*/
|
||||
void release(String vm, String reservationId);
|
||||
void release(long vmId, String reservationId);
|
||||
|
||||
/**
|
||||
* Destroy all disks
|
||||
* @param disks
|
||||
* @param reservationId
|
||||
*/
|
||||
void destroy(List<String> disks, String reservationId);
|
||||
void destroy(List<Long> disks, String reservationId);
|
||||
|
||||
/**
|
||||
* Cancel a reservation
|
||||
* @param reservationId reservation to
|
||||
*/
|
||||
void cancel(String reservationId);
|
||||
|
||||
/**
|
||||
* If attaching a volume in allocated state to a running vm, need to create this volume
|
||||
*/
|
||||
void prepareAttachDiskToVM(long diskId, long vmId, String reservationId);
|
||||
}
|
||||
|
||||
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.platform.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.platform.subsystem.api.storage.StorageProvider;
|
||||
import org.apache.cloudstack.platform.subsystem.api.storage.VolumeStrategy;
|
||||
import org.apache.cloudstack.storage.volume.VolumeManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeHostVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.dao.VolumeHostDao;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public class StorageOrchestratorImpl implements StorageOrchestrator {
|
||||
private static final Logger s_logger = Logger.getLogger(StorageOrchestratorImpl.class);
|
||||
@Inject
|
||||
StoragePoolDao _storagePoolDao;
|
||||
@Inject
|
||||
StorageProviderManager _spManager;
|
||||
@Inject
|
||||
VolumeDao _volumeDao;
|
||||
@Inject
|
||||
VMInstanceDao _vmDao;
|
||||
@Inject
|
||||
DiskOfferingDao _diskOfferingDao;
|
||||
@Inject
|
||||
VolumeHostDao _volumeHostDao;
|
||||
@Inject
|
||||
StorageProviderManager _storageProviderMgr;
|
||||
@Inject
|
||||
VolumeManager _volumeMgr;
|
||||
|
||||
protected Volume copyVolumeFromBackupStorage(VolumeVO volume, DataStore destStore, String reservationId) {
|
||||
StorageProvider sp = _storageProviderMgr.getBackupStorageProvider(volume.getDataCenterId());
|
||||
|
||||
VolumeHostVO volumeHostVO = _volumeHostDao.findByVolumeId(volume.getId());
|
||||
long poolId = volumeHostVO.getHostId();
|
||||
DataStore srcStore = _storageProviderMgr.getDataStore(poolId);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected Volume migrateVolume(VolumeVO volume, DataStore srcStore, DataStore destStore, String reservationId) throws NoTransitionException {
|
||||
VolumeStrategy vs = srcStore.getVolumeStrategy();
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
volume.setReservationId(reservationId);
|
||||
volume = _volumeMgr.processEvent(volume, Volume.Event.MigrationRequested);
|
||||
Volume destVolume = _volumeMgr.allocateDuplicateVolume(volume);
|
||||
destVolume = _volumeMgr.processEvent(destVolume, Volume.Event.CreateRequested);
|
||||
txn.commit();
|
||||
|
||||
vs.migrateVolume(volume, srcStore, destVolume, destStore);
|
||||
|
||||
txn.start();
|
||||
volume = _volumeMgr.processEvent(volume, Volume.Event.OperationSucceeded);
|
||||
destVolume = _volumeMgr.processEvent(destVolume, Volume.Event.OperationSucceeded);
|
||||
txn.commit();
|
||||
_volumeDao.remove(volume.getId());
|
||||
return destVolume;
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void prepareVolumes(List<VolumeVO> vols, Long destPoolId, String reservationId) throws NoTransitionException {
|
||||
DataStore destStore = null;
|
||||
if (destPoolId != null) {
|
||||
destStore = _storageProviderMgr.getDataStore(destPoolId);
|
||||
}
|
||||
|
||||
for (VolumeVO volume : vols) {
|
||||
if (volume.getPoolId() == null && destStore == null) {
|
||||
throw new CloudRuntimeException("Volume has no pool associate and also no storage pool assigned in DeployDestination, Unable to create.");
|
||||
}
|
||||
if (destStore == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DataStore srcStore = _storageProviderMgr.getDataStore(volume.getPoolId());
|
||||
boolean needToCreateVolume = false;
|
||||
boolean needToRecreateVolume = false;
|
||||
boolean needToMigrateVolume = false;
|
||||
boolean needToCopyFromSec = false;
|
||||
|
||||
Volume.State state = volume.getState();
|
||||
if (state == Volume.State.Allocated) {
|
||||
needToCreateVolume = true;
|
||||
} else if (state == Volume.State.UploadOp) {
|
||||
needToCopyFromSec = true;
|
||||
} else if (destStore.getId() != srcStore.getId()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Mismatch in storage pool " + destStore.getId() + " assigned by deploymentPlanner and the one associated with volume " + volume);
|
||||
}
|
||||
|
||||
if (Volume.Type.ROOT == volume.getVolumeType()) {
|
||||
needToMigrateVolume = true;
|
||||
} else {
|
||||
if (destStore.getCluterId() != srcStore.getCluterId()) {
|
||||
needToMigrateVolume = true;
|
||||
} else if (!srcStore.isSharedStorage() && srcStore.getId() != destStore.getId()) {
|
||||
needToMigrateVolume = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
VolumeStrategy vs = srcStore.getVolumeStrategy();
|
||||
if (needToCreateVolume) {
|
||||
volume.setReservationId(reservationId);
|
||||
volume = _volumeMgr.processEvent(volume, Volume.Event.CreateRequested);
|
||||
|
||||
vs.createVolume(volume, destStore);
|
||||
|
||||
volume = _volumeMgr.processEvent(volume, Volume.Event.OperationSucceeded);
|
||||
} else if (needToMigrateVolume) {
|
||||
migrateVolume(volume, srcStore, destStore, reservationId);
|
||||
} else if (needToCopyFromSec) {
|
||||
_volumeMgr.processEvent(volume, Volume.Event.CopyRequested);
|
||||
} else if (needToRecreateVolume) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void prepare(long vmId, DeploymentPlan plan, String reservationId) {
|
||||
VirtualMachine vm = _vmDao.findById(vmId);
|
||||
|
||||
|
||||
List<VolumeVO> vols = _volumeDao.findUsableVolumesForInstance(vm.getId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Prepare " + vols.size() + " volumes for " + vm.getInstanceName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void release(long vmId, String reservationId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void destroy(List<Long> disks, String reservationId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void cancel(String reservationId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void prepareAttachDiskToVM(long disk, long vm, String reservationId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,11 @@
|
||||
package org.apache.cloudstack.storage;
|
||||
|
||||
import org.apache.cloudstack.platform.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.platform.subsystem.api.storage.StorageProvider;
|
||||
|
||||
public interface StorageProviderManager {
|
||||
StorageProvider getProvider(String uuid);
|
||||
StorageProvider getProvider(long poolId);
|
||||
StorageProvider getBackupStorageProvider(long zoneId);
|
||||
DataStore getDataStore(long poolId);
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import org.apache.cloudstack.storage.filesystem.DefaultFileSystem;
|
||||
import org.apache.cloudstack.storage.lifecycle.DefaultPrimaryDataStoreLifeCycle;
|
||||
import org.apache.cloudstack.storage.strategy.XenBackupStrategy;
|
||||
import org.apache.cloudstack.storage.strategy.XenSnapshotStrategy;
|
||||
import org.apache.cloudstack.storage.strategy.XenVolumeStrategy;
|
||||
import org.apache.cloudstack.storage.strategy.DefaultVolumeStrategy;
|
||||
|
||||
import com.cloud.storage.StoragePool;
|
||||
|
||||
@ -26,7 +26,7 @@ public class XenNfsDataStoreConfigurator extends NfsDataStoreConfigurator {
|
||||
ds.setUUID(pool.getUuid());
|
||||
ds.setDataStoreDriver(new XenDataStoreDriver(ds));
|
||||
ds.setBackupStrategy(new XenBackupStrategy(ds));
|
||||
ds.setVolumeStrategy(new XenVolumeStrategy(ds));
|
||||
ds.setVolumeStrategy(new DefaultVolumeStrategy(ds));
|
||||
ds.setSnapshotStrategy(new XenSnapshotStrategy(ds));
|
||||
ds.setLifeCycle(new DefaultPrimaryDataStoreLifeCycle(ds));
|
||||
return ds;
|
||||
|
||||
@ -6,9 +6,9 @@ import org.apache.cloudstack.platform.subsystem.api.storage.Template;
|
||||
import org.apache.cloudstack.platform.subsystem.api.storage.Volume;
|
||||
import org.apache.cloudstack.platform.subsystem.api.storage.VolumeStrategy;
|
||||
|
||||
public class XenVolumeStrategy implements VolumeStrategy {
|
||||
public class DefaultVolumeStrategy implements VolumeStrategy {
|
||||
protected DataStore _ds;
|
||||
public XenVolumeStrategy(DataStore ds) {
|
||||
public DefaultVolumeStrategy(DataStore ds) {
|
||||
_ds = ds;
|
||||
}
|
||||
|
||||
@ -16,7 +16,13 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.platform.subsystem.api.storage;
|
||||
package org.apache.cloudstack.storage.volume;
|
||||
|
||||
public interface Volume extends DataObject {
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
|
||||
public interface VolumeManager {
|
||||
VolumeVO allocateDuplicateVolume(VolumeVO oldVol);
|
||||
VolumeVO processEvent(Volume vol, Volume.Event event) throws NoTransitionException;
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
|
||||
public class VolumeManagerImpl implements VolumeManager {
|
||||
private StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
|
||||
@Inject
|
||||
protected VolumeDao _volumeDao;
|
||||
|
||||
|
||||
public VolumeVO allocateDuplicateVolume(VolumeVO oldVol) {
|
||||
VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(), oldVol.getSize());
|
||||
newVol.setTemplateId(oldVol.getTemplateId());
|
||||
newVol.setDeviceId(oldVol.getDeviceId());
|
||||
newVol.setInstanceId(oldVol.getInstanceId());
|
||||
newVol.setRecreatable(oldVol.isRecreatable());
|
||||
newVol.setReservationId(oldVol.getReservationId());
|
||||
|
||||
return _volumeDao.persist(newVol);
|
||||
}
|
||||
|
||||
|
||||
public VolumeVO processEvent(Volume vol, Volume.Event event) throws NoTransitionException {
|
||||
_volStateMachine.transitTo(vol, event, null, _volumeDao);
|
||||
return _volumeDao.findById(vol.getId());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.apache.cloudstack.platform.subsystem.api.storage.Volume;
|
||||
|
||||
import com.cloud.api.commands.CreateVolumeCmd;
|
||||
|
||||
public interface VolumeService {
|
||||
/**
|
||||
* Creates the database object for a volume based on the given criteria
|
||||
*
|
||||
* @param cmd
|
||||
* @return the volume object
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
Volume allocVolumeInDB(CreateVolumeCmd cmd);
|
||||
|
||||
/**
|
||||
* Creates the volume based on the given criteria
|
||||
*
|
||||
* @param cmd
|
||||
*
|
||||
* @return the volume object
|
||||
*/
|
||||
Volume createVolume(CreateVolumeCmd cmd);
|
||||
|
||||
/**
|
||||
* Delete volume
|
||||
* @param volumeId
|
||||
* @return
|
||||
* @throws ConcurrentOperationException
|
||||
*/
|
||||
boolean deleteVolume(long volumeId);
|
||||
|
||||
/**
|
||||
* Migrate volume to another storage pool
|
||||
* @param volumeId
|
||||
* @param storagePoolId
|
||||
* @return
|
||||
* @throws ConcurrentOperationException
|
||||
*/
|
||||
Volume migrateVolume(Long volumeId, Long storagePoolId);
|
||||
|
||||
/**
|
||||
* Copy volume another storage pool, a new volume will be created on destination storage pool
|
||||
* @param volumeId
|
||||
* @param destStoragePoolId
|
||||
* @return
|
||||
*/
|
||||
Volume copyVolume(Long volumeId, Long destStoragePoolId);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user