diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java index bb74d848342..e34a3340e9e 100644 --- a/api/src/com/cloud/vm/DiskProfile.java +++ b/api/src/com/cloud/vm/DiskProfile.java @@ -34,6 +34,7 @@ public class DiskProfile { private long diskOfferingId; private Long templateId; private long volumeId; + private String path; private HypervisorType hyperType; @@ -56,6 +57,10 @@ public class DiskProfile { this(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(), offering.isCustomized(), null); this.hyperType = hyperType; } + + public DiskProfile(DiskProfile dp) { + + } /** * @return size of the disk requested in bytes. @@ -137,4 +142,16 @@ public class DiskProfile { public HypervisorType getHypersorType() { return this.hyperType; } + + public void setPath(String path) { + this.path = path; + } + + public String getPath() { + return this.path; + } + + public void setSize(long size) { + this.size = size; + } } diff --git a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStore.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStore.java index b8d4e958e04..20a16e587df 100644 --- a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStore.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStore.java @@ -18,7 +18,9 @@ */ package org.apache.cloudstack.platform.subsystem.api.storage; +import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.storage.Snapshot; +import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; @@ -46,7 +48,9 @@ public interface DataStore { long getCluterId(); long getPodId(); long getZoneId(); + String getPath(); StoreType getType(); + StoragePoolType getPoolType(); StoreScope getScope(); boolean isSharedStorage(); Long getId(); @@ -56,6 +60,7 @@ public interface DataStore { VolumeStrategy getVolumeStrategy(); SnapshotStrategy getSnapshotStrategy(); BackupStrategy getBackupStrategy(); + TemplateStrategy getTemplateStrategy(); DataStoreLifeCycle getLifeCycle(); VolumeProfile prepareVolume(Volume volume, DataStore destStore); @@ -63,6 +68,7 @@ public interface DataStore { TemplateProfile prepareTemplate(VirtualMachineTemplate template, DataStore destStore); boolean contains(Volume volume); boolean contains(Snapshot snapshot); - boolean contains(VirtualMachineTemplate template); - TemplateProfile get(VirtualMachineTemplate template); + boolean contains(TemplateProfile template); + TemplateProfile get(TemplateProfile template); + StorageFilerTO getTO(); } diff --git a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreDriver.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreDriver.java index 1b285bb71a2..61ff9675d70 100644 --- a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreDriver.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreDriver.java @@ -20,9 +20,12 @@ package org.apache.cloudstack.platform.subsystem.api.storage; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.vm.DiskProfile; public interface DataStoreDriver { String getDriverType(); + TemplateProfile install(TemplateProfile tp, DataStoreEndPoint ep); + DiskProfile createVolumeFromTemplate(DiskProfile volProfile, TemplateProfile tp, DataStoreEndPoint ep); DataObject create(DataObject obj); DataObject copy(DataObject src, DataStore dest); DataObject copy(DataObject src, DataObject dest); diff --git a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreEndPoint.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreEndPoint.java index 92f431a1923..8029424a424 100644 --- a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreEndPoint.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreEndPoint.java @@ -1,5 +1,8 @@ package org.apache.cloudstack.platform.subsystem.api.storage; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + public class DataStoreEndPoint { protected long hostId; protected String privIp; @@ -16,4 +19,8 @@ public class DataStoreEndPoint { public String getPrivateIp() { return privIp; } + + public Answer sendCommand(Command cmd) { + return new Answer(cmd); + } } diff --git a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreEndPointSelector.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreEndPointSelector.java index df6d96c8653..30b597cb5cd 100644 --- a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreEndPointSelector.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/DataStoreEndPointSelector.java @@ -3,5 +3,5 @@ package org.apache.cloudstack.platform.subsystem.api.storage; import java.util.List; public interface DataStoreEndPointSelector { - List getEndPoints(); + List getEndPoints(StorageEvent event); } diff --git a/platform/storage/src/org/apache/cloudstack/storage/manager/ImageManagerImpl.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/StorageEvent.java similarity index 84% rename from platform/storage/src/org/apache/cloudstack/storage/manager/ImageManagerImpl.java rename to platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/StorageEvent.java index ade59f00256..7ff4a76208e 100644 --- a/platform/storage/src/org/apache/cloudstack/storage/manager/ImageManagerImpl.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/StorageEvent.java @@ -16,8 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.manager; - -public class ImageManagerImpl implements ImageManager { +package org.apache.cloudstack.platform.subsystem.api.storage; +public enum StorageEvent { + DownloadTemplateToPrimary, + CreateVolumeFromTemplate; } diff --git a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/TemplateProfile.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/TemplateProfile.java index fec5de7dd22..39da9d3753b 100644 --- a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/TemplateProfile.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/TemplateProfile.java @@ -18,9 +18,55 @@ */ package org.apache.cloudstack.platform.subsystem.api.storage; +import com.cloud.storage.Storage; + public class TemplateProfile { private String _uri; + private String _imageStorageUri; + private String _localPath; + private long _id; + private long _templatePoolRefId; public String getURI() { return _uri; } + + public long getId() { + return _id; + } + + public String getLocalPath() { + return _localPath; + } + + public void setLocalPath(String path) { + _localPath = path; + } + + public void setTemplatePoolRefId(long id) { + this._templatePoolRefId = id; + } + + public long getTemplatePoolRefId() { + return this._templatePoolRefId; + } + + public String getImageStorageUri() { + return _imageStorageUri; + } + + public String getUniqueName() { + return null; + } + + public Storage.ImageFormat getFormat() { + return null; + } + + public String getInstallPath() { + return null; + } + + public long getTemplateSize() { + return 0; + } } diff --git a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/TemplateStrategy.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/TemplateStrategy.java index 01e90c5304a..a76f17d5dcc 100644 --- a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/TemplateStrategy.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/TemplateStrategy.java @@ -1,5 +1,7 @@ package org.apache.cloudstack.platform.subsystem.api.storage; public interface TemplateStrategy { - + TemplateProfile install(TemplateProfile tp); + TemplateProfile get(long templateId); + int getDownloadWait(); } diff --git a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/VolumeProfile.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/VolumeProfile.java index 8af9bc54ecb..236ebf592fb 100644 --- a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/VolumeProfile.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/VolumeProfile.java @@ -23,4 +23,12 @@ public class VolumeProfile { public String getURI() { return _uri; } + + public String getPath() { + return null; + } + + public long getSize() { + return 0; + } } diff --git a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/VolumeStrategy.java b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/VolumeStrategy.java index deea0d4bb46..207bbba0eb6 100644 --- a/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/VolumeStrategy.java +++ b/platform/api/src/org/apache/cloudstack/platform/subsystem/api/storage/VolumeStrategy.java @@ -5,12 +5,12 @@ import com.cloud.storage.Volume; public interface VolumeStrategy { Volume createVolume(Volume vol); - Volume createDataVolume(Volume vol, DataStore store); - Volume copyVolumeFromBackup(VolumeProfile srcVol, Volume destVol, DataStore destStore); - Volume createVolumeFromSnapshot(SnapshotProfile snapshot, Volume vol, DataStore destStore); - Volume createVolumeFromTemplate(TemplateProfile template, Volume vol, DataStore destStore); - Volume migrateVolume(Volume srcVol, DataStore srcStore, Volume destVol, DataStore destStore); - TemplateProfile createBaseVolume(TemplateProfile tp, DataStore destStore); - Volume createVolumeFromBaseTemplate(TemplateProfile tp, DataStore destStore); + Volume createDataVolume(Volume vol); + Volume copyVolumeFromBackup(VolumeProfile srcVol, Volume destVol); + Volume createVolumeFromSnapshot(SnapshotProfile snapshot, Volume vol); + Volume createVolumeFromTemplate(TemplateProfile template, Volume vol); + Volume migrateVolume(Volume srcVol, Volume destVol, DataStore destStore); + Volume createVolumeFromBaseTemplate(Volume destVol, TemplateProfile tp); boolean deleteVolume(Volume vol); + VolumeProfile get(long volumeId); } diff --git a/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java b/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java index 9b5ceffeff6..e53cb0bbb74 100644 --- a/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java +++ b/platform/storage/src/org/apache/cloudstack/storage/StorageOrchestratorImpl.java @@ -29,7 +29,7 @@ import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile; import org.apache.cloudstack.platform.subsystem.api.storage.VolumeStrategy; import org.apache.cloudstack.storage.db.VolumeHostVO; import org.apache.cloudstack.storage.manager.BackupStorageManager; -import org.apache.cloudstack.storage.manager.ImageManager; +import org.apache.cloudstack.storage.manager.TemplateManager; import org.apache.cloudstack.storage.manager.SecondaryStorageManager; import org.apache.cloudstack.storage.volume.VolumeManager; import org.apache.log4j.Logger; @@ -76,13 +76,13 @@ public class StorageOrchestratorImpl implements StorageOrchestrator { @Inject SecondaryStorageManager _secondaryStorageMgr; @Inject - ImageManager _imageMgr; + TemplateManager _templateMgr; @Inject VMTemplateDao _templateDao; @DB protected Volume copyVolumeFromBackupStorage(VolumeVO volume, DataStore destStore, String reservationId) throws NoTransitionException { - DataStore ds = _secondaryStorageMgr.getBackupDataStore(volume); + DataStore ds = _secondaryStorageMgr.getStore(volume); if (!ds.contains(volume)) { throw new CloudRuntimeException("volume: " + volume + "doesn't exist on backup storage"); } @@ -98,7 +98,7 @@ public class StorageOrchestratorImpl implements StorageOrchestrator { destVolume = _volumeMgr.processEvent(destVolume, Volume.Event.CreateRequested); txn.commit(); - vs.copyVolumeFromBackup(vp, destVolume, destStore); + vs.copyVolumeFromBackup(vp, destVolume); txn.start(); volume = _volumeMgr.processEvent(volume, Volume.Event.OperationSucceeded); @@ -119,7 +119,7 @@ public class StorageOrchestratorImpl implements StorageOrchestrator { txn.commit(); VolumeStrategy vs = srcStore.getVolumeStrategy(); - vs.migrateVolume(volume, srcStore, destVolume, destStore); + vs.migrateVolume(volume, destVolume, destStore); txn.start(); volume = _volumeMgr.processEvent(volume, Volume.Event.OperationSucceeded); @@ -147,7 +147,7 @@ public class StorageOrchestratorImpl implements StorageOrchestrator { DataStore srcStore = _storageProviderMgr.getDataStore(srcVolume.getPoolId()); VolumeStrategy vs = srcStore.getVolumeStrategy(); - vs.migrateVolume(srcVolume, srcStore, destVolume, destStore); + vs.migrateVolume(srcVolume, destVolume, destStore); txn.start(); srcVolume = _volumeMgr.processEvent(srcVolume, Volume.Event.OperationSucceeded); @@ -170,16 +170,17 @@ public class StorageOrchestratorImpl implements StorageOrchestrator { if (volume.getTemplateId() != null) { VirtualMachineTemplate template = _templateDao.findById(volume.getTemplateId()); - DataStore ds = _secondaryStorageMgr.getBackupDataStore(template); + DataStore ds = _secondaryStorageMgr.getImageStore(destStore); TemplateProfile tp = ds.prepareTemplate(template, destStore); - if (!destStore.contains(template)) { - tp = vs.createBaseVolume(tp, destStore); + if (!destStore.contains(tp)) { + tp = _templateMgr.AssociateTemplateStoragePool(tp, destStore); + tp = destStore.getTemplateStrategy().install(tp); } else { - tp = destStore.get(template); + tp = destStore.getTemplateStrategy().get(tp.getId()); } - volume = vs.createVolumeFromBaseTemplate(tp, destStore); + volume = vs.createVolumeFromBaseTemplate(volume, tp); } else { - volume = vs.createDataVolume(volume, destStore); + volume = vs.createDataVolume(volume); } volume = _volumeMgr.processEvent(volume, Volume.Event.OperationSucceeded); diff --git a/platform/storage/src/org/apache/cloudstack/storage/datastore/DefaultDataStore.java b/platform/storage/src/org/apache/cloudstack/storage/datastore/DefaultDataStore.java index a3e52cf9339..81c7608c1e5 100644 --- a/platform/storage/src/org/apache/cloudstack/storage/datastore/DefaultDataStore.java +++ b/platform/storage/src/org/apache/cloudstack/storage/datastore/DefaultDataStore.java @@ -7,12 +7,14 @@ import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPointSel import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.platform.subsystem.api.storage.FileSystem; import org.apache.cloudstack.platform.subsystem.api.storage.SnapshotStrategy; +import org.apache.cloudstack.platform.subsystem.api.storage.TemplateStrategy; import org.apache.cloudstack.platform.subsystem.api.storage.VolumeStrategy; public class DefaultDataStore implements DataStore { protected VolumeStrategy _volumeStrategy; protected SnapshotStrategy _snapshotStrategy; protected BackupStrategy _backupStrategy; + protected TemplateStrategy _templateStrategy; protected String _uri; protected String _uuid; protected StoreType _type; @@ -119,6 +121,14 @@ public class DefaultDataStore implements DataStore { public void setBackupStrategy(BackupStrategy bs) { this._backupSt = bs; } + + public TemplateStrategy getTemplateStrategy() { + return this._templateStrategy; + } + + public void setTemplateStrategy(TemplateStrategy ts) { + this._templateStrategy = ts; + } public DataStoreLifeCycle getLifeCycle() { return this._dslf; diff --git a/platform/storage/src/org/apache/cloudstack/storage/datastore/XenDataStoreDriver.java b/platform/storage/src/org/apache/cloudstack/storage/datastore/XenDataStoreDriver.java deleted file mode 100644 index 0c2ee37f094..00000000000 --- a/platform/storage/src/org/apache/cloudstack/storage/datastore/XenDataStoreDriver.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.apache.cloudstack.storage.datastore; - -import org.apache.cloudstack.platform.subsystem.api.storage.DataObject; -import org.apache.cloudstack.platform.subsystem.api.storage.DataStore; -import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreDriver; - -public class XenDataStoreDriver implements DataStoreDriver { - protected DataStore _ds; - public XenDataStoreDriver(DataStore ds) { - _ds = ds; - } - - public String getDriverType() { - // TODO Auto-generated method stub - return null; - } - - public DataObject create(DataObject obj) { - // TODO Auto-generated method stub - return null; - } - - public DataObject copy(DataObject src, DataStore dest) { - // TODO Auto-generated method stub - return null; - } - - public DataObject copy(DataObject src, DataObject dest) { - // TODO Auto-generated method stub - return null; - } - - public DataObject move(DataObject src, DataObject dest) { - // TODO Auto-generated method stub - return null; - } - - public boolean delete(DataObject obj) { - // TODO Auto-generated method stub - return false; - } - -} diff --git a/platform/storage/src/org/apache/cloudstack/storage/datastoreconfigurator/XenNfsDataStoreConfigurator.java b/platform/storage/src/org/apache/cloudstack/storage/datastoreconfigurator/XenNfsDataStoreConfigurator.java index 8f4993473b4..8d872a804a1 100644 --- a/platform/storage/src/org/apache/cloudstack/storage/datastoreconfigurator/XenNfsDataStoreConfigurator.java +++ b/platform/storage/src/org/apache/cloudstack/storage/datastoreconfigurator/XenNfsDataStoreConfigurator.java @@ -6,6 +6,7 @@ import org.apache.cloudstack.platform.subsystem.api.storage.DataStore; import org.apache.cloudstack.platform.subsystem.api.storage.DataStore.StoreType; import org.apache.cloudstack.storage.datastore.DefaultDataStore; import org.apache.cloudstack.storage.datastore.XenDataStoreDriver; +import org.apache.cloudstack.storage.driver.XenServerStorageDriver; import org.apache.cloudstack.storage.epselector.DefaultPrimaryEndpointSelector; import org.apache.cloudstack.storage.filesystem.DefaultFileSystem; import org.apache.cloudstack.storage.lifecycle.DefaultPrimaryDataStoreLifeCycle; @@ -24,7 +25,7 @@ public class XenNfsDataStoreConfigurator extends NfsDataStoreConfigurator { ds.setType(StoreType.Primary); ds.setURI(pool.getHostAddress() + "/" + pool.getPath()); ds.setUUID(pool.getUuid()); - ds.setDataStoreDriver(new XenDataStoreDriver(ds)); + ds.setDataStoreDriver(new XenServerStorageDriver(ds)); ds.setBackupStrategy(new XenBackupStrategy(ds)); ds.setVolumeStrategy(new DefaultVolumeStrategy(ds)); ds.setSnapshotStrategy(new XenSnapshotStrategy(ds)); diff --git a/platform/storage/src/org/apache/cloudstack/storage/driver/AbstractStorageDriver.java b/platform/storage/src/org/apache/cloudstack/storage/driver/AbstractStorageDriver.java new file mode 100644 index 00000000000..10b39c05a6e --- /dev/null +++ b/platform/storage/src/org/apache/cloudstack/storage/driver/AbstractStorageDriver.java @@ -0,0 +1,69 @@ +/* + * 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.driver; + +import org.apache.cloudstack.platform.subsystem.api.storage.DataStore; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreDriver; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPoint; +import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile; + +import org.apache.cloudstack.platform.subsystem.api.storage.TemplateProfile; +import org.apache.cloudstack.platform.subsystem.api.storage.TemplateStrategy; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.CreateAnswer; +import com.cloud.agent.api.storage.CreateCommand; +import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.vm.DiskProfile; + + + +public abstract class AbstractStorageDriver implements DataStoreDriver { + protected DataStore _ds; + protected TemplateStrategy _ts; + + public AbstractStorageDriver(DataStore ds) { + _ds = ds; + _ts = ds.getTemplateStrategy(); + } + + public TemplateProfile install(TemplateProfile tp, DataStoreEndPoint ep) { + PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(tp.getUniqueName(), tp.getURI(), tp.getFormat(), + 0, _ds.getId(), _ds.getUUID(), _ts.getDownloadWait()); + dcmd.setSecondaryStorageUrl(tp.getImageStorageUri()); + dcmd.setPrimaryStorageUrl(_ds.getURI()); + Answer asw = ep.sendCommand(dcmd); + + TemplateProfile tpn = new TemplateProfile(); + tpn.setLocalPath("/mnt/test"); + tpn.setTemplatePoolRefId(tp.getTemplatePoolRefId()); + return tpn; + } + + public DiskProfile createVolumeFromTemplate(DiskProfile volProfile, TemplateProfile tp, DataStoreEndPoint ep) { + CreateCommand cmd = new CreateCommand(volProfile, tp.getLocalPath(), _ds.getTO()); + CreateAnswer ans = (CreateAnswer)ep.sendCommand(cmd); + VolumeTO created = ans.getVolume(); + DiskProfile diskProfile = new DiskProfile(volProfile); + diskProfile.setPath(created.getPath()); + diskProfile.setSize(created.getSize()); + return diskProfile; + } +} diff --git a/platform/storage/src/org/apache/cloudstack/storage/driver/XenServerStorageDriver.java b/platform/storage/src/org/apache/cloudstack/storage/driver/XenServerStorageDriver.java new file mode 100644 index 00000000000..eb50f111700 --- /dev/null +++ b/platform/storage/src/org/apache/cloudstack/storage/driver/XenServerStorageDriver.java @@ -0,0 +1,69 @@ +/* + * 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.driver; + +import org.apache.cloudstack.platform.subsystem.api.storage.DataObject; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStore; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPoint; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class XenServerStorageDriver extends AbstractStorageDriver { + protected DataStore _ds; + public XenServerStorageDriver(DataStore ds) { + _ds = ds; + } + + public String getDriverType() { + // TODO Auto-generated method stub + return null; + } + + public DataObject create(DataObject obj) { + // TODO Auto-generated method stub + return null; + } + + public DataObject copy(DataObject src, DataStore dest) { + // TODO Auto-generated method stub + return null; + } + + public DataObject copy(DataObject src, DataObject dest) { + // TODO Auto-generated method stub + return null; + } + + public DataObject move(DataObject src, DataObject dest) { + // TODO Auto-generated method stub + return null; + } + + public Answer sendMessage(DataStoreEndPoint dsep, Command cmd) { + // TODO Auto-generated method stub + return null; + } + + public boolean delete(DataObject obj) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/platform/storage/src/org/apache/cloudstack/storage/manager/SecondaryStorageManager.java b/platform/storage/src/org/apache/cloudstack/storage/manager/SecondaryStorageManager.java index 8fa1a957b69..2a80a963a87 100644 --- a/platform/storage/src/org/apache/cloudstack/storage/manager/SecondaryStorageManager.java +++ b/platform/storage/src/org/apache/cloudstack/storage/manager/SecondaryStorageManager.java @@ -18,6 +18,14 @@ */ package org.apache.cloudstack.storage.manager; -public interface SecondaryStorageManager { +import org.apache.cloudstack.platform.subsystem.api.storage.DataStore; +import com.cloud.storage.Snapshot; +import com.cloud.storage.Volume; +import com.cloud.template.VirtualMachineTemplate; + +public interface SecondaryStorageManager { + DataStore getStore(Volume volume); + DataStore getImageStore(DataStore destStore); + DataStore getStore(Snapshot snapshot); } diff --git a/platform/storage/src/org/apache/cloudstack/storage/manager/ImageManager.java b/platform/storage/src/org/apache/cloudstack/storage/manager/TemplateManager.java similarity index 83% rename from platform/storage/src/org/apache/cloudstack/storage/manager/ImageManager.java rename to platform/storage/src/org/apache/cloudstack/storage/manager/TemplateManager.java index 81fe391ee89..916d795f26e 100644 --- a/platform/storage/src/org/apache/cloudstack/storage/manager/ImageManager.java +++ b/platform/storage/src/org/apache/cloudstack/storage/manager/TemplateManager.java @@ -27,8 +27,7 @@ import com.cloud.storage.Snapshot; import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; -public interface ImageManager { - VolumeProfile prepareVolume(Volume volume, DataStore destStore); - SnapshotProfile prepareSnapshot(Snapshot snapshot, DataStore destStore); - TemplateProfile prepareTemplate(VirtualMachineTemplate template, DataStore destStore); +public interface TemplateManager { + TemplateProfile AssociateTemplateStoragePool(TemplateProfile tp, DataStore ds); + TemplateProfile getProfile(long templateId); } diff --git a/platform/storage/src/org/apache/cloudstack/storage/manager/TemplateManagerImpl.java b/platform/storage/src/org/apache/cloudstack/storage/manager/TemplateManagerImpl.java new file mode 100644 index 00000000000..ba9cf0ffdea --- /dev/null +++ b/platform/storage/src/org/apache/cloudstack/storage/manager/TemplateManagerImpl.java @@ -0,0 +1,91 @@ +/* + * 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.manager; + +import org.apache.cloudstack.platform.subsystem.api.storage.DataStore; +import org.apache.cloudstack.platform.subsystem.api.storage.TemplateProfile; +import org.apache.log4j.Logger; + +import com.cloud.storage.VMTemplateHostVO; +import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VMTemplatePoolDao; +import com.cloud.template.VirtualMachineTemplate; +import com.cloud.utils.component.Inject; +import com.cloud.utils.exception.CloudRuntimeException; + +public class TemplateManagerImpl implements TemplateManager { + private static final Logger s_logger = Logger.getLogger(TemplateManagerImpl.class); + @Inject + VMTemplateDao _templateDao; + @Inject + VMTemplatePoolDao _templatePoolDao; + + public boolean contains(VirtualMachineTemplate template, DataStore ds) { + long templateId = template.getId(); + long poolId = ds.getId(); + VMTemplateStoragePoolVO templateStoragePoolRef = null; + templateStoragePoolRef = _templatePoolDao.findByPoolTemplate(poolId, templateId); + return templateStoragePoolRef == null ? false : true; + } + + public TemplateProfile AssociateTemplateStoragePool(TemplateProfile tp, DataStore ds) { + long templateId = tp.getId(); + long poolId = ds.getId(); + VMTemplateStoragePoolVO templateStoragePoolRef = null; + long templateStoragePoolRefId; + + templateStoragePoolRef = _templatePoolDao.findByPoolTemplate(poolId, templateId); + if (templateStoragePoolRef != null) { + templateStoragePoolRef.setMarkedForGC(false); + _templatePoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef); + + if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId); + } + + tp.setLocalPath(templateStoragePoolRef.getInstallPath()); + tp.setTemplatePoolRefId(templateStoragePoolRef.getId()); + return tp; + } + } + + if (templateStoragePoolRef == null) { + templateStoragePoolRef = new VMTemplateStoragePoolVO(poolId, templateId); + try { + templateStoragePoolRef = _templatePoolDao.persist(templateStoragePoolRef); + templateStoragePoolRefId = templateStoragePoolRef.getId(); + } catch (Exception e) { + s_logger.debug("Assuming we're in a race condition: " + e.getMessage()); + templateStoragePoolRef = _templatePoolDao.findByPoolTemplate(poolId, templateId); + if (templateStoragePoolRef == null) { + throw new CloudRuntimeException("Unable to persist a reference for pool " + poolId + " and template " + templateId); + } + templateStoragePoolRefId = templateStoragePoolRef.getId(); + } + } else { + templateStoragePoolRefId = templateStoragePoolRef.getId(); + } + tp.setTemplatePoolRefId(templateStoragePoolRefId); + return tp; + } +} diff --git a/platform/storage/src/org/apache/cloudstack/storage/strategy/DefaultTemplateStratey.java b/platform/storage/src/org/apache/cloudstack/storage/strategy/DefaultTemplateStratey.java new file mode 100644 index 00000000000..e5701a1199d --- /dev/null +++ b/platform/storage/src/org/apache/cloudstack/storage/strategy/DefaultTemplateStratey.java @@ -0,0 +1,98 @@ +/* + * 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.strategy; + +import java.util.Collections; +import java.util.List; + +import org.apache.cloudstack.platform.subsystem.api.storage.DataStore; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreDriver; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPoint; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPointSelector; +import org.apache.cloudstack.platform.subsystem.api.storage.StorageEvent; +import org.apache.cloudstack.platform.subsystem.api.storage.TemplateProfile; +import org.apache.cloudstack.platform.subsystem.api.storage.TemplateStrategy; +import org.apache.cloudstack.storage.manager.TemplateManager; +import org.apache.log4j.Logger; + +import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.dao.VMTemplatePoolDao; +import com.cloud.utils.component.Inject; +import com.cloud.utils.exception.CloudRuntimeException; + +public class DefaultTemplateStratey implements TemplateStrategy { + private static final Logger s_logger = Logger.getLogger(DefaultTemplateStratey.class); + protected DataStore _ds; + protected DataStoreDriver _driver; + protected int _primaryStorageDownloadWait; + protected int _installTries = 3; + protected int _storagePoolMaxWaitSeconds = 3600; + @Inject + VMTemplatePoolDao _templatePoolDao; + @Inject + TemplateManager _templateMgr; + + public TemplateProfile get(long templateId) { + return _templateMgr.getProfile(templateId); + } + + public TemplateProfile install(TemplateProfile tp) { + DataStoreEndPointSelector dseps = _ds.getEndPointSelector(); + List eps = dseps.getEndPoints(StorageEvent.DownloadTemplateToPrimary); + int tries = Math.min(eps.size(), _installTries); + + VMTemplateStoragePoolVO templateStoragePoolRef = _templatePoolDao.acquireInLockTable(tp.getTemplatePoolRefId(), _storagePoolMaxWaitSeconds); + if (templateStoragePoolRef == null) { + throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + tp.getTemplatePoolRefId()); + } + + try { + for (int retry = 0; retry < tries; retry++) { + Collections.shuffle(eps); + DataStoreEndPoint ep = eps.get(0); + try { + tp = _driver.install(tp, ep); + templateStoragePoolRef.setDownloadPercent(100); + templateStoragePoolRef.setDownloadState(Status.DOWNLOADED); + templateStoragePoolRef.setLocalDownloadPath(tp.getInstallPath()); + templateStoragePoolRef.setInstallPath(tp.getInstallPath()); + templateStoragePoolRef.setTemplateSize(tp.getTemplateSize()); + _templatePoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Template " + tp.getId() + " is installed via " + ep.getHostId()); + } + return get(tp.getId()); + } catch (CloudRuntimeException e) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Template " + tp.getId() + " download to pool " + _ds.getId() + " failed due to " + e.toString()); + } + } + } + } finally { + _templatePoolDao.releaseFromLockTable(tp.getTemplatePoolRefId()); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Template " + tp.getId() + " is not found on and can not be downloaded to pool " + _ds.getId()); + } + return null; + } + +} diff --git a/platform/storage/src/org/apache/cloudstack/storage/strategy/DefaultVolumeStrategy.java b/platform/storage/src/org/apache/cloudstack/storage/strategy/DefaultVolumeStrategy.java index 9e11b44b8c8..35e284f1c70 100644 --- a/platform/storage/src/org/apache/cloudstack/storage/strategy/DefaultVolumeStrategy.java +++ b/platform/storage/src/org/apache/cloudstack/storage/strategy/DefaultVolumeStrategy.java @@ -1,56 +1,90 @@ package org.apache.cloudstack.storage.strategy; +import java.util.List; + import org.apache.cloudstack.platform.subsystem.api.storage.DataStore; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreDriver; + +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPoint; +import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPointSelector; import org.apache.cloudstack.platform.subsystem.api.storage.SnapshotProfile; +import org.apache.cloudstack.platform.subsystem.api.storage.StorageEvent; import org.apache.cloudstack.platform.subsystem.api.storage.TemplateProfile; import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile; import org.apache.cloudstack.platform.subsystem.api.storage.VolumeStrategy; +import org.apache.cloudstack.storage.volume.VolumeManager; + +import org.apache.log4j.Logger; + import com.cloud.storage.Volume; +import com.cloud.storage.VolumeVO; +import com.cloud.utils.component.Inject; + public class DefaultVolumeStrategy implements VolumeStrategy { + private static final Logger s_logger = Logger.getLogger(DefaultVolumeStrategy.class); protected DataStore _ds; + protected DataStoreDriver _driver; + @Inject + VolumeManager _volumeMgr; + + public VolumeProfile get(long volumeId) { + return _volumeMgr.getProfile(volumeId); + } + public DefaultVolumeStrategy(DataStore ds) { _ds = ds; } - public Volume createVolume(Volume vol) { // TODO Auto-generated method stub return null; } - public Volume createDataVolume(Volume vol, DataStore store) { + public Volume createDataVolume(Volume vol) { // TODO Auto-generated method stub return null; } - public Volume copyVolumeFromBackup(VolumeProfile srcVol, Volume destVol, DataStore destStore) { + public Volume copyVolumeFromBackup(VolumeProfile srcVol, Volume destVol) { // TODO Auto-generated method stub return null; } - public Volume createVolumeFromSnapshot(SnapshotProfile snapshot, Volume vol, DataStore destStore) { + public Volume createVolumeFromSnapshot(SnapshotProfile snapshot, Volume vol) { // TODO Auto-generated method stub return null; } - public Volume createVolumeFromTemplate(TemplateProfile template, Volume vol, DataStore destStore) { + public Volume createVolumeFromTemplate(TemplateProfile template, Volume vol) { // TODO Auto-generated method stub return null; } - public Volume migrateVolume(Volume srcVol, DataStore srcStore, Volume destVol, DataStore destStore) { + public Volume migrateVolume(Volume srcVol, Volume destVol, DataStore destStore) { // TODO Auto-generated method stub return null; } - public TemplateProfile createBaseVolume(TemplateProfile tp, DataStore destStore) { - // TODO Auto-generated method stub - return null; - } - public Volume createVolumeFromBaseTemplate(TemplateProfile tp, DataStore destStore) { - // TODO Auto-generated method stub - return null; + + public Volume createVolumeFromBaseTemplate(Volume volume, TemplateProfile tp) { + DataStoreEndPointSelector dsep = _ds.getEndPointSelector(); + List dseps = dsep.getEndPoints(StorageEvent.CreateVolumeFromTemplate); + DataStoreEndPoint dp = dseps.get(0); + + VolumeProfile vp = _driver.createVolumeFromTemplate(get(volume.getId()), tp, dp); + + VolumeVO vlvo = _volumeMgr.getVolume(volume.getId()); + + vlvo.setFolder(_ds.getPath()); + vlvo.setPath(vp.getPath()); + vlvo.setSize(vp.getSize()); + vlvo.setPoolType(_ds.getPoolType()); + vlvo.setPoolId(_ds.getId()); + vlvo.setPodId(_ds.getPodId()); + + return _volumeMgr.updateVolume(vlvo); } public boolean deleteVolume(Volume vol) { // TODO Auto-generated method stub return false; } - + + } diff --git a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManager.java b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManager.java index 625f305922a..1b4bc93d75d 100644 --- a/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManager.java +++ b/platform/storage/src/org/apache/cloudstack/storage/volume/VolumeManager.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.storage.volume; +import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile; + import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.utils.fsm.NoTransitionException; @@ -25,4 +27,7 @@ import com.cloud.utils.fsm.NoTransitionException; public interface VolumeManager { VolumeVO allocateDuplicateVolume(VolumeVO oldVol); VolumeVO processEvent(Volume vol, Volume.Event event) throws NoTransitionException; + VolumeProfile getProfile(long volumeId); + VolumeVO getVolume(long volumeId); + VolumeVO updateVolume(VolumeVO volume); }