Updated Branches: refs/heads/javelin aa7b3e0f6 -> e4e2cf6be
add image create test case Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/c921118c Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/c921118c Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/c921118c Branch: refs/heads/javelin Commit: c921118c5800a2bc326c2dda24a0934ce03f80a8 Parents: aa7b3e0 Author: Edison Su <edison...@citrix.com> Authored: Tue Jan 22 11:20:03 2013 -0800 Committer: Edison Su <edison...@citrix.com> Committed: Tue Jan 22 13:25:48 2013 -0800 ---------------------------------------------------------------------- .../subsystem/api/storage/CreateCmdResult.java | 8 ++- .../engine/subsystem/api/storage/DataObject.java | 2 +- .../engine/subsystem/api/storage/ScopeType.java | 4 +- .../storage/image/ImageDataFactoryImpl.java | 10 +++- .../cloudstack/storage/image/ImageServiceImpl.java | 5 ++ .../driver/DefaultImageDataStoreDriverImpl.java | 28 ++++++++- .../image/manager/ImageDataManagerImpl.java | 4 +- .../storage/image/store/HttpDataStoreImpl.java | 17 +++-- .../storage/image/store/TemplateObject.java | 21 ++++-- .../lifecycle/DefaultImageDataStoreLifeCycle.java | 12 +++- .../cloudstack/storage/test/volumeServiceTest.java | 46 +++++++++++++- .../storage/snapshot/SnapshotObject.java | 4 +- .../storage/command/CreateObjectAnswer.java | 48 +++++++++++++++ .../storage/command/CreateVolumeAnswer.java | 43 ------------- .../storage/db/ObjectInDataStoreDaoImpl.java | 43 ++++++++++++- .../cloudstack/storage/db/ObjectInDataStoreVO.java | 36 ++++++++++- .../storage/endpoint/DefaultEndPointSelector.java | 6 ++- .../image/datastore/ImageDataStoreHelper.java | 9 +++- .../storage/image/db/ImageDataStoreVO.java | 28 +++++++++ .../cloudstack/storage/image/db/ImageDataVO.java | 3 +- .../driver/DefaultPrimaryDataStoreDriverImpl.java | 8 +- .../cloudstack/storage/volume/VolumeObject.java | 2 +- .../xen/resource/XenServerStorageResource.java | 23 +++++-- .../apache/cloudstack/storage/test/VolumeTest.java | 4 +- setup/db/4.1-new-db-schema.sql | 34 ++++++++-- 25 files changed, 347 insertions(+), 101 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java ---------------------------------------------------------------------- diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java index 8934416..b6d5b68 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java @@ -20,12 +20,18 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public class CreateCmdResult extends CommandResult { private String path; - public CreateCmdResult(String path) { + private Long size; + public CreateCmdResult(String path, Long size) { super(); this.path = path; + this.size = size; } public String getPath() { return this.path; } + + public Long getSize() { + return this.size; + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java ---------------------------------------------------------------------- diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java index 1732ec1..812db48 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java @@ -24,7 +24,7 @@ public interface DataObject { public long getId(); public String getUri(); public DataStore getDataStore(); - public long getSize(); + public Long getSize(); public DataObjectType getType(); public DiskFormat getFormat(); public String getUuid(); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ScopeType.java ---------------------------------------------------------------------- diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ScopeType.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ScopeType.java index d1606e1..a3d21ce 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ScopeType.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ScopeType.java @@ -21,5 +21,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public enum ScopeType { HOST, CLUSTER, - ZONE; + ZONE, + REGION, + GLOBAL; } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java index ea25b7c..b6a45b5 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java @@ -40,11 +40,17 @@ public class ImageDataFactoryImpl implements ImageDataFactory { DataStoreManager storeMgr; @Override public TemplateInfo getTemplate(long templateId, DataStore store) { + ImageDataVO templ = imageDataDao.findById(templateId); + if (store == null) { + TemplateObject tmpl = TemplateObject.getTemplate(templ, null); + return tmpl; + } ObjectInDataStoreVO obj = objMap.findObject(templateId, DataObjectType.TEMPLATE, store.getId(), store.getRole()); if (obj == null) { - return null; + TemplateObject tmpl = TemplateObject.getTemplate(templ, null); + return tmpl; } - ImageDataVO templ = imageDataDao.findById(templateId); + TemplateObject tmpl = TemplateObject.getTemplate(templ, store); return tmpl; } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java index 99b57e8..b1e2a60 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java @@ -78,6 +78,7 @@ public class ImageServiceImpl implements ImageService { TemplateInfo templateOnStore = null; if (obj == null) { templateOnStore = objectInDataStoreMgr.create(template, store); + obj = objectInDataStoreMgr.findObject(template.getId(), template.getType(), store.getId(), store.getRole()); } else { CommandResult result = new CommandResult(); result.setResult("duplicate template on the storage"); @@ -128,6 +129,10 @@ public class ImageServiceImpl implements ImageService { ObjectInDataStoreVO obj = context.obj; obj.setInstallPath(callbackResult.getPath()); + if (callbackResult.getSize() != null) { + obj.setSize(callbackResult.getSize()); + } + try { objectInDataStoreMgr.update(templateOnStore, Event.OperationSuccessed); } catch (NoTransitionException e) { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java index 8c83ff2..b713fa6 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java @@ -20,6 +20,8 @@ package org.apache.cloudstack.storage.image.driver; import java.util.Set; +import javax.inject.Inject; + import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -28,11 +30,15 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.endpoint.EndPointSelector; import org.apache.cloudstack.storage.image.ImageDataStoreDriver; //http-read-only based image store public class DefaultImageDataStoreDriverImpl implements ImageDataStoreDriver { - + @Inject + EndPointSelector selector; public DefaultImageDataStoreDriverImpl() { } @@ -57,10 +63,28 @@ public class DefaultImageDataStoreDriverImpl implements ImageDataStoreDriver { public void createAsync(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) { //for default http data store, can create http based template/iso - CreateCmdResult result = new CreateCmdResult(""); + CreateCmdResult result = new CreateCmdResult("", null); if (!data.getUri().startsWith("http")) { result.setResult("can't register an image which is not a http link"); callback.complete(result); + return; + } + + if (data.getSize() == null && data.getType() == DataObjectType.TEMPLATE) { + //the template size is unknown during registration, need to find out the size of template + EndPoint ep = selector.select(data); + if (ep == null) { + result.setResult("can't find storage client for:" + data.getId() + "," + data.getType()); + callback.complete(result); + return; + } + CreateObjectCommand createCmd = new CreateObjectCommand(data.getUri()); + CreateObjectAnswer answer = (CreateObjectAnswer)ep.sendMessage(createCmd); + if (answer.getResult()) { + result = new CreateCmdResult(answer.getPath(), answer.getSize()); + } else { + result.setResult(answer.getDetails()); + } } callback.complete(result); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java index 09303aa..d90f2b6 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java @@ -21,11 +21,13 @@ package org.apache.cloudstack.storage.image.manager; import org.apache.cloudstack.storage.image.TemplateEvent; import org.apache.cloudstack.storage.image.TemplateState; import org.apache.cloudstack.storage.image.db.ImageDataVO; +import org.springframework.stereotype.Component; import com.cloud.utils.fsm.StateMachine2; +@Component public class ImageDataManagerImpl implements ImageDataManager { - private final static StateMachine2<TemplateState, TemplateEvent, ImageDataVO> + private final StateMachine2<TemplateState, TemplateEvent, ImageDataVO> stateMachine = new StateMachine2<TemplateState, TemplateEvent, ImageDataVO>(); public ImageDataManagerImpl() { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/image/src/org/apache/cloudstack/storage/image/store/HttpDataStoreImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/HttpDataStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/HttpDataStoreImpl.java index 1c135a8..e1fdd3d 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/HttpDataStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/HttpDataStoreImpl.java @@ -45,12 +45,16 @@ public class HttpDataStoreImpl implements ImageDataStore { ImageDataDao imageDao; @Inject private ObjectInDataStoreManager objectInStoreMgr; - ImageDataStoreDriver driver; - ImageDataStoreVO imageDataStoreVO; - ImageDataStoreProvider provider; + protected ImageDataStoreDriver driver; + protected ImageDataStoreVO imageDataStoreVO; + protected ImageDataStoreProvider provider; boolean needDownloadToCacheStorage = false; - private HttpDataStoreImpl(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver, + protected HttpDataStoreImpl() { + + } + + protected void configure(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver, ImageDataStoreProvider provider) { this.driver = imageDataStoreDriver; this.imageDataStoreVO = dataStoreVO; @@ -59,8 +63,9 @@ public class HttpDataStoreImpl implements ImageDataStore { public static HttpDataStoreImpl getDataStore(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver, ImageDataStoreProvider provider) { - HttpDataStoreImpl instance = new HttpDataStoreImpl(dataStoreVO, imageDataStoreDriver, provider); - return ComponentContext.inject(instance); + HttpDataStoreImpl instance = (HttpDataStoreImpl)ComponentContext.inject(HttpDataStoreImpl.class); + instance.configure(dataStoreVO, imageDataStoreDriver, provider); + return instance; } @Override http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java ---------------------------------------------------------------------- diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index fb4f9ca..f926a66 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -49,14 +49,18 @@ public class TemplateObject implements TemplateInfo { @Inject ObjectInDataStoreManager ojbectInStoreMgr; - private TemplateObject(ImageDataVO template, DataStore dataStore) { + protected TemplateObject() { + } + + protected void configure(ImageDataVO template, DataStore dataStore) { this.imageVO = template; this.dataStore = dataStore; } public static TemplateObject getTemplate(ImageDataVO vo, DataStore store) { - TemplateObject to = new TemplateObject(vo, store); - return ComponentContext.inject(to); + TemplateObject to = ComponentContext.inject(TemplateObject.class); + to.configure(vo, store); + return to; } public void setImageStoreId(long id) { @@ -90,7 +94,7 @@ public class TemplateObject implements TemplateInfo { } else { ObjectInDataStoreVO obj = ojbectInStoreMgr.findObject(this.imageVO.getId(), DataObjectType.TEMPLATE, this.dataStore.getId(), this.dataStore.getRole()); if (obj.getState() != ObjectInDataStoreStateMachine.State.Ready) { - return this.dataStore.getUri() + File.separator + "&objType=" + DataObjectType.TEMPLATE + "&size=" + this.imageVO.getSize(); + return this.dataStore.getUri() + File.separator + "&objType=" + DataObjectType.TEMPLATE + "&size=" + this.imageVO.getSize() + "&path=" + this.imageVO.getUrl(); } else { return this.dataStore.getUri() + File.separator + "&objType=" + DataObjectType.TEMPLATE + "&path=" + obj.getInstallPath(); } @@ -98,9 +102,12 @@ public class TemplateObject implements TemplateInfo { } @Override - public long getSize() { - // TODO Auto-generated method stub - return 0; + public Long getSize() { + if (this.dataStore == null) { + return null; + } + ObjectInDataStoreVO obj = ojbectInStoreMgr.findObject(this.imageVO.getId(), DataObjectType.TEMPLATE, this.dataStore.getId(), this.dataStore.getRole()); + return obj.getSize(); } @Override http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java ---------------------------------------------------------------------- diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java index 9189963..07d52b4 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java @@ -23,20 +23,26 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; +import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; public class DefaultImageDataStoreLifeCycle implements ImageDataStoreLifeCycle { @Inject protected ImageDataStoreDao imageStoreDao; - + @Inject + ImageDataStoreHelper imageStoreHelper; + @Inject + ImageDataStoreManager imageStoreMgr; public DefaultImageDataStoreLifeCycle() { } @Override public DataStore initialize(Map<String, String> dsInfos) { - // TODO Auto-generated method stub - return null; + ImageDataStoreVO ids = imageStoreHelper.createImageDataStore(dsInfos); + return imageStoreMgr.getImageDataStore(ids.getId()); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java ---------------------------------------------------------------------- diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 0d4a540..eeb7b54 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -32,19 +32,25 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity; import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; +import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.HypervisorHostEndPoint; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO; import org.apache.cloudstack.storage.datastore.provider.DataStoreProvider; import org.apache.cloudstack.storage.datastore.provider.DataStoreProviderManager; import org.apache.cloudstack.storage.endpoint.EndPointSelector; +import org.apache.cloudstack.storage.image.ImageDataFactory; import org.apache.cloudstack.storage.image.ImageService; +import org.apache.cloudstack.storage.image.TemplateInfo; import org.apache.cloudstack.storage.image.db.ImageDataDao; import org.apache.cloudstack.storage.image.db.ImageDataVO; import org.apache.cloudstack.storage.volume.VolumeService; @@ -52,6 +58,7 @@ import org.apache.cloudstack.storage.volume.db.VolumeDao2; import org.apache.cloudstack.storage.volume.db.VolumeVO; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; +import org.testng.Assert; import org.testng.annotations.Test; import com.cloud.agent.AgentManager; @@ -69,6 +76,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster.ClusterType; import com.cloud.org.Managed.ManagedState; import com.cloud.resource.ResourceState; +import com.cloud.storage.Storage; import com.cloud.storage.Storage.TemplateType; @ContextConfiguration(locations={"classpath:/storageContext.xml"}) @@ -99,6 +107,8 @@ public class volumeServiceTest extends CloudStackTestNGBase { AgentManager agentMgr; @Inject EndPointSelector selector; + @Inject + ImageDataFactory imageDataFactory; Long dcId; Long clusterId; Long podId; @@ -188,6 +198,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { eps.add(HypervisorHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress())); Mockito.when(selector.selectAll(Mockito.any(DataStore.class))).thenReturn(eps); + Mockito.when(selector.select(Mockito.any(DataObject.class))).thenReturn(eps.get(0)); } private ImageDataVO createImageData() { @@ -200,7 +211,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { image.setFeatured(true); image.setRequireHvm(true); image.setBits(64); - //image.setFormat(new VHD().toString()); + image.setFormat(Storage.ImageFormat.VHD.toString()); image.setAccountId(1); image.setEnablePassword(true); image.setEnableSshKey(true); @@ -209,12 +220,20 @@ public class volumeServiceTest extends CloudStackTestNGBase { image.setPrepopulate(true); image.setCrossZones(true); image.setExtractable(true); + + //image.setImageDataStoreId(storeId); image = imageDataDao.persist(image); + return image; } private TemplateEntity createTemplate() { try { + DataStore store = createImageStore(); + ImageDataVO image = createImageData(); + TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store); + AsyncCallFuture<CommandResult> future = imageService.createTemplateAsync(template, store); + future.get(); /*imageProviderMgr.configure("image Provider", new HashMap<String, Object>()); ImageDataVO image = createImageData(); ImageDataStoreProvider defaultProvider = imageProviderMgr.getProvider("DefaultProvider"); @@ -225,15 +244,17 @@ public class volumeServiceTest extends CloudStackTestNGBase { return te;*/ return null; } catch (Exception e) { - return null; + Assert.fail("failed", e); + return null; } } + @Test public void createTemplateTest() { createTemplate(); } - @Test + //@Test public void testCreatePrimaryStorage() { DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default primary data store provider"); Map<String, String> params = new HashMap<String, String>(); @@ -261,6 +282,25 @@ public class volumeServiceTest extends CloudStackTestNGBase { ClusterScope scope = new ClusterScope(clusterId, podId, dcId); lifeCycle.attachCluster(store, scope); } + + private DataStore createImageStore() { + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default image data store"); + Map<String, String> params = new HashMap<String, String>(); + String name = UUID.randomUUID().toString(); + params.put("name", name); + params.put("uuid", name); + params.put("protocol", "http"); + params.put("scope", ScopeType.GLOBAL.toString()); + params.put("provider", Long.toString(provider.getId())); + DataStoreLifeCycle lifeCycle = provider.getLifeCycle(); + DataStore store = lifeCycle.initialize(params); + return store; + } + @Test + public void testcreateImageStore() { + createImageStore(); + } + @Test public PrimaryDataStoreInfo createPrimaryDataStore() { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java ---------------------------------------------------------------------- diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index 8c04843..6ce1797 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -74,9 +74,9 @@ public class SnapshotObject implements SnapshotInfo { } @Override - public long getSize() { + public Long getSize() { // TODO Auto-generated method stub - return 0; + return 0L; } @Override http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java new file mode 100644 index 0000000..43540de --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java @@ -0,0 +1,48 @@ +/* + * 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.command; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class CreateObjectAnswer extends Answer { + private String path; + private Long size; + protected CreateObjectAnswer() { + super(); + } + + public CreateObjectAnswer(Command cmd, String path, Long size) { + super(cmd); + this.path = path; + this.size = size; + } + + public CreateObjectAnswer(Command cmd, boolean status, String result) { + super(cmd, status, result); + } + + public String getPath() { + return this.path; + } + + public Long getSize() { + return this.size; + } +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeAnswer.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeAnswer.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeAnswer.java deleted file mode 100644 index 42674de..0000000 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeAnswer.java +++ /dev/null @@ -1,43 +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.command; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; - -public class CreateVolumeAnswer extends Answer { - private String volumeUuid; - - protected CreateVolumeAnswer() { - super(); - } - - public CreateVolumeAnswer(Command cmd, String volumeUuid) { - super(cmd); - this.volumeUuid = volumeUuid; - } - - public CreateVolumeAnswer(Command cmd, boolean status, String result) { - super(cmd, status, result); - } - - public String getVolumeUuid() { - return this.volumeUuid; - } -} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java index ac75a9a..7bd9f58 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java @@ -15,21 +15,58 @@ // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.storage.db; +import java.util.Date; + import org.springframework.stereotype.Component; import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.State; +import org.apache.cloudstack.storage.volume.db.VolumeVO; +import org.apache.log4j.Logger; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; +import com.cloud.utils.db.UpdateBuilder; @Component public class ObjectInDataStoreDaoImpl extends GenericDaoBase<ObjectInDataStoreVO, Long> implements ObjectInDataStoreDao { - + private static final Logger s_logger = Logger.getLogger(ObjectInDataStoreDaoImpl.class); @Override public boolean updateState(State currentState, Event event, State nextState, ObjectInDataStoreVO vo, Object data) { - // TODO Auto-generated method stub - return false; + Long oldUpdated = vo.getUpdatedCount(); + Date oldUpdatedTime = vo.getUpdated(); + + SearchCriteria<ObjectInDataStoreVO> sc = this.createSearchCriteria(); + 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((ObjectInDataStoreVO) vo, sc); + if (rows == 0 && s_logger.isDebugEnabled()) { + ObjectInDataStoreVO 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 objectIndatastore: id=" + vo.getId() + ", as there is no such object exists in the database anymore"); + } + } + return rows > 0; } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java index 91506e4..e208d40 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java @@ -51,7 +51,7 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa @Enumerated(EnumType.STRING) private DataStoreRole dataStoreRole; - @Column(name = "ojbect_id") + @Column(name = "object_id") long objectId; @Column(name = "object_type") @@ -85,7 +85,7 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa String installPath; @Column(name = "size") - long size; + Long size; @Column(name = "state") @Enumerated(EnumType.STRING) @@ -94,6 +94,10 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa @Column(name="update_count", updatable = true, nullable=false) protected long updatedCount; + @Column(name = "updated") + @Temporal(value = TemporalType.TIMESTAMP) + Date updated; + public ObjectInDataStoreVO() { this.state = ObjectInDataStoreStateMachine.State.Allocated; } @@ -146,4 +150,32 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa public String getInstallPath() { return this.installPath; } + + public void setSize(Long size) { + this.size = size; + } + + public Long getSize() { + return this.size; + } + + public long getUpdatedCount() { + return this.updatedCount; + } + + public void incrUpdatedCount() { + this.updatedCount++; + } + + public void decrUpdatedCount() { + this.updatedCount--; + } + + public Date getUpdated() { + return updated; + } + + public void setUpdated(Date updated) { + this.updated = updated; + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index d45aa72..c385abe 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -165,7 +165,11 @@ public class DefaultEndPointSelector implements EndPointSelector { DataStore store = object.getDataStore(); if (store.getRole() == DataStoreRole.Primary) { return findEndpointForPrimaryStorage(store); - } else { + } else if (store.getRole() == DataStoreRole.Image) { + //in case there is no ssvm, directly send down command hypervisor host + //TODO: add code to handle in case ssvm is there + return findEndpointForPrimaryStorage(store); + }else { throw new CloudRuntimeException("not implemented yet"); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java index e888192..0d4a566 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java @@ -22,6 +22,7 @@ import java.util.Map; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; import org.springframework.stereotype.Component; @@ -33,10 +34,16 @@ public class ImageDataStoreHelper { @Inject ImageDataStoreDao imageStoreDao; public ImageDataStoreVO createImageDataStore(Map<String, String> params) { - ImageDataStoreVO store = new ImageDataStoreVO(); + ImageDataStoreVO store = imageStoreDao.findByUuid(params.get("uuid")); + if (store != null) { + throw new CloudRuntimeException("duplicate uuid"); + } + store = new ImageDataStoreVO(); store.setName(params.get("name")); store.setProtocol(params.get("protocol")); store.setProvider(Long.parseLong(params.get("provider"))); + store.setScope(Enum.valueOf(ScopeType.class, params.get("scope"))); + store.setUuid(params.get("uuid")); store = imageStoreDao.persist(store); return store; } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java index 0eb7536..c7b8e2d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java @@ -20,10 +20,14 @@ package org.apache.cloudstack.storage.image.db; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.TableGenerator; +import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; + @Entity @Table(name = "image_data_store") public class ImageDataStoreVO { @@ -35,6 +39,9 @@ public class ImageDataStoreVO { @Column(name = "name", nullable = false) private String name; + @Column(name = "uuid", nullable = false) + private String uuid; + @Column(name = "protocol", nullable = false) private String protocol; @@ -44,6 +51,11 @@ public class ImageDataStoreVO { @Column(name = "data_center_id") private long dcId; + @Column(name = "scope") + @Enumerated(value = EnumType.STRING) + private ScopeType scope; + + public long getId() { return this.id; } @@ -79,4 +91,20 @@ public class ImageDataStoreVO { public long getDcId() { return this.dcId; } + + public ScopeType getScope() { + return this.scope; + } + + public void setScope(ScopeType scope) { + this.scope = scope; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return this.uuid; + } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataVO.java ---------------------------------------------------------------------- diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataVO.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataVO.java index f7274c3..3802596 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataVO.java @@ -80,7 +80,7 @@ public class ImageDataVO implements Identity, StateObject<TemplateState> { @Temporal(value = TemporalType.TIMESTAMP) @Column(name = GenericDao.CREATED_COLUMN) - private final Date created = null; + private Date created = null; @Column(name = GenericDao.REMOVED) @Temporal(TemporalType.TIMESTAMP) @@ -155,6 +155,7 @@ public class ImageDataVO implements Identity, StateObject<TemplateState> { public ImageDataVO() { this.uuid = UUID.randomUUID().toString(); this.state = TemplateState.Allocated; + this.created = new Date(); } public boolean getEnablePassword() { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java ---------------------------------------------------------------------- diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java index ab57d6e..39b2aef 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java @@ -30,7 +30,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.command.CreateObjectCommand; -import org.apache.cloudstack.storage.command.CreateVolumeAnswer; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.endpoint.EndPointSelector; import org.apache.cloudstack.storage.snapshot.SnapshotInfo; @@ -70,11 +70,11 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver public Void createAsyncCallback(AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> callback, CreateVolumeContext<CreateCmdResult> context) { CreateCmdResult result = null; - CreateVolumeAnswer volAnswer = (CreateVolumeAnswer) callback.getResult(); + CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult(); if (volAnswer.getResult()) { - result = new CreateCmdResult(volAnswer.getVolumeUuid()); + result = new CreateCmdResult(volAnswer.getPath(), volAnswer.getSize()); } else { - result = new CreateCmdResult(""); + result = new CreateCmdResult("", null); result.setResult(volAnswer.getDetails()); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java ---------------------------------------------------------------------- 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 3b7600c..5ae587c 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 @@ -78,7 +78,7 @@ public class VolumeObject implements VolumeInfo { } @Override - public long getSize() { + public Long getSize() { return volumeVO.getSize(); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index b0ddb8e..1aa96c3 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -36,7 +36,7 @@ import org.apache.cloudstack.storage.command.CopyCmd; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; -import org.apache.cloudstack.storage.command.CreateVolumeAnswer; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol; @@ -130,7 +130,12 @@ public class XenServerStorageResource { return params; } - protected CreateVolumeAnswer execute(CreateObjectCommand cmd) { + protected CreateObjectAnswer getTemplateSize(CreateObjectCommand cmd, String templateUrl) { + Connection conn = hypervisorResource.getConnection(); + long size = this.getTemplateSize(conn, templateUrl); + return new CreateObjectAnswer(cmd, templateUrl, size); + } + protected CreateObjectAnswer execute(CreateObjectCommand cmd) { String uriString = cmd.getObjectUri(); Map<String, String> params = null; @@ -139,7 +144,11 @@ public class XenServerStorageResource { params = getParameters(uri); } catch (URISyntaxException e1) { s_logger.debug("uri exception", e1); - return new CreateVolumeAnswer(cmd, false, e1.toString()); + return new CreateObjectAnswer(cmd, false, e1.toString()); + } + + if (params.get("objType").equalsIgnoreCase("template")) { + return getTemplateSize(cmd, params.get("path")); } long size = Long.parseLong(params.get("size")); @@ -154,7 +163,7 @@ public class XenServerStorageResource { vdi = createVdi(conn, name, primaryDataStoreSR, size); VDI.Record record = vdi.getRecord(conn); result = true; - return new CreateVolumeAnswer(cmd, record.uuid); + return new CreateObjectAnswer(cmd, record.uuid, record.virtualSize); } catch (BadServerResponse e) { s_logger.debug("Failed to create volume", e); errorMsg = e.toString(); @@ -174,7 +183,7 @@ public class XenServerStorageResource { } } - return new CreateVolumeAnswer(cmd, false, errorMsg); + return new CreateObjectAnswer(cmd, false, errorMsg); } protected Answer execute(DeleteVolumeCommand cmd) { @@ -208,7 +217,7 @@ public class XenServerStorageResource { VDI baseVdi = VDI.getByUuid(conn, baseImage.getPathOnPrimaryDataStore()); VDI newVol = baseVdi.createClone(conn, new HashMap<String, String>()); newVol.setNameLabel(conn, volume.getName()); - return new CreateVolumeAnswer(cmd, newVol.getUuid(conn)); + return new CreateObjectAnswer(cmd, newVol.getUuid(conn), newVol.getVirtualSize(conn)); } catch (BadServerResponse e) { return new Answer(cmd, false, e.toString()); } catch (XenAPIException e) { @@ -579,7 +588,7 @@ public class XenServerStorageResource { params = getParameters(uri); } catch (URISyntaxException e1) { s_logger.debug("uri exception", e1); - return new CreateVolumeAnswer(cmd, false, e1.toString()); + return new CreateObjectAnswer(cmd, false, e1.toString()); } SR sr = hypervisorResource.getStorageRepository(conn, params.get("storeUuid")); hypervisorResource.setupHeartbeatSr(conn, sr, false); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java ---------------------------------------------------------------------- diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java index 1bd51b2..20cb8fb 100644 --- a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -26,7 +26,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; -import org.apache.cloudstack.storage.command.CreateVolumeAnswer; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.provider.PrimaryDataStoreProvider; @@ -112,7 +112,7 @@ public class VolumeTest { results.add(host); Mockito.when(hostDao.listAll()).thenReturn(results); Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); - CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(null,UUID.randomUUID().toString()); + CreateObjectAnswer createVolumeFromImageAnswer = new CreateObjectAnswer(null,UUID.randomUUID().toString()); try { Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(CreateVolumeFromBaseImageCommand.class))).thenReturn(createVolumeFromImageAnswer); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c921118c/setup/db/4.1-new-db-schema.sql ---------------------------------------------------------------------- diff --git a/setup/db/4.1-new-db-schema.sql b/setup/db/4.1-new-db-schema.sql index fb80920..d541537 100644 --- a/setup/db/4.1-new-db-schema.sql +++ b/setup/db/4.1-new-db-schema.sql @@ -16,6 +16,8 @@ -- under the License. alter table vm_template add image_data_store_id bigint unsigned; +alter table vm_template add size bigint unsigned; +alter table vm_template add state varchar(255); alter table storage_pool add storage_provider_id bigint unsigned; alter table storage_pool add scope varchar(255); alter table storage_pool modify id bigint unsigned AUTO_INCREMENT UNIQUE NOT NULL; @@ -48,6 +50,26 @@ alter table cluster add column owner varchar(255); alter table cluster add column created datetime COMMENT 'date created'; alter table cluster add column lastUpdated datetime COMMENT 'last updated'; alter table cluster add column engine_state varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'the engine state of the zone'; +CREATE TABLE `cloud`.`object_datastore_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `datastore_id` bigint unsigned NOT NULL, + `datastore_role` varchar(255) NOT NULL, + `object_id` bigint unsigned NOT NULL, + `object_type` varchar(255) NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `job_id` varchar(255), + `download_pct` int(10) unsigned, + `download_state` varchar(255), + `error_str` varchar(255), + `local_path` varchar(255), + `install_path` varchar(255), + `size` bigint unsigned COMMENT 'the size of the template on the pool', + `state` varchar(255) NOT NULL, + `update_count` bigint unsigned NOT NULL, + `updated` DATETIME NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`data_store_provider` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', @@ -56,18 +78,16 @@ CREATE TABLE `cloud`.`data_store_provider` ( PRIMARY KEY(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`image_data_store_provider` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `name` varchar(255) NOT NULL COMMENT 'name of data store provider', - PRIMARY KEY(`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - CREATE TABLE `cloud`.`image_data_store` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `name` varchar(255) NOT NULL COMMENT 'name of data store', `image_provider_id` bigint unsigned NOT NULL COMMENT 'id of image_data_store_provider', + `protocol` varchar(255) NOT NULL COMMENT 'protocol of data store', + `data_center_id` bigint unsigned COMMENT 'datacenter id of data store', + `scope` varchar(255) COMMENT 'scope of data store', + `uuid` varchar(255) COMMENT 'uuid of data store', PRIMARY KEY(`id`), - CONSTRAINT `fk_tags__image_data_store_provider_id` FOREIGN KEY(`image_provider_id`) REFERENCES `image_data_store_provider`(`id`) + CONSTRAINT `fk_tags__image_data_store_provider_id` FOREIGN KEY(`image_provider_id`) REFERENCES `data_store_provider`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`vm_compute_tags` (