You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2012/12/21 04:06:38 UTC
git commit: finaly, finish download template to primary storage
Updated Branches:
refs/heads/javelin 1d5019c3d -> ac88c16be
finaly, finish download template to primary storage
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/ac88c16b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/ac88c16b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/ac88c16b
Branch: refs/heads/javelin
Commit: ac88c16be630a16880ae61b581a4eb9b598892a5
Parents: 1d5019c
Author: Edison Su <su...@gmail.com>
Authored: Thu Dec 20 19:05:47 2012 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Thu Dec 20 19:06:02 2012 -0800
----------------------------------------------------------------------
.../storage/test/DirectAgentManagerSimpleImpl.java | 7 +
.../cloudstack/storage/test/DirectAgentTest.java | 6 +-
...ockHostEndpointRpcServerDirectCallResource.java | 87 +++++++++++++++
.../test/MockHypervsiorHostEndPointRpcServer.java | 10 ++-
.../cloudstack/storage/test/volumeServiceTest.java | 4 +-
.../cloudstack/storage/HostEndpointRpcServer.java | 3 +-
.../cloudstack/storage/HypervisorHostEndPoint.java | 22 ++--
.../storage/HypervsiorHostEndPointRpcServer.java | 56 +++++++++-
.../command/AttachPrimaryDataStoreAnswer.java | 55 +++++++++
.../storage/command/AttachPrimaryDataStoreCmd.java | 41 +++++++
.../DefaultPrimaryDataStoreLifeCycleImpl.java | 24 +++-
.../xen/resource/CitrixResourceBase.java | 26 ++--
.../xen/resource/XenServerStorageResource.java | 62 +++++++++-
scripts/vm/hypervisor/xenserver/mockxcpplugin.py | 66 +++++++++++
scripts/vm/hypervisor/xenserver/storagePlugin | 37 +++++--
scripts/vm/hypervisor/xenserver/xcposs/patch | 1 +
16 files changed, 447 insertions(+), 60 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
index 080e65b..6d09561 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
@@ -31,12 +31,14 @@ import com.cloud.agent.Listener;
import com.cloud.agent.StartupCommandProcessor;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
+import com.cloud.agent.api.SetupCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.manager.AgentAttache;
import com.cloud.agent.manager.Commands;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConnectionException;
import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.HostEnvironment;
import com.cloud.host.HostVO;
import com.cloud.host.Status.Event;
import com.cloud.host.dao.HostDao;
@@ -100,6 +102,11 @@ public class DirectAgentManagerSimpleImpl implements AgentManager {
} catch (ConfigurationException e) {
logger.debug("Failed to load resource:" + e.toString());
}
+ HostEnvironment env = new HostEnvironment();
+ SetupCommand cmd = new SetupCommand(env);
+ cmd.setNeedSetup(true);
+
+ resource.executeRequest(cmd);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java
----------------------------------------------------------------------
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 2f5e7ae..072535b 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
@@ -69,7 +69,7 @@ public class DirectAgentTest {
private long dcId;
private long clusterId;
private long hostId;
- private String hostGuid = "759ee4c9-a15a-297b-67c6-ac267d8aa429";
+ private String hostGuid = "9d4c9db8-32f7-25c3-0435-eab4bf3adcea";
@Before
public void setUp() {
HostVO host = hostDao.findByGuid(hostGuid);
@@ -102,7 +102,7 @@ public class DirectAgentTest {
host.setName("devcloud xen host");
host.setType(Host.Type.Routing);
host.setHypervisorType(HypervisorType.XenServer);
- host.setPrivateIpAddress("192.168.56.2");
+ host.setPrivateIpAddress("192.168.56.10");
host.setDataCenterId(dc.getId());
host.setVersion("6.0.1");
host.setAvailable(true);
@@ -133,7 +133,7 @@ public class DirectAgentTest {
public void testDownloadTemplate() {
ImageOnPrimayDataStoreTO image = Mockito.mock(ImageOnPrimayDataStoreTO.class);
PrimaryDataStoreTO primaryStore = Mockito.mock(PrimaryDataStoreTO.class);
- Mockito.when(primaryStore.getUuid()).thenReturn("cd10cac1-4772-92e5-5da6-c2bc16b1ce1b");
+ Mockito.when(primaryStore.getUuid()).thenReturn("9f3f9262-3f77-09cc-2df7-0d8475676260");
Mockito.when(image.getPrimaryDataStore()).thenReturn(primaryStore);
ImageDataStoreTO imageStore = Mockito.mock(ImageDataStoreTO.class);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java
new file mode 100644
index 0000000..f2272ce
--- /dev/null
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java
@@ -0,0 +1,87 @@
+/*
+ * 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.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+import org.apache.cloudstack.storage.HostEndpointRpcServer;
+import org.apache.cloudstack.storage.HypervisorHostEndPoint;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+
+
+public class MockHostEndpointRpcServerDirectCallResource implements HostEndpointRpcServer {
+ private static final Logger s_logger = Logger.getLogger(MockHostEndpointRpcServerDirectCallResource.class);
+ private ScheduledExecutorService executor;
+ @Inject
+ AgentManager agentMgr;
+ public MockHostEndpointRpcServerDirectCallResource() {
+ executor = Executors.newScheduledThreadPool(10);
+ }
+ protected class MockRpcCallBack implements Runnable {
+ private final Command cmd;
+ private final long hostId;
+ private final AsyncCompletionCallback<Answer> callback;
+ public MockRpcCallBack(long hostId, Command cmd, final AsyncCompletionCallback<Answer> callback) {
+ this.cmd = cmd;
+ this.callback = callback;
+ this.hostId = hostId;
+ }
+ @Override
+ public void run() {
+ try {
+ Answer answer = agentMgr.send(hostId, cmd);
+ callback.complete(answer);
+ } catch (Exception e) {
+ s_logger.debug("send command failed:" + e.toString());
+ }
+ }
+
+ }
+
+ public void sendCommandAsync(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback<Answer> callback) {
+ executor.schedule(new MockRpcCallBack(host.getHostId(), command, callback), 10, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public Answer sendCommand(HypervisorHostEndPoint host, Command command) {
+ Answer answer;
+ try {
+ answer = agentMgr.send(host.getHostId(), command);
+ return answer;
+ } catch (AgentUnavailableException e) {
+ return null;
+ } catch (OperationTimedoutException e) {
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java
index 35b5bb1..6c5ee19 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java
@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.HostEndpointRpcServer;
+import org.apache.cloudstack.storage.HypervisorHostEndPoint;
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageCmd;
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer;
import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
@@ -63,7 +64,14 @@ public class MockHypervsiorHostEndPointRpcServer implements HostEndpointRpcServe
}
}
- public void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback) {
+
+ public void sendCommandAsync(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback<Answer> callback) {
executor.schedule(new MockRpcCallBack(command, callback), 10, TimeUnit.SECONDS);
}
+
+ @Override
+ public Answer sendCommand(HypervisorHostEndPoint host, Command command) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/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 59a7554..238de2b 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
@@ -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.2");
+ host.setPrivateIpAddress("192.168.56.10");
host.setDataCenterId(dc.getId());
host.setVersion("6.0.1");
host.setAvailable(true);
@@ -237,7 +237,7 @@ public class volumeServiceTest {
PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("default primary data store provider");
Map<String, String> params = new HashMap<String, String>();
- params.put("url", "nfs://test/test");
+ params.put("url", "nfs://localhost/primarynfs");
params.put("dcId", dcId.toString());
params.put("clusterId", clusterId.toString());
params.put("name", "my primary data store");
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java b/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java
index 25ebc7f..a316223 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java
@@ -24,5 +24,6 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
public interface HostEndpointRpcServer {
- void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback);
+ void sendCommandAsync(HypervisorHostEndPoint ep, final Command command, final AsyncCompletionCallback<Answer> callback);
+ Answer sendCommand(HypervisorHostEndPoint ep, final Command command);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java
index 7e5387d..a2e9ea9 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java
@@ -42,24 +42,22 @@ public class HypervisorHostEndPoint implements EndPoint {
this.hostId = hostId;
this.hostAddress = hostAddress;
}
+
+ public String getHostAddr() {
+ return this.hostAddress;
+ }
+
+ public long getHostId() {
+ return this.hostId;
+ }
@Override
public Answer sendMessage(Command cmd) {
- Answer answer = null;
- try {
- answer = agentMgr.send(hostId, cmd);
- } catch (AgentUnavailableException e) {
- s_logger.debug("Unable to send command:" + cmd + ", due to: " + e.toString());
- } catch (OperationTimedoutException e) {
- s_logger.debug("Unable to send command:" + cmd + ", due to: " + e.toString());
- } catch (Exception e) {
- s_logger.debug("Unable to send command:" + cmd + ", due to: " + e.toString());
- }
- return answer;
+ return rpcServer.sendCommand(this, cmd);
}
@Override
public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback) {
- rpcServer.sendCommandAsync(this.hostAddress, cmd, callback);
+ rpcServer.sendCommandAsync(this, cmd, callback);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java b/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java
index de7b386..0975869 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java
@@ -20,19 +20,23 @@ package org.apache.cloudstack.storage;
import javax.inject.Inject;
+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.framework.rpc.RpcCallbackListener;
import org.apache.cloudstack.framework.rpc.RpcException;
import org.apache.cloudstack.framework.rpc.RpcProvider;
import org.apache.cloudstack.framework.rpc.RpcServiceDispatcher;
+import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
+import com.cloud.utils.exception.CloudRuntimeException;
@Component
public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer {
-
+ private static final Logger s_logger = Logger.getLogger(HypervsiorHostEndPointRpcServer.class);
private RpcProvider _rpcProvider;
@Inject
public HypervsiorHostEndPointRpcServer(RpcProvider rpcProvider) {
@@ -41,8 +45,8 @@ public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer {
}
@Override
- public void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback) {
- _rpcProvider.newCall(host).addCallbackListener(new RpcCallbackListener<Answer>() {
+ public void sendCommandAsync(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback<Answer> callback) {
+ _rpcProvider.newCall(host.getHostAddr()).addCallbackListener(new RpcCallbackListener<Answer>() {
@Override
public void onSuccess(Answer result) {
callback.complete(result);
@@ -55,4 +59,50 @@ public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer {
}
}).apply();
}
+
+ private class SendCommandContext<T> extends AsyncRpcConext<T> {
+ private T answer;
+
+ public SendCommandContext(AsyncCompletionCallback<T> callback) {
+ super(callback);
+ }
+
+ public void setAnswer(T answer) {
+ this.answer = answer;
+ }
+
+ public T getAnswer() {
+ return this.answer;
+ }
+
+ }
+
+ @Override
+ public Answer sendCommand(HypervisorHostEndPoint host, Command command) {
+ SendCommandContext<Answer> context = new SendCommandContext<Answer>(null);
+ AsyncCallbackDispatcher<HypervsiorHostEndPointRpcServer> caller = AsyncCallbackDispatcher.create(this);
+ caller.setCallback(caller.getTarget().sendCommandCallback(null, null))
+ .setContext(context);
+
+ this.sendCommandAsync(host, command, caller);
+
+ synchronized (context) {
+ try {
+ context.wait();
+ } catch (InterruptedException e) {
+ s_logger.debug(e.toString());
+ throw new CloudRuntimeException("wait on context is interrupted", e);
+ }
+ }
+
+ return context.getAnswer();
+ }
+
+ protected Object sendCommandCallback(AsyncCallbackDispatcher<HypervsiorHostEndPointRpcServer> callback, SendCommandContext<Answer> context) {
+ context.setAnswer((Answer)callback.getResult());
+ synchronized(context) {
+ context.notify();
+ }
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java b/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java
new file mode 100644
index 0000000..cd15030
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java
@@ -0,0 +1,55 @@
+/*
+ * 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 AttachPrimaryDataStoreAnswer extends Answer {
+ private String uuid;
+ private long capacity;
+ private long avail;
+ public AttachPrimaryDataStoreAnswer(Command cmd) {
+ super(cmd);
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getUuid() {
+ return this.uuid;
+ }
+
+ public void setCapacity(long capacity) {
+ this.capacity = capacity;
+ }
+
+ public long getCapacity() {
+ return this.capacity;
+ }
+
+ public void setAvailable(long avail) {
+ this.avail = avail;
+ }
+
+ public long getAvailable() {
+ return this.avail;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java b/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java
new file mode 100644
index 0000000..53400a3
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java
@@ -0,0 +1,41 @@
+/*
+ * 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 org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+
+import com.cloud.agent.api.Command;
+
+public class AttachPrimaryDataStoreCmd extends Command implements StorageSubSystemCommand {
+ private final PrimaryDataStoreTO dataStore;
+ public AttachPrimaryDataStoreCmd(PrimaryDataStoreInfo dataStore) {
+ this.dataStore = new PrimaryDataStoreTO(dataStore);
+ }
+
+ public PrimaryDataStoreTO getDataStore() {
+ return this.dataStore;
+ }
+
+ @Override
+ public boolean executeInSequence() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java
----------------------------------------------------------------------
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 dc304a1..7f55797 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
@@ -23,12 +23,15 @@ import java.util.Map;
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
+import org.apache.cloudstack.storage.EndPoint;
+import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd;
import org.apache.cloudstack.storage.datastore.DataStoreStatus;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle {
- protected PrimaryDataStoreInfo dataStore;
+ protected PrimaryDataStore dataStore;
protected PrimaryDataStoreDao dataStoreDao;
public DefaultPrimaryDataStoreLifeCycleImpl(PrimaryDataStoreDao dataStoreDao) {
this.dataStoreDao = dataStoreDao;
@@ -36,7 +39,7 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif
@Override
public void setDataStore(PrimaryDataStoreInfo dataStore) {
- this.dataStore = dataStore;
+ this.dataStore = (PrimaryDataStore)dataStore;
}
@Override
@@ -50,11 +53,18 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif
@Override
public boolean attachCluster(ClusterScope scope) {
- PrimaryDataStoreVO dataStore = dataStoreDao.findById(this.dataStore.getId());
- dataStore.setDataCenterId(scope.getZoneId());
- dataStore.setPodId(scope.getPodId());
- dataStore.setClusterId(scope.getScopeId());
- dataStoreDao.update(this.dataStore.getId(), dataStore);
+ 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;
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 611913a..9cd1bf6 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -5042,7 +5042,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
boolean add = cmd.getAdd();
if( add ) {
try {
- SR sr = getStorageRepository(conn, pool);
+ SR sr = getStorageRepository(conn, pool.getUuid());
setupHeartbeatSr(conn, sr, false);
long capacity = sr.getPhysicalSize(conn);
long available = capacity - sr.getPhysicalUtilisation(conn);
@@ -5065,7 +5065,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
} else {
try {
- SR sr = getStorageRepository(conn, pool);
+ SR sr = getStorageRepository(conn, pool.getUuid());
String srUuid = sr.getUuid(conn);
String result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.uuid, "sr", srUuid, "add", "false");
if (result == null || !result.split("#")[1].equals("0")) {
@@ -5330,7 +5330,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
Connection conn = getConnection();
StorageFilerTO poolTO = cmd.getPool();
try {
- SR sr = getStorageRepository(conn, poolTO);
+ SR sr = getStorageRepository(conn, poolTO.getUuid());
removeSR(conn, sr);
Answer answer = new Answer(cmd, true, "success");
return answer;
@@ -5587,7 +5587,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
DiskProfile dskch = cmd.getDiskCharacteristics();
VDI vdi = null;
try {
- SR poolSr = getStorageRepository(conn, pool);
+ SR poolSr = getStorageRepository(conn, pool.getUuid());
if (cmd.getTemplateUrl() != null) {
VDI tmpltvdi = null;
@@ -5973,7 +5973,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
String remoteVolumesMountPath = uri.getHost() + ":" + uri.getPath() + "/volumes/";
String volumeFolder = String.valueOf(cmd.getVolumeId()) + "/";
String mountpoint = remoteVolumesMountPath + volumeFolder;
- SR primaryStoragePool = getStorageRepository(conn, poolTO);
+ SR primaryStoragePool = getStorageRepository(conn, poolTO.getUuid());
String srUuid = primaryStoragePool.getUuid(conn);
if (toSecondaryStorage) {
// Create the volume folder
@@ -6685,30 +6685,30 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
}
- protected SR getStorageRepository(Connection conn, StorageFilerTO pool) {
+ protected SR getStorageRepository(Connection conn, String uuid) {
Set<SR> srs;
try {
- srs = SR.getByNameLabel(conn, pool.getUuid());
+ srs = SR.getByNameLabel(conn, uuid);
} catch (XenAPIException e) {
- throw new CloudRuntimeException("Unable to get SR " + pool.getUuid() + " due to " + e.toString(), e);
+ throw new CloudRuntimeException("Unable to get SR " + uuid + " due to " + e.toString(), e);
} catch (Exception e) {
- throw new CloudRuntimeException("Unable to get SR " + pool.getUuid() + " due to " + e.getMessage(), e);
+ throw new CloudRuntimeException("Unable to get SR " + uuid + " due to " + e.getMessage(), e);
}
if (srs.size() > 1) {
- throw new CloudRuntimeException("More than one storage repository was found for pool with uuid: " + pool.getUuid());
+ throw new CloudRuntimeException("More than one storage repository was found for pool with uuid: " + uuid);
} else if (srs.size() == 1) {
SR sr = srs.iterator().next();
if (s_logger.isDebugEnabled()) {
- s_logger.debug("SR retrieved for " + pool.getId());
+ s_logger.debug("SR retrieved for " + uuid);
}
if (checkSR(conn, sr)) {
return sr;
}
- throw new CloudRuntimeException("SR check failed for storage pool: " + pool.getUuid() + "on host:" + _host.uuid);
+ throw new CloudRuntimeException("SR check failed for storage pool: " + uuid + "on host:" + _host.uuid);
} else {
- throw new CloudRuntimeException("Can not see storage pool: " + pool.getUuid() + " from on host:" + _host.uuid);
+ throw new CloudRuntimeException("Can not see storage pool: " + uuid + " from on host:" + _host.uuid);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/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 8789bb7..f47b080 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
@@ -28,6 +28,8 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
+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.StorageSubSystemCommand;
@@ -51,7 +53,10 @@ import org.apache.xmlrpc.XmlRpcException;
import com.cloud.agent.api.Answer;
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.storage.template.TemplateInfo;
import com.cloud.utils.exception.CloudRuntimeException;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.PBD;
@@ -72,11 +77,25 @@ public class XenServerStorageResource {
public Answer handleStorageCommands(StorageSubSystemCommand command) {
if (command instanceof CopyTemplateToPrimaryStorageCmd) {
return this.execute((CopyTemplateToPrimaryStorageCmd)command);
+ } else if (command instanceof AttachPrimaryDataStoreCmd) {
+ return this.execute((AttachPrimaryDataStoreCmd)command);
}
return new Answer((Command)command, false, "not implemented yet");
}
- private long getTemplateSize(String url) {
+ private long getTemplateSize(Connection conn, String url) {
+ String size = hypervisorResource.callHostPlugin(conn, "storagePlugin", "getTemplateSize", "srcUrl", url);
+ if (size == "" || size == null) {
+ throw new CloudRuntimeException("Can't get template size");
+ }
+
+ try {
+ return Long.parseLong(size);
+ } catch (NumberFormatException e) {
+ throw new CloudRuntimeException("Failed to get template lenght", e);
+ }
+
+ /*
HttpHead method = new HttpHead(url);
DefaultHttpClient client = new DefaultHttpClient();
try {
@@ -93,7 +112,7 @@ public class XenServerStorageResource {
throw new CloudRuntimeException("Failed to get template lenght", e);
} catch (NumberFormatException e) {
throw new CloudRuntimeException("Failed to get template lenght", e);
- }
+ }*/
}
private void downloadHttpToLocalFile(String destFilePath, String url) {
@@ -143,17 +162,17 @@ public class XenServerStorageResource {
boolean result = false;
try {
- Set<SR> srs = SR.getByNameLabel(conn, primaryStoreUuid);
- if (srs.size() != 1) {
+ SR sr = SR.getByUuid(conn, primaryStoreUuid);
+ if (sr == null) {
throw new CloudRuntimeException("storage uuid: " + primaryStoreUuid + " is not unique");
}
- poolsr = srs.iterator().next();
+ poolsr = sr;
VDI.Record vdir = new VDI.Record();
vdir.nameLabel = "Base-Image-" + UUID.randomUUID().toString();
vdir.SR = poolsr;
vdir.type = Types.VdiType.USER;
- vdir.virtualSize = getTemplateSize(template.getPath());
+ vdir.virtualSize = getTemplateSize(conn, template.getPath());
vdi = VDI.create(conn, vdir);
vdir = vdi.getRecord(conn);
@@ -172,7 +191,7 @@ public class XenServerStorageResource {
String vdiPath = pbdLocation + "/" + vdiLocation + ".vhd";
//download a url into vdipath
//downloadHttpToLocalFile(vdiPath, template.getPath());
- hypervisorResource.callHostPlugin(conn, "vmopsStorage", "downloadTemplateFromUrl", "destPath", vdiPath, "srcUrl", template.getPath());
+ hypervisorResource.callHostPlugin(conn, "storagePlugin", "downloadTemplateFromUrl", "destPath", vdiPath, "srcUrl", template.getPath());
result = true;
return new CopyTemplateToPrimaryStorageAnswer(cmd, vdi.getUuid(conn));
} catch (BadServerResponse e) {
@@ -199,6 +218,35 @@ public class XenServerStorageResource {
return new Answer(cmd, false, "Failed to download template");
}
+ protected Answer execute(AttachPrimaryDataStoreCmd cmd) {
+ PrimaryDataStoreTO dataStore = cmd.getDataStore();
+ Connection conn = hypervisorResource.getConnection();
+ try {
+ SR sr = hypervisorResource.getStorageRepository(conn, dataStore.getUuid());
+ hypervisorResource.setupHeartbeatSr(conn, sr, false);
+ long capacity = sr.getPhysicalSize(conn);
+ long available = capacity - sr.getPhysicalUtilisation(conn);
+ if (capacity == -1) {
+ String msg = "Pool capacity is -1! pool: ";
+ s_logger.warn(msg);
+ return new Answer(cmd, false, msg);
+ }
+ AttachPrimaryDataStoreAnswer answer = new AttachPrimaryDataStoreAnswer(cmd);
+ answer.setCapacity(capacity);
+ answer.setUuid(sr.getUuid(conn));
+ answer.setAvailable(available);
+ return answer;
+ } catch (XenAPIException e) {
+ String msg = "AttachPrimaryDataStoreCmd add XenAPIException:" + e.toString();
+ s_logger.warn(msg, e);
+ return new Answer(cmd, false, msg);
+ } catch (Exception e) {
+ String msg = "AttachPrimaryDataStoreCmd failed:" + e.getMessage();
+ s_logger.warn(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+ }
+
protected Answer execute(CopyTemplateToPrimaryStorageCmd cmd) {
ImageOnPrimayDataStoreTO imageTO = cmd.getImage();
TemplateTO template = imageTO.getTemplate();
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/scripts/vm/hypervisor/xenserver/mockxcpplugin.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/mockxcpplugin.py b/scripts/vm/hypervisor/xenserver/mockxcpplugin.py
new file mode 100644
index 0000000..0de24ca
--- /dev/null
+++ b/scripts/vm/hypervisor/xenserver/mockxcpplugin.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+# 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.
+
+# This is for test purpose, to test xcp plugin
+
+import sys
+import XenAPI
+import os.path
+import traceback
+import socket
+def getHost():
+ hostname = socket.gethostname()
+ url = "http://localhost"
+ session = XenAPI.Session(url)
+ session.xenapi.login_with_password("root", "password")
+ host = session.xenapi.host
+ hosts = session.xenapi.host.get_by_name_label(hostname)
+ if len(hosts) != 1:
+ print "can't find host:" + hostname
+ sys.exit(1)
+ localhost = hosts[0]
+ return [host, localhost]
+
+def callPlugin(pluginName, func, params):
+ hostPair = getHost()
+ host = hostPair[0]
+ localhost = hostPair[1]
+ return host.call_plugin(localhost, pluginName, func, params)
+
+def main():
+ if len(sys.argv) < 3:
+ print "args: pluginName funcName params"
+ sys.exit(1)
+
+ pluginName = sys.argv[1]
+ funcName = sys.argv[2]
+
+ paramList = sys.argv[3:]
+ if (len(paramList) % 2) != 0:
+ print "params must be name/value pair"
+ sys.exit(2)
+ params = {}
+ pos = 0;
+ for i in range(len(paramList) / 2):
+ params[str(paramList[pos])] = str(paramList[pos+1])
+ pos = pos + 2
+ print "call: " + pluginName + " " + funcName + ", with params: " + str(params)
+ print "return: " + callPlugin(pluginName, funcName, params)
+
+if __name__ == "__main__":
+ main()
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/scripts/vm/hypervisor/xenserver/storagePlugin
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/storagePlugin b/scripts/vm/hypervisor/xenserver/storagePlugin
index df1c340..7cb6e35 100755
--- a/scripts/vm/hypervisor/xenserver/storagePlugin
+++ b/scripts/vm/hypervisor/xenserver/storagePlugin
@@ -22,24 +22,23 @@
import os, sys, time
import XenAPIPlugin
-sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"])
+sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"])
+import util
import base64
-import hostvmstats
import socket
import stat
import tempfile
-import util
import subprocess
import zlib
import urllib2
-from util import CommandException
+import traceback
def echo(fn):
def wrapped(*v, **k):
name = fn.__name__
- util.SMlog("#### VMOPS enter %s ####" % name )
+ util.SMlog("#### xen plugin enter %s ####" % name )
res = fn(*v, **k)
- util.SMlog("#### VMOPS exit %s ####" % name )
+ util.SMlog("#### xen plugin exit %s ####" % name )
return res
return wrapped
@@ -47,10 +46,26 @@ def echo(fn):
def downloadTemplateFromUrl(session, args):
destPath = args["destPath"]
srcUrl = args["srcUrl"]
- template = urllib2.urlopen(srcUrl)
- destFile = open(destPath, "wb")
- destFile.write(template.read())
- destFile.close()
+ try:
+ template = urllib2.urlopen(srcUrl)
+ destFile = open(destPath, "wb")
+ destFile.write(template.read())
+ destFile.close()
+ return "success"
+ except:
+ util.SMlog("exception: " + str(sys.exc_info()))
+ return ""
+@echo
+def getTemplateSize(session, args):
+ srcUrl = args["srcUrl"]
+ try:
+ template = urllib2.urlopen(srcUrl)
+ headers = template.info()
+ return str(headers["Content-Length"])
+ except:
+ return ""
if __name__ == "__main__":
- XenAPIPlugin.dispatch({"downloadTemplateFromUrl": downloadTemplateFromUrl})
+ XenAPIPlugin.dispatch({"downloadTemplateFromUrl": downloadTemplateFromUrl
+ ,"getTemplateSize": getTemplateSize
+ })
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ac88c16b/scripts/vm/hypervisor/xenserver/xcposs/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xcposs/patch b/scripts/vm/hypervisor/xenserver/xcposs/patch
index 2ab9421..1b615b7 100644
--- a/scripts/vm/hypervisor/xenserver/xcposs/patch
+++ b/scripts/vm/hypervisor/xenserver/xcposs/patch
@@ -64,3 +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