finaly, finish download template to primary storage

This commit is contained in:
Edison Su 2012-12-20 19:05:47 -08:00
parent 1d5019c3d0
commit ac88c16be6
16 changed files with 447 additions and 60 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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");

View File

@ -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);
}

View File

@ -43,23 +43,21 @@ public class HypervisorHostEndPoint implements EndPoint {
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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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();

View 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()

View File

@ -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
})

View File

@ -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