diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 0dbc9a28832..f004561099d 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -51,11 +51,11 @@ test - org.apache.httpcomponents - httpclient - 4.2.2 - compile - + org.apache.httpcomponents + httpclient + 4.2.2 + compile + mysql mysql-connector-java @@ -72,10 +72,22 @@ javax.inject 1 + + org.testng + testng + 6.1.1 + test + + install - test + ${project.basedir}/test + + + ${project.basedir}/test/resource + + maven-compiler-plugin diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java new file mode 100644 index 00000000000..94ae2088d91 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -0,0 +1,68 @@ +package org.apache.cloudstack.storage.test; + +import java.lang.reflect.Method; + +import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; + +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Transaction; + +public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { + private String hostGateway; + private String hostCidr; + private String hostIp; + private String hostGuid; + private String templateUrl; + private String localStorageUuid; + private Transaction txn; + + @BeforeMethod(alwaysRun = true) + protected void injectDB(Method testMethod) throws Exception { + txn = Transaction.open(testMethod.getName()); + } + + @AfterMethod(alwaysRun = true) + protected void closeDB(Method testMethod) throws Exception { + if (txn != null) { + txn.close(); + } + } + + @BeforeMethod(alwaysRun = true) + @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid"}) + protected void setup(String hostuuid, String gateway, String cidr, String hostIp, String templateUrl, String localStorageUuid) { + this.hostGuid = hostuuid; + this.hostGateway = gateway; + this.hostCidr = cidr; + this.hostIp = hostIp; + this.templateUrl = templateUrl; + this.localStorageUuid = localStorageUuid; + } + + protected String getHostGuid() { + return this.hostGuid; + } + + protected String getHostGateway() { + return this.hostGateway; + } + + protected String getHostCidr() { + return this.hostCidr; + } + + protected String getHostIp() { + return this.hostIp; + } + + protected String getTemplateUrl() { + return this.templateUrl; + } + + protected String getLocalStorageUuid() { + return this.localStorageUuid; + } +} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java index 072535b37b8..371e6d0eb87 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.test; +import java.lang.reflect.Method; import java.util.UUID; import javax.inject.Inject; @@ -27,12 +28,16 @@ import org.apache.cloudstack.storage.to.ImageDataStoreTO; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.TemplateTO; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; + import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; import com.cloud.agent.AgentManager; import com.cloud.agent.api.ReadyCommand; @@ -52,10 +57,11 @@ 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.utils.db.DB; +import com.cloud.utils.db.Transaction; -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="classpath:/resource/storageContext.xml") -public class DirectAgentTest { +@ContextConfiguration(locations="classpath:/storageContext.xml") +public class DirectAgentTest extends CloudStackTestNGBase { @Inject AgentManager agentMgr; @Inject @@ -69,10 +75,10 @@ public class DirectAgentTest { private long dcId; private long clusterId; private long hostId; - private String hostGuid = "9d4c9db8-32f7-25c3-0435-eab4bf3adcea"; - @Before + + @Test(priority = -1) public void setUp() { - HostVO host = hostDao.findByGuid(hostGuid); + HostVO host = hostDao.findByGuid(this.getHostGuid()); if (host != null) { hostId = host.getId(); dcId = host.getDataCenterId(); @@ -86,7 +92,7 @@ public class DirectAgentTest { dcId = dc.getId(); //create pod - HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "192.168.56.1", "192.168.56.0/24", 8, "test"); + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test"); pod = podDao.persist(pod); //create xen cluster ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); @@ -97,12 +103,11 @@ public class DirectAgentTest { clusterId = cluster.getId(); //create xen host - //TODO: this hardcode host uuid in devcloud - host = new HostVO(hostGuid); + host = new HostVO(this.getHostGuid()); host.setName("devcloud xen host"); host.setType(Host.Type.Routing); host.setHypervisorType(HypervisorType.XenServer); - host.setPrivateIpAddress("192.168.56.10"); + host.setPrivateIpAddress(this.getHostIp()); host.setDataCenterId(dc.getId()); host.setVersion("6.0.1"); host.setAvailable(true); @@ -133,14 +138,14 @@ public class DirectAgentTest { public void testDownloadTemplate() { ImageOnPrimayDataStoreTO image = Mockito.mock(ImageOnPrimayDataStoreTO.class); PrimaryDataStoreTO primaryStore = Mockito.mock(PrimaryDataStoreTO.class); - Mockito.when(primaryStore.getUuid()).thenReturn("9f3f9262-3f77-09cc-2df7-0d8475676260"); + Mockito.when(primaryStore.getUuid()).thenReturn(this.getLocalStorageUuid()); Mockito.when(image.getPrimaryDataStore()).thenReturn(primaryStore); ImageDataStoreTO imageStore = Mockito.mock(ImageDataStoreTO.class); Mockito.when(imageStore.getType()).thenReturn("http"); TemplateTO template = Mockito.mock(TemplateTO.class); - Mockito.when(template.getPath()).thenReturn("http://download.cloud.com/templates/devcloud/defaulttemplates/5/ce5b212e-215a-3461-94fb-814a635b2215.vhd"); + Mockito.when(template.getPath()).thenReturn(this.getTemplateUrl()); Mockito.when(template.getImageDataStore()).thenReturn(imageStore); Mockito.when(image.getTemplate()).thenReturn(template); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/Future2.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/Future2.java deleted file mode 100644 index bc2fd7aaae7..00000000000 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/Future2.java +++ /dev/null @@ -1,114 +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.test; - -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - - -public class Future2 { - - private Callable callable; - private Callable success; - private Callable failed; - private ExecutorService executor = Executors.newFixedThreadPool(2); - private Future f; - - public class Func implements Callable { - private Callable f; - private Callable fs; - public T func() throws Exception { - return f.call(); - } - - public T success() throws Exception { - return fs.call(); - } - - public Func (Callable f, Callable s) { - this.f = f; - this.fs = s; - } - - - @Override - public T call() throws Exception { - func(); - success(); - return null; - } - - } - public Future2 (Callable callable) { - this.callable = callable; - } - - public void onSuccess(Callable s) { - this.success = s; - } - - public void go() { - Func ft = new Func(this.callable, this.success); - f = executor.submit(ft); - } - - public T get() { - try { - return this.f.get(); - } catch (InterruptedException e) { - return null; - } catch (ExecutionException e) { - // TODO Auto-generated catch block - return null; - } - } - - public void shutdown() { - this.executor.shutdown(); - } - - public static void main(String[] args) { - Callable fun = new Callable () { - - @Override - public String call() throws Exception { - System.out.println("execing"); - return "test"; - } - - }; - Future2 f2 = new Future2(fun); - f2.onSuccess(new Callable() { - - @Override - public String call() throws Exception { - Thread.sleep(1000); - System.out.println("success"); - return null; - } - }); - - f2.go(); - //f2.get(); - f2.shutdown(); - } -} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SimpleTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SimpleTest.java deleted file mode 100644 index a9b3f93f446..00000000000 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SimpleTest.java +++ /dev/null @@ -1,41 +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.test; - -import static org.junit.Assert.*; - -import java.net.URI; -import java.net.URISyntaxException; - -import org.junit.Test; - -public class SimpleTest { - - @Test - public void test() { - try { - URI u = new URI("http://myproxy.domain.com:3128"); - System.out.print(u.getHost()); - } catch (URISyntaxException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - -} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java index 9de1c21e997..8b10f7e3224 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java @@ -40,13 +40,15 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.testng.annotations.Parameters; -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="classpath:/resource/storageContext.xml") -public class TestHttp { +@ContextConfiguration(locations="classpath:/storageContext.xml") +public class TestHttp extends AbstractTestNGSpringContextTests { @Test - public void testHttpclient() { - HttpHead method = new HttpHead("http://download.cloud.com/templates/devcloud/defaulttemplates/5/ce5b212e-215a-3461-94fb-814a635b2215.vhd"); + @Parameters("template-url") + public void testHttpclient(String templateUrl) { + HttpHead method = new HttpHead(templateUrl); DefaultHttpClient client = new DefaultHttpClient(); OutputStream output = null; @@ -60,7 +62,7 @@ public class TestHttp { localFile.createNewFile(); } - HttpGet getMethod = new HttpGet("http://download.cloud.com/templates/devcloud/defaulttemplates/5/ce5b212e-215a-3461-94fb-814a635b2215.vhd"); + HttpGet getMethod = new HttpGet(templateUrl); response = client.execute(getMethod); HttpEntity entity = response.getEntity(); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java new file mode 100644 index 00000000000..3da31e8eb4b --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java @@ -0,0 +1,19 @@ +package org.apache.cloudstack.storage.test; + +import junit.framework.Assert; + +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import com.cloud.utils.db.DB; +@ContextConfiguration(locations="classpath:/storageContext.xml") +public class TestNG extends AbstractTestNGSpringContextTests { + @Test + @DB + public void test1() { + Assert.assertEquals("", "192.168.56.2"); + } +} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java new file mode 100644 index 00000000000..6cc2d209c20 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java @@ -0,0 +1,37 @@ +package org.apache.cloudstack.storage.test; + +import java.lang.reflect.Method; +import java.util.List; + +import org.testng.IMethodInstance; +import org.testng.IMethodInterceptor; +import org.testng.ITestContext; +import org.testng.ITestNGMethod; +import org.testng.internal.ConstructorOrMethod; + +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Transaction; + +public class TestNGAop implements IMethodInterceptor { + + @Override + public List intercept(List methods, + ITestContext context) { + for (IMethodInstance methodIns : methods) { + ITestNGMethod method = methodIns.getMethod(); + ConstructorOrMethod meth = method.getConstructorOrMethod(); + Method m = meth.getMethod(); + if (m != null) { + DB db = m.getAnnotation(DB.class); + if (db != null) { + Transaction txn = Transaction.open(m.getName()); + } + } + } + + + // TODO Auto-generated method stub + return methods; + } + +} 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 238de2bb50d..cd251b15074 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 @@ -105,7 +105,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="classpath:/resource/storageContext.xml") +@ContextConfiguration(locations="classpath:/storageContext.xml") public class volumeServiceTest { @Inject ImageDataStoreProviderManager imageProviderMgr; @@ -158,7 +158,7 @@ public class volumeServiceTest { HostVO host = new HostVO(UUID.randomUUID().toString()); host.setName("devcloud xen host"); host.setType(Host.Type.Routing); - host.setPrivateIpAddress("192.168.56.10"); + host.setPrivateIpAddress("192.168.56.2"); host.setDataCenterId(dc.getId()); host.setVersion("6.0.1"); host.setAvailable(true); diff --git a/engine/storage/integration-test/test/resource/testng.xml b/engine/storage/integration-test/test/resource/testng.xml new file mode 100644 index 00000000000..b2531d17d93 --- /dev/null +++ b/engine/storage/integration-test/test/resource/testng.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java new file mode 100644 index 00000000000..db5c0192f02 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java @@ -0,0 +1,23 @@ +package org.apache.cloudstack.storage.command; + +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; + +import com.cloud.agent.api.Command; + +public class CreatePrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { + private final PrimaryDataStoreTO dataStore; + public CreatePrimaryDataStoreCmd(PrimaryDataStoreTO dataStore) { + this.dataStore = dataStore; + } + + public PrimaryDataStoreTO getDataStore() { + return this.dataStore; + } + + @Override + public boolean executeInSequence() { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/configurator/validator/NfsValidator.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/configurator/validator/NfsValidator.java index 5ee931602e7..0da41749206 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/configurator/validator/NfsValidator.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/configurator/validator/NfsValidator.java @@ -23,6 +23,7 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.UUID; import com.cloud.utils.exception.CloudRuntimeException; @@ -48,6 +49,7 @@ public class NfsValidator implements ProtocolValidator { params.put("path", hostPath); params.put("user", userInfo); params.put("port", String.valueOf(port)); + params.put("uuid", UUID.fromString(storageHost + hostPath).toString()); } catch (URISyntaxException e) { throw new CloudRuntimeException("invalid url: " + e.toString()); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreVO.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreVO.java index 251c817137c..4a7a5366045 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreVO.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreVO.java @@ -53,7 +53,7 @@ public class PrimaryDataStoreVO implements Identity { private String uuid = null; @Column(name = "pool_type", updatable = false, nullable = false, length = 32) - private String protocol; + private String poolType; @Column(name = GenericDao.CREATED_COLUMN) Date created; @@ -123,11 +123,11 @@ public class PrimaryDataStoreVO implements Identity { } public String getPoolType() { - return protocol; + return poolType; } public void setPoolType(String protocol) { - this.protocol = protocol; + this.poolType = protocol; } public Date getCreated() { @@ -262,6 +262,6 @@ public class PrimaryDataStoreVO implements Identity { @Override public String toString() { - return new StringBuilder("Pool[").append(id).append("|").append(protocol).append("]").toString(); + return new StringBuilder("Pool[").append(id).append("|").append(poolType).append("]").toString(); } } \ No newline at end of file diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java index 7f55797a4f4..3826414e51f 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java @@ -51,21 +51,25 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif return true; } + protected void attachCluster() { + //send down createStoragePool command to all the hosts in the cluster + AttachPrimaryDataStoreCmd cmd = new AttachPrimaryDataStoreCmd(this.dataStore); + for (EndPoint ep : dataStore.getEndPoints()) { + ep.sendMessage(cmd); + } + } + @Override public boolean attachCluster(ClusterScope scope) { + attachCluster(); + PrimaryDataStoreVO dataStoreVO = dataStoreDao.findById(this.dataStore.getId()); dataStoreVO.setDataCenterId(scope.getZoneId()); dataStoreVO.setPodId(scope.getPodId()); dataStoreVO.setClusterId(scope.getScopeId()); dataStoreVO.setStatus(DataStoreStatus.Up); dataStoreDao.update(dataStoreVO.getId(), dataStoreVO); - - //send down createStoragePool command to all the hosts in the cluster - AttachPrimaryDataStoreCmd cmd = new AttachPrimaryDataStoreCmd(this.dataStore); - for (EndPoint ep : dataStore.getEndPoints()) { - ep.sendMessage(cmd); - } - return false; + return true; } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java index 824ac01daf6..d689258480b 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java @@ -18,8 +18,13 @@ */ package org.apache.cloudstack.storage.datastore.lifecycle; +import org.apache.cloudstack.storage.EndPoint; +import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import com.cloud.agent.api.Answer; +import com.cloud.utils.exception.CloudRuntimeException; + public class DefaultXenPrimaryDataStoreLifeCycle extends DefaultPrimaryDataStoreLifeCycleImpl { /** @@ -30,5 +35,22 @@ public class DefaultXenPrimaryDataStoreLifeCycle extends DefaultPrimaryDataStore super(dataStoreDao); // TODO Auto-generated constructor stub } + + @Override + public void attachCluster() { + //send one time is enough, as xenserver is clustered + AttachPrimaryDataStoreCmd cmd = new AttachPrimaryDataStoreCmd(this.dataStore); + String result = null; + for (EndPoint ep : dataStore.getEndPoints()) { + Answer answer = ep.sendMessage(cmd); + if (answer.getResult()) { + return; + } + result = answer.getDetails(); + } + + throw new CloudRuntimeException("AttachPrimaryDataStoreCmd failed: " + result); + } + } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java index 9953708e715..3bd4113b62a 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java @@ -125,6 +125,7 @@ public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProv dataStoreVO.setPort(Integer.parseInt(dsInfos.get("port"))); dataStoreVO.setKey(key); dataStoreVO.setName(dsInfos.get("name")); + dataStoreVO.setUuid(dsInfos.get("uuid")); dataStoreVO = dataStoreDao.persist(dataStoreVO); DefaultPrimaryDataStore dataStore = (DefaultPrimaryDataStore)configurator.getDataStore(dataStoreVO.getId()); 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 f47b080dc24..7b2de95abee 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 @@ -32,6 +32,7 @@ import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageCmd; import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer; +import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.to.ImageDataStoreTO; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; @@ -56,10 +57,14 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.ModifyStoragePoolAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; +import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.template.TemplateInfo; import com.cloud.utils.exception.CloudRuntimeException; import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; import com.xensource.xenapi.PBD; +import com.xensource.xenapi.Pool; import com.xensource.xenapi.SR; import com.xensource.xenapi.Types; import com.xensource.xenapi.Types.BadServerResponse; @@ -79,13 +84,212 @@ public class XenServerStorageResource { return this.execute((CopyTemplateToPrimaryStorageCmd)command); } else if (command instanceof AttachPrimaryDataStoreCmd) { return this.execute((AttachPrimaryDataStoreCmd)command); + } else if (command instanceof CreatePrimaryDataStoreCmd) { + return execute((CreatePrimaryDataStoreCmd) command); } return new Answer((Command)command, false, "not implemented yet"); } + /* + protected SR getNfsSR(Connection conn, PrimaryDataStoreTO pool) { + Map deviceConfig = new HashMap(); + try { + String server = pool.getHost(); + String serverpath = pool.getPath(); + serverpath = serverpath.replace("//", "/"); + Set srs = SR.getAll(conn); + for (SR sr : srs) { + if (!SRType.NFS.equals(sr.getType(conn))) { + continue; + } + + Set pbds = sr.getPBDs(conn); + if (pbds.isEmpty()) { + continue; + } + + PBD pbd = pbds.iterator().next(); + + Map dc = pbd.getDeviceConfig(conn); + + if (dc == null) { + continue; + } + + if (dc.get("server") == null) { + continue; + } + + if (dc.get("serverpath") == null) { + continue; + } + + if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { + throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + + dc.get("serverpath") + " for pool " + pool.getUuid() + "on host:" + _host.uuid); + } + + } + deviceConfig.put("server", server); + deviceConfig.put("serverpath", serverpath); + Host host = Host.getByUuid(conn, _host.uuid); + SR sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, + new HashMap()); + sr.scan(conn); + return sr; + } catch (XenAPIException e) { + throw new CloudRuntimeException("Unable to create NFS SR " + pool.toString(), e); + } catch (XmlRpcException e) { + throw new CloudRuntimeException("Unable to create NFS SR " + pool.toString(), e); + } + } + + protected SR getIscsiSR(Connection conn, PrimaryDataStoreTO pool) { + synchronized (pool.getUuid().intern()) { + Map deviceConfig = new HashMap(); + try { + String target = pool.getHost(); + String path = pool.getPath(); + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); + } + + String tmp[] = path.split("/"); + if (tmp.length != 3) { + String msg = "Wrong iscsi path " + pool.getPath() + " it should be /targetIQN/LUN"; + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + String targetiqn = tmp[1].trim(); + String lunid = tmp[2].trim(); + String scsiid = ""; + + Set srs = SR.getByNameLabel(conn, pool.getUuid()); + for (SR sr : srs) { + if (!SRType.LVMOISCSI.equals(sr.getType(conn))) { + continue; + } + Set pbds = sr.getPBDs(conn); + if (pbds.isEmpty()) { + continue; + } + PBD pbd = pbds.iterator().next(); + Map dc = pbd.getDeviceConfig(conn); + if (dc == null) { + continue; + } + if (dc.get("target") == null) { + continue; + } + if (dc.get("targetIQN") == null) { + continue; + } + if (dc.get("lunid") == null) { + continue; + } + if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) { + throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + + dc.get("targetIQN") + ", lunid:" + dc.get("lunid") + " for pool " + pool.getUuid() + "on host:" + _host.uuid); + } + } + deviceConfig.put("target", target); + deviceConfig.put("targetIQN", targetiqn); + + Host host = Host.getByUuid(conn, _host.uuid); + Map smConfig = new HashMap(); + String type = SRType.LVMOISCSI.toString(); + String poolId = Long.toString(pool.getId()); + SR sr = null; + try { + sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), poolId, type, "user", true, + smConfig); + } catch (XenAPIException e) { + String errmsg = e.toString(); + if (errmsg.contains("SR_BACKEND_FAILURE_107")) { + String lun[] = errmsg.split(""); + boolean found = false; + for (int i = 1; i < lun.length; i++) { + int blunindex = lun[i].indexOf("") + 7; + int elunindex = lun[i].indexOf(""); + String ilun = lun[i].substring(blunindex, elunindex); + ilun = ilun.trim(); + if (ilun.equals(lunid)) { + int bscsiindex = lun[i].indexOf("") + 8; + int escsiindex = lun[i].indexOf(""); + scsiid = lun[i].substring(bscsiindex, escsiindex); + scsiid = scsiid.trim(); + found = true; + break; + } + } + if (!found) { + String msg = "can not find LUN " + lunid + " in " + errmsg; + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + } else { + String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } + } + deviceConfig.put("SCSIid", scsiid); + + String result = SR.probe(conn, host, deviceConfig, type , smConfig); + String pooluuid = null; + if( result.indexOf("") != -1) { + pooluuid = result.substring(result.indexOf("") + 6, result.indexOf("")).trim(); + } + if( pooluuid == null || pooluuid.length() != 36) { + sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), poolId, type, "user", true, + smConfig); + } else { + sr = SR.introduce(conn, pooluuid, pool.getUuid(), poolId, + type, "user", true, smConfig); + Pool.Record pRec = XenServerConnectionPool.getPoolRecord(conn); + PBD.Record rec = new PBD.Record(); + rec.deviceConfig = deviceConfig; + rec.host = pRec.master; + rec.SR = sr; + PBD pbd = PBD.create(conn, rec); + pbd.plug(conn); + } + sr.scan(conn); + return sr; + } catch (XenAPIException e) { + String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } catch (Exception e) { + String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.getMessage(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } + } + }*/ + + protected Answer execute(CreatePrimaryDataStoreCmd cmd) { + Connection conn = hypervisorResource.getConnection(); + PrimaryDataStoreTO dataStore = cmd.getDataStore(); + try { + if (dataStore.getType() == StoragePoolType.NetworkFilesystem.toString()) { + //getNfsSR(conn, dataStore); + } else if (dataStore.getType() == StoragePoolType.IscsiLUN.toString()) { + //getIscsiSR(conn, dataStore); + } else if (dataStore.getType() == StoragePoolType.PreSetup.toString()) { + } else { + //return new Answer(cmd, false, "The pool type: " + pool.getType().name() + " is not supported."); + } + return new Answer(cmd, true, "success"); + } catch (Exception e) { + // String msg = "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath(); + //s_logger.warn(msg, e); + return new Answer(cmd, false, null); + } + } private long getTemplateSize(Connection conn, String url) { String size = hypervisorResource.callHostPlugin(conn, "storagePlugin", "getTemplateSize", "srcUrl", url); - if (size == "" || size == null) { + if (size.equalsIgnoreCase("") || size == null) { throw new CloudRuntimeException("Can't get template size"); } diff --git a/scripts/vm/hypervisor/xenserver/storagePlugin b/scripts/vm/hypervisor/xenserver/storagePlugin index 7cb6e354a1e..bb033797620 100755 --- a/scripts/vm/hypervisor/xenserver/storagePlugin +++ b/scripts/vm/hypervisor/xenserver/storagePlugin @@ -22,7 +22,7 @@ import os, sys, time import XenAPIPlugin -sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) +sys.path.extend(["/opt/xensource/sm/", "/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"]) import util import base64 import socket diff --git a/scripts/vm/hypervisor/xenserver/xcposs/patch b/scripts/vm/hypervisor/xenserver/xcposs/patch index 1b615b77fdb..b121a5628a9 100644 --- a/scripts/vm/hypervisor/xenserver/xcposs/patch +++ b/scripts/vm/hypervisor/xenserver/xcposs/patch @@ -64,4 +64,4 @@ cloud-prepare-upgrade.sh=..,0755,/usr/lib/xcp/bin getRouterStatus.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin bumpUpPriority.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin getDomRVersion.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin -storagePlugin=.,0755,/usr/lib/xcp/plugins +storagePlugin=..,0755,/usr/lib/xcp/plugins