add volumeorchestra

This commit is contained in:
Edison Su 2012-08-29 18:16:44 -07:00
parent 2300310243
commit cc73f2a8f2
12 changed files with 368 additions and 10 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -44,6 +44,7 @@ public interface DataStore {
long getZoneId();
StoreType getType();
StoreScope getScope();
boolean isSharedStorage();
Long getId();
DataStoreDriver getDataStoreDriver();
DataStoreEndPointSelector getEndPointSelector();

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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());
}
}

View File

@ -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);
}