mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-16 10:32:34 +01:00
finaly, finish download template to primary storage
This commit is contained in:
parent
1d5019c3d0
commit
ac88c16be6
@ -31,12 +31,14 @@ import com.cloud.agent.Listener;
|
|||||||
import com.cloud.agent.StartupCommandProcessor;
|
import com.cloud.agent.StartupCommandProcessor;
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
|
import com.cloud.agent.api.SetupCommand;
|
||||||
import com.cloud.agent.api.StartupCommand;
|
import com.cloud.agent.api.StartupCommand;
|
||||||
import com.cloud.agent.manager.AgentAttache;
|
import com.cloud.agent.manager.AgentAttache;
|
||||||
import com.cloud.agent.manager.Commands;
|
import com.cloud.agent.manager.Commands;
|
||||||
import com.cloud.exception.AgentUnavailableException;
|
import com.cloud.exception.AgentUnavailableException;
|
||||||
import com.cloud.exception.ConnectionException;
|
import com.cloud.exception.ConnectionException;
|
||||||
import com.cloud.exception.OperationTimedoutException;
|
import com.cloud.exception.OperationTimedoutException;
|
||||||
|
import com.cloud.host.HostEnvironment;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
import com.cloud.host.Status.Event;
|
import com.cloud.host.Status.Event;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
@ -100,6 +102,11 @@ public class DirectAgentManagerSimpleImpl implements AgentManager {
|
|||||||
} catch (ConfigurationException e) {
|
} catch (ConfigurationException e) {
|
||||||
logger.debug("Failed to load resource:" + e.toString());
|
logger.debug("Failed to load resource:" + e.toString());
|
||||||
}
|
}
|
||||||
|
HostEnvironment env = new HostEnvironment();
|
||||||
|
SetupCommand cmd = new SetupCommand(env);
|
||||||
|
cmd.setNeedSetup(true);
|
||||||
|
|
||||||
|
resource.executeRequest(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -69,7 +69,7 @@ public class DirectAgentTest {
|
|||||||
private long dcId;
|
private long dcId;
|
||||||
private long clusterId;
|
private long clusterId;
|
||||||
private long hostId;
|
private long hostId;
|
||||||
private String hostGuid = "759ee4c9-a15a-297b-67c6-ac267d8aa429";
|
private String hostGuid = "9d4c9db8-32f7-25c3-0435-eab4bf3adcea";
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
HostVO host = hostDao.findByGuid(hostGuid);
|
HostVO host = hostDao.findByGuid(hostGuid);
|
||||||
@ -102,7 +102,7 @@ public class DirectAgentTest {
|
|||||||
host.setName("devcloud xen host");
|
host.setName("devcloud xen host");
|
||||||
host.setType(Host.Type.Routing);
|
host.setType(Host.Type.Routing);
|
||||||
host.setHypervisorType(HypervisorType.XenServer);
|
host.setHypervisorType(HypervisorType.XenServer);
|
||||||
host.setPrivateIpAddress("192.168.56.2");
|
host.setPrivateIpAddress("192.168.56.10");
|
||||||
host.setDataCenterId(dc.getId());
|
host.setDataCenterId(dc.getId());
|
||||||
host.setVersion("6.0.1");
|
host.setVersion("6.0.1");
|
||||||
host.setAvailable(true);
|
host.setAvailable(true);
|
||||||
@ -133,7 +133,7 @@ public class DirectAgentTest {
|
|||||||
public void testDownloadTemplate() {
|
public void testDownloadTemplate() {
|
||||||
ImageOnPrimayDataStoreTO image = Mockito.mock(ImageOnPrimayDataStoreTO.class);
|
ImageOnPrimayDataStoreTO image = Mockito.mock(ImageOnPrimayDataStoreTO.class);
|
||||||
PrimaryDataStoreTO primaryStore = Mockito.mock(PrimaryDataStoreTO.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);
|
Mockito.when(image.getPrimaryDataStore()).thenReturn(primaryStore);
|
||||||
|
|
||||||
ImageDataStoreTO imageStore = Mockito.mock(ImageDataStoreTO.class);
|
ImageDataStoreTO imageStore = Mockito.mock(ImageDataStoreTO.class);
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||||
import org.apache.cloudstack.storage.HostEndpointRpcServer;
|
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.CopyTemplateToPrimaryStorageCmd;
|
||||||
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer;
|
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer;
|
||||||
import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
|
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);
|
executor.schedule(new MockRpcCallBack(command, callback), 10, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Answer sendCommand(HypervisorHostEndPoint host, Command command) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -158,7 +158,7 @@ public class volumeServiceTest {
|
|||||||
HostVO host = new HostVO(UUID.randomUUID().toString());
|
HostVO host = new HostVO(UUID.randomUUID().toString());
|
||||||
host.setName("devcloud xen host");
|
host.setName("devcloud xen host");
|
||||||
host.setType(Host.Type.Routing);
|
host.setType(Host.Type.Routing);
|
||||||
host.setPrivateIpAddress("192.168.56.2");
|
host.setPrivateIpAddress("192.168.56.10");
|
||||||
host.setDataCenterId(dc.getId());
|
host.setDataCenterId(dc.getId());
|
||||||
host.setVersion("6.0.1");
|
host.setVersion("6.0.1");
|
||||||
host.setAvailable(true);
|
host.setAvailable(true);
|
||||||
@ -237,7 +237,7 @@ public class volumeServiceTest {
|
|||||||
PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("default primary data store provider");
|
PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("default primary data store provider");
|
||||||
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
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("dcId", dcId.toString());
|
||||||
params.put("clusterId", clusterId.toString());
|
params.put("clusterId", clusterId.toString());
|
||||||
params.put("name", "my primary data store");
|
params.put("name", "my primary data store");
|
||||||
|
|||||||
@ -24,5 +24,6 @@ import com.cloud.agent.api.Answer;
|
|||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
|
|
||||||
public interface HostEndpointRpcServer {
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,23 +43,21 @@ public class HypervisorHostEndPoint implements EndPoint {
|
|||||||
this.hostAddress = hostAddress;
|
this.hostAddress = hostAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHostAddr() {
|
||||||
|
return this.hostAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getHostId() {
|
||||||
|
return this.hostId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Answer sendMessage(Command cmd) {
|
public Answer sendMessage(Command cmd) {
|
||||||
Answer answer = null;
|
return rpcServer.sendCommand(this, cmd);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback) {
|
public void sendMessageAsync(Command cmd, AsyncCompletionCallback<Answer> callback) {
|
||||||
rpcServer.sendCommandAsync(this.hostAddress, cmd, callback);
|
rpcServer.sendCommandAsync(this, cmd, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,19 +20,23 @@ package org.apache.cloudstack.storage;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
|
||||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
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.RpcCallbackListener;
|
||||||
import org.apache.cloudstack.framework.rpc.RpcException;
|
import org.apache.cloudstack.framework.rpc.RpcException;
|
||||||
import org.apache.cloudstack.framework.rpc.RpcProvider;
|
import org.apache.cloudstack.framework.rpc.RpcProvider;
|
||||||
import org.apache.cloudstack.framework.rpc.RpcServiceDispatcher;
|
import org.apache.cloudstack.framework.rpc.RpcServiceDispatcher;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer {
|
public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer {
|
||||||
|
private static final Logger s_logger = Logger.getLogger(HypervsiorHostEndPointRpcServer.class);
|
||||||
private RpcProvider _rpcProvider;
|
private RpcProvider _rpcProvider;
|
||||||
@Inject
|
@Inject
|
||||||
public HypervsiorHostEndPointRpcServer(RpcProvider rpcProvider) {
|
public HypervsiorHostEndPointRpcServer(RpcProvider rpcProvider) {
|
||||||
@ -41,8 +45,8 @@ public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCommandAsync(String host, final Command command, final AsyncCompletionCallback<Answer> callback) {
|
public void sendCommandAsync(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback<Answer> callback) {
|
||||||
_rpcProvider.newCall(host).addCallbackListener(new RpcCallbackListener<Answer>() {
|
_rpcProvider.newCall(host.getHostAddr()).addCallbackListener(new RpcCallbackListener<Answer>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Answer result) {
|
public void onSuccess(Answer result) {
|
||||||
callback.complete(result);
|
callback.complete(result);
|
||||||
@ -55,4 +59,50 @@ public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer {
|
|||||||
}
|
}
|
||||||
}).apply();
|
}).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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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.ClusterScope;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
|
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.DataStoreStatus;
|
||||||
|
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
|
||||||
|
|
||||||
public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle {
|
public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle {
|
||||||
protected PrimaryDataStoreInfo dataStore;
|
protected PrimaryDataStore dataStore;
|
||||||
protected PrimaryDataStoreDao dataStoreDao;
|
protected PrimaryDataStoreDao dataStoreDao;
|
||||||
public DefaultPrimaryDataStoreLifeCycleImpl(PrimaryDataStoreDao dataStoreDao) {
|
public DefaultPrimaryDataStoreLifeCycleImpl(PrimaryDataStoreDao dataStoreDao) {
|
||||||
this.dataStoreDao = dataStoreDao;
|
this.dataStoreDao = dataStoreDao;
|
||||||
@ -36,7 +39,7 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDataStore(PrimaryDataStoreInfo dataStore) {
|
public void setDataStore(PrimaryDataStoreInfo dataStore) {
|
||||||
this.dataStore = dataStore;
|
this.dataStore = (PrimaryDataStore)dataStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -50,11 +53,18 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean attachCluster(ClusterScope scope) {
|
public boolean attachCluster(ClusterScope scope) {
|
||||||
PrimaryDataStoreVO dataStore = dataStoreDao.findById(this.dataStore.getId());
|
PrimaryDataStoreVO dataStoreVO = dataStoreDao.findById(this.dataStore.getId());
|
||||||
dataStore.setDataCenterId(scope.getZoneId());
|
dataStoreVO.setDataCenterId(scope.getZoneId());
|
||||||
dataStore.setPodId(scope.getPodId());
|
dataStoreVO.setPodId(scope.getPodId());
|
||||||
dataStore.setClusterId(scope.getScopeId());
|
dataStoreVO.setClusterId(scope.getScopeId());
|
||||||
dataStoreDao.update(this.dataStore.getId(), dataStore);
|
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 false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5042,7 +5042,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||||||
boolean add = cmd.getAdd();
|
boolean add = cmd.getAdd();
|
||||||
if( add ) {
|
if( add ) {
|
||||||
try {
|
try {
|
||||||
SR sr = getStorageRepository(conn, pool);
|
SR sr = getStorageRepository(conn, pool.getUuid());
|
||||||
setupHeartbeatSr(conn, sr, false);
|
setupHeartbeatSr(conn, sr, false);
|
||||||
long capacity = sr.getPhysicalSize(conn);
|
long capacity = sr.getPhysicalSize(conn);
|
||||||
long available = capacity - sr.getPhysicalUtilisation(conn);
|
long available = capacity - sr.getPhysicalUtilisation(conn);
|
||||||
@ -5065,7 +5065,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
SR sr = getStorageRepository(conn, pool);
|
SR sr = getStorageRepository(conn, pool.getUuid());
|
||||||
String srUuid = sr.getUuid(conn);
|
String srUuid = sr.getUuid(conn);
|
||||||
String result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.uuid, "sr", srUuid, "add", "false");
|
String result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.uuid, "sr", srUuid, "add", "false");
|
||||||
if (result == null || !result.split("#")[1].equals("0")) {
|
if (result == null || !result.split("#")[1].equals("0")) {
|
||||||
@ -5330,7 +5330,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||||||
Connection conn = getConnection();
|
Connection conn = getConnection();
|
||||||
StorageFilerTO poolTO = cmd.getPool();
|
StorageFilerTO poolTO = cmd.getPool();
|
||||||
try {
|
try {
|
||||||
SR sr = getStorageRepository(conn, poolTO);
|
SR sr = getStorageRepository(conn, poolTO.getUuid());
|
||||||
removeSR(conn, sr);
|
removeSR(conn, sr);
|
||||||
Answer answer = new Answer(cmd, true, "success");
|
Answer answer = new Answer(cmd, true, "success");
|
||||||
return answer;
|
return answer;
|
||||||
@ -5587,7 +5587,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||||||
DiskProfile dskch = cmd.getDiskCharacteristics();
|
DiskProfile dskch = cmd.getDiskCharacteristics();
|
||||||
VDI vdi = null;
|
VDI vdi = null;
|
||||||
try {
|
try {
|
||||||
SR poolSr = getStorageRepository(conn, pool);
|
SR poolSr = getStorageRepository(conn, pool.getUuid());
|
||||||
if (cmd.getTemplateUrl() != null) {
|
if (cmd.getTemplateUrl() != null) {
|
||||||
VDI tmpltvdi = null;
|
VDI tmpltvdi = null;
|
||||||
|
|
||||||
@ -5973,7 +5973,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||||||
String remoteVolumesMountPath = uri.getHost() + ":" + uri.getPath() + "/volumes/";
|
String remoteVolumesMountPath = uri.getHost() + ":" + uri.getPath() + "/volumes/";
|
||||||
String volumeFolder = String.valueOf(cmd.getVolumeId()) + "/";
|
String volumeFolder = String.valueOf(cmd.getVolumeId()) + "/";
|
||||||
String mountpoint = remoteVolumesMountPath + volumeFolder;
|
String mountpoint = remoteVolumesMountPath + volumeFolder;
|
||||||
SR primaryStoragePool = getStorageRepository(conn, poolTO);
|
SR primaryStoragePool = getStorageRepository(conn, poolTO.getUuid());
|
||||||
String srUuid = primaryStoragePool.getUuid(conn);
|
String srUuid = primaryStoragePool.getUuid(conn);
|
||||||
if (toSecondaryStorage) {
|
if (toSecondaryStorage) {
|
||||||
// Create the volume folder
|
// 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;
|
Set<SR> srs;
|
||||||
try {
|
try {
|
||||||
srs = SR.getByNameLabel(conn, pool.getUuid());
|
srs = SR.getByNameLabel(conn, uuid);
|
||||||
} catch (XenAPIException e) {
|
} 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) {
|
} 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) {
|
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) {
|
} else if (srs.size() == 1) {
|
||||||
SR sr = srs.iterator().next();
|
SR sr = srs.iterator().next();
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("SR retrieved for " + pool.getId());
|
s_logger.debug("SR retrieved for " + uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkSR(conn, sr)) {
|
if (checkSR(conn, sr)) {
|
||||||
return 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 {
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,8 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
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.CopyTemplateToPrimaryStorageCmd;
|
||||||
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer;
|
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer;
|
||||||
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
|
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.Answer;
|
||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
|
import com.cloud.agent.api.ModifyStoragePoolAnswer;
|
||||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
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.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.xensource.xenapi.Connection;
|
import com.xensource.xenapi.Connection;
|
||||||
import com.xensource.xenapi.PBD;
|
import com.xensource.xenapi.PBD;
|
||||||
@ -72,11 +77,25 @@ public class XenServerStorageResource {
|
|||||||
public Answer handleStorageCommands(StorageSubSystemCommand command) {
|
public Answer handleStorageCommands(StorageSubSystemCommand command) {
|
||||||
if (command instanceof CopyTemplateToPrimaryStorageCmd) {
|
if (command instanceof CopyTemplateToPrimaryStorageCmd) {
|
||||||
return this.execute((CopyTemplateToPrimaryStorageCmd)command);
|
return this.execute((CopyTemplateToPrimaryStorageCmd)command);
|
||||||
|
} else if (command instanceof AttachPrimaryDataStoreCmd) {
|
||||||
|
return this.execute((AttachPrimaryDataStoreCmd)command);
|
||||||
}
|
}
|
||||||
return new Answer((Command)command, false, "not implemented yet");
|
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);
|
HttpHead method = new HttpHead(url);
|
||||||
DefaultHttpClient client = new DefaultHttpClient();
|
DefaultHttpClient client = new DefaultHttpClient();
|
||||||
try {
|
try {
|
||||||
@ -93,7 +112,7 @@ public class XenServerStorageResource {
|
|||||||
throw new CloudRuntimeException("Failed to get template lenght", e);
|
throw new CloudRuntimeException("Failed to get template lenght", e);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new CloudRuntimeException("Failed to get template lenght", e);
|
throw new CloudRuntimeException("Failed to get template lenght", e);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadHttpToLocalFile(String destFilePath, String url) {
|
private void downloadHttpToLocalFile(String destFilePath, String url) {
|
||||||
@ -143,17 +162,17 @@ public class XenServerStorageResource {
|
|||||||
boolean result = false;
|
boolean result = false;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
Set<SR> srs = SR.getByNameLabel(conn, primaryStoreUuid);
|
SR sr = SR.getByUuid(conn, primaryStoreUuid);
|
||||||
if (srs.size() != 1) {
|
if (sr == null) {
|
||||||
throw new CloudRuntimeException("storage uuid: " + primaryStoreUuid + " is not unique");
|
throw new CloudRuntimeException("storage uuid: " + primaryStoreUuid + " is not unique");
|
||||||
}
|
}
|
||||||
poolsr = srs.iterator().next();
|
poolsr = sr;
|
||||||
VDI.Record vdir = new VDI.Record();
|
VDI.Record vdir = new VDI.Record();
|
||||||
vdir.nameLabel = "Base-Image-" + UUID.randomUUID().toString();
|
vdir.nameLabel = "Base-Image-" + UUID.randomUUID().toString();
|
||||||
vdir.SR = poolsr;
|
vdir.SR = poolsr;
|
||||||
vdir.type = Types.VdiType.USER;
|
vdir.type = Types.VdiType.USER;
|
||||||
|
|
||||||
vdir.virtualSize = getTemplateSize(template.getPath());
|
vdir.virtualSize = getTemplateSize(conn, template.getPath());
|
||||||
vdi = VDI.create(conn, vdir);
|
vdi = VDI.create(conn, vdir);
|
||||||
|
|
||||||
vdir = vdi.getRecord(conn);
|
vdir = vdi.getRecord(conn);
|
||||||
@ -172,7 +191,7 @@ public class XenServerStorageResource {
|
|||||||
String vdiPath = pbdLocation + "/" + vdiLocation + ".vhd";
|
String vdiPath = pbdLocation + "/" + vdiLocation + ".vhd";
|
||||||
//download a url into vdipath
|
//download a url into vdipath
|
||||||
//downloadHttpToLocalFile(vdiPath, template.getPath());
|
//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;
|
result = true;
|
||||||
return new CopyTemplateToPrimaryStorageAnswer(cmd, vdi.getUuid(conn));
|
return new CopyTemplateToPrimaryStorageAnswer(cmd, vdi.getUuid(conn));
|
||||||
} catch (BadServerResponse e) {
|
} catch (BadServerResponse e) {
|
||||||
@ -199,6 +218,35 @@ public class XenServerStorageResource {
|
|||||||
return new Answer(cmd, false, "Failed to download template");
|
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) {
|
protected Answer execute(CopyTemplateToPrimaryStorageCmd cmd) {
|
||||||
ImageOnPrimayDataStoreTO imageTO = cmd.getImage();
|
ImageOnPrimayDataStoreTO imageTO = cmd.getImage();
|
||||||
TemplateTO template = imageTO.getTemplate();
|
TemplateTO template = imageTO.getTemplate();
|
||||||
|
|||||||
66
scripts/vm/hypervisor/xenserver/mockxcpplugin.py
Normal file
66
scripts/vm/hypervisor/xenserver/mockxcpplugin.py
Normal file
@ -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()
|
||||||
@ -22,24 +22,23 @@
|
|||||||
|
|
||||||
import os, sys, time
|
import os, sys, time
|
||||||
import XenAPIPlugin
|
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 base64
|
||||||
import hostvmstats
|
|
||||||
import socket
|
import socket
|
||||||
import stat
|
import stat
|
||||||
import tempfile
|
import tempfile
|
||||||
import util
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import zlib
|
import zlib
|
||||||
import urllib2
|
import urllib2
|
||||||
from util import CommandException
|
import traceback
|
||||||
|
|
||||||
def echo(fn):
|
def echo(fn):
|
||||||
def wrapped(*v, **k):
|
def wrapped(*v, **k):
|
||||||
name = fn.__name__
|
name = fn.__name__
|
||||||
util.SMlog("#### VMOPS enter %s ####" % name )
|
util.SMlog("#### xen plugin enter %s ####" % name )
|
||||||
res = fn(*v, **k)
|
res = fn(*v, **k)
|
||||||
util.SMlog("#### VMOPS exit %s ####" % name )
|
util.SMlog("#### xen plugin exit %s ####" % name )
|
||||||
return res
|
return res
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
@ -47,10 +46,26 @@ def echo(fn):
|
|||||||
def downloadTemplateFromUrl(session, args):
|
def downloadTemplateFromUrl(session, args):
|
||||||
destPath = args["destPath"]
|
destPath = args["destPath"]
|
||||||
srcUrl = args["srcUrl"]
|
srcUrl = args["srcUrl"]
|
||||||
|
try:
|
||||||
template = urllib2.urlopen(srcUrl)
|
template = urllib2.urlopen(srcUrl)
|
||||||
destFile = open(destPath, "wb")
|
destFile = open(destPath, "wb")
|
||||||
destFile.write(template.read())
|
destFile.write(template.read())
|
||||||
destFile.close()
|
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__":
|
if __name__ == "__main__":
|
||||||
XenAPIPlugin.dispatch({"downloadTemplateFromUrl": downloadTemplateFromUrl})
|
XenAPIPlugin.dispatch({"downloadTemplateFromUrl": downloadTemplateFromUrl
|
||||||
|
,"getTemplateSize": getTemplateSize
|
||||||
|
})
|
||||||
|
|||||||
@ -64,3 +64,4 @@ cloud-prepare-upgrade.sh=..,0755,/usr/lib/xcp/bin
|
|||||||
getRouterStatus.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin
|
getRouterStatus.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin
|
||||||
bumpUpPriority.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
|
getDomRVersion.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin
|
||||||
|
storagePlugin=.,0755,/usr/lib/xcp/plugins
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user