You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2015/03/12 07:05:01 UTC
[09/12] git commit: updated refs/heads/master to c27c694
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3FenceBuilder.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3FenceBuilder.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3FenceBuilder.java
new file mode 100755
index 0000000..b297cc9
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3FenceBuilder.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * 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 com.cloud.hypervisor.ovm3.resources;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.ha.FenceBuilder;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.VirtualMachine;
+
+@Local(value = FenceBuilder.class)
+public class Ovm3FenceBuilder extends AdapterBase implements FenceBuilder {
+ Map<String, Object> fenceParams;
+ private static final Logger LOGGER = Logger.getLogger(Ovm3FenceBuilder.class);
+ @Inject
+ AgentManager agentMgr;
+ @Inject
+ ResourceManager resourceMgr;
+
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ fenceParams = params;
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ /* start the agent here ? */
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ /* stop the agent here ? */
+ return true;
+ }
+
+ public Ovm3FenceBuilder() {
+ super();
+ }
+
+ @Override
+ public Boolean fenceOff(VirtualMachine vm, Host host) {
+ if (host.getHypervisorType() != HypervisorType.Ovm3) {
+ LOGGER.debug("Don't know how to fence non Ovm3 hosts "
+ + host.getHypervisorType());
+ return null;
+ } else {
+ LOGGER.debug("Fencing " + vm + " on host " + host
+ + " with params: "+ fenceParams );
+ }
+
+ List<HostVO> hosts = resourceMgr.listAllHostsInCluster(host
+ .getClusterId());
+ FenceCommand fence = new FenceCommand(vm, host);
+
+ for (HostVO h : hosts) {
+ if (h.getHypervisorType() == HypervisorType.Ovm3 &&
+ h.getStatus() == Status.Up &&
+ h.getId() != host.getId()) {
+ FenceAnswer answer;
+ try {
+ answer = (FenceAnswer) agentMgr.send(h.getId(), fence);
+ } catch (AgentUnavailableException | OperationTimedoutException e) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Moving on to the next host because "
+ + h.toString() + " is unavailable", e);
+ }
+ continue;
+ }
+ if (answer != null && answer.getResult()) {
+ return true;
+ }
+ }
+ }
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Unable to fence off " + vm.toString() + " on "
+ + host.toString());
+ }
+
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorGuru.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorGuru.java
new file mode 100755
index 0000000..526b061
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorGuru.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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 com.cloud.hypervisor.ovm3.resources;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuru;
+import com.cloud.hypervisor.HypervisorGuruBase;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.utils.Pair;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = HypervisorGuru.class)
+public class Ovm3HypervisorGuru extends HypervisorGuruBase implements HypervisorGuru {
+ private final Logger LOGGER = Logger.getLogger(Ovm3HypervisorGuru.class);
+ @Inject
+ GuestOSDao guestOsDao;
+ @Inject
+ EndPointSelector endPointSelector;
+ @Inject
+ HostDao hostDao;
+
+ protected Ovm3HypervisorGuru() {
+ super();
+ }
+
+ @Override
+ public HypervisorType getHypervisorType() {
+ return HypervisorType.Ovm3;
+ }
+
+ @Override
+ public VirtualMachineTO implement(VirtualMachineProfile vm) {
+ VirtualMachineTO to = toVirtualMachineTO(vm);
+ to.setBootloader(vm.getBootLoaderType());
+
+ // Determine the VM's OS description
+ GuestOSVO guestOS = guestOsDao.findById(vm.getVirtualMachine()
+ .getGuestOSId());
+ to.setOs(guestOS.getDisplayName());
+
+ return to;
+ }
+
+ @Override
+ public boolean trackVmHostChange() {
+ return true;
+ }
+
+ /* I dislike the notion of having to place this here, and not being able to just override
+ *
+ * (non-Javadoc)
+ * @see com.cloud.hypervisor.HypervisorGuruBase#getCommandHostDelegation(long, com.cloud.agent.api.Command)
+ */
+ public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
+ LOGGER.debug("getCommandHostDelegation: " + cmd.getClass());
+ if (cmd instanceof StorageSubSystemCommand) {
+ StorageSubSystemCommand c = (StorageSubSystemCommand)cmd;
+ c.setExecuteInSequence(true);
+ }
+ if (cmd instanceof CopyCommand) {
+ CopyCommand cpyCommand = (CopyCommand)cmd;
+ DataTO srcData = cpyCommand.getSrcTO();
+ DataTO destData = cpyCommand.getDestTO();
+
+ if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
+ LOGGER.debug("Snapshot to Template: " + cmd);
+ DataStoreTO srcStore = srcData.getDataStore();
+ DataStoreTO destStore = destData.getDataStore();
+ if (srcStore instanceof NfsTO && destStore instanceof NfsTO) {
+ HostVO host = hostDao.findById(hostId);
+ EndPoint ep = endPointSelector.selectHypervisorHost(new ZoneScope(host.getDataCenterId()));
+ host = hostDao.findById(ep.getId());
+ hostDao.loadDetails(host);
+ // String snapshotHotFixVersion = host.getDetail(XenserverConfigs.XS620HotFix);
+ // if (snapshotHotFixVersion != null && snapshotHotFixVersion.equalsIgnoreCase(XenserverConfigs.XSHotFix62ESP1004)) {
+ return new Pair<Boolean, Long>(Boolean.TRUE, Long.valueOf(ep.getId()));
+ }
+ }
+ }
+ return new Pair<Boolean, Long>(Boolean.FALSE, Long.valueOf(hostId));
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
new file mode 100644
index 0000000..dac8f1c
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
@@ -0,0 +1,596 @@
+/*******************************************************************************
+ * 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 com.cloud.hypervisor.ovm3.resources;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+// import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Common;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3HypervisorNetwork;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3StoragePool;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3VirtualRoutingSupport;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3VmGuestTypes;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3VmSupport;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3HypervisorSupport;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.resource.hypervisor.HypervisorResource;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+/**
+ * Hypervisor related
+ */
+@Local(value = HypervisorResource.class)
+public class Ovm3HypervisorResource extends ServerResourceBase implements
+ HypervisorResource {
+ private static final Logger LOGGER = Logger
+ .getLogger(Ovm3HypervisorResource.class);
+ @Inject
+ private VirtualRoutingResource vrResource;
+ private StorageSubsystemCommandHandler storageHandler;
+ private Connection c;
+ private Ovm3StoragePool storagepool;
+ private Ovm3StorageProcessor storageprocessor;
+ private Ovm3HypervisorSupport hypervisorsupport;
+ private Ovm3VmSupport vmsupport;
+ private Ovm3HypervisorNetwork hypervisornetwork;
+ private Ovm3VirtualRoutingResource virtualroutingresource;
+ private Ovm3VirtualRoutingSupport virtualroutingsupport;
+ private Ovm3Configuration configuration;
+ private Ovm3VmGuestTypes guesttypes;
+ private OvmObject ovmObject = new OvmObject();
+
+ /*
+ * TODO: Add a network map, so we know which tagged interfaces we can remove
+ * and switch to ConcurrentHashMap
+ */
+ private Map<String, Xen.Vm> vmMap = new HashMap<String, Xen.Vm>();
+
+ @Override
+ public Type getType() {
+ return Type.Routing;
+ }
+
+ /*
+ * configure is called before this, does setup of the connection and
+ * gets the params.
+ *
+ * @see com.cloud.resource.ServerResource#initialize()
+ */
+ @Override
+ public StartupCommand[] initialize() {
+ LOGGER.debug("Ovm3 resource intializing");
+ try {
+ StartupRoutingCommand srCmd = new StartupRoutingCommand();
+ StartupStorageCommand ssCmd = new StartupStorageCommand();
+
+ /* here stuff gets completed, but where should state live ? */
+ hypervisorsupport.fillHostInfo(srCmd);
+ hypervisorsupport.vmStateMapClear();
+ LOGGER.debug("Ovm3 pool " + ssCmd + " " + srCmd);
+ return new StartupCommand[] { srCmd, ssCmd };
+ } catch (Exception e) {
+ LOGGER.debug("Ovm3 resource initializes failed", e);
+ return new StartupCommand[] {};
+ }
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ try {
+ /* feels useless somehow */
+ Common test = new Common(c);
+ String ping = "put";
+ String pong = test.echo(ping);
+ if (pong.contains(ping)) {
+ hypervisorsupport.syncState();
+ CloudstackPlugin cSp = new CloudstackPlugin(c);
+ if (!cSp.dom0CheckStorageHealthCheck(configuration .getAgentScriptsDir(),
+ configuration.getAgentCheckStorageScript(),
+ configuration.getCsHostGuid(),
+ configuration.getAgentStorageCheckTimeout(),
+ configuration.getAgentStorageCheckInterval())
+ && !cSp.dom0CheckStorageHealthCheck()) {
+ LOGGER.error("Storage health check not running on "
+ + configuration.getAgentHostname());
+ } else if (cSp.dom0CheckStorageHealthCheck()) {
+ LOGGER.error("Storage health check started on "
+ + configuration.getAgentHostname());
+ } else {
+ LOGGER.debug("Storage health check running on "
+ + configuration.getAgentHostname());
+ }
+ return new PingRoutingCommand(getType(), id,
+ hypervisorsupport.hostVmStateReport());
+ } else {
+ LOGGER.debug("Agent did not respond correctly: " + ping
+ + " but got " + pong);
+ }
+
+ } catch (Ovm3ResourceException | NullPointerException e) {
+ LOGGER.debug("Check agent status failed", e);
+ return null;
+ }
+ return null;
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ Class<? extends Command> clazz = cmd.getClass();
+ LOGGER.debug("executeRequest called: " + cmd.getClass());
+ if (cmd instanceof NetworkElementCommand) {
+ return vrResource.executeRequest((NetworkElementCommand) cmd);
+ } else if (clazz == NetworkRulesSystemVmCommand.class) {
+ return virtualroutingsupport
+ .execute((NetworkRulesSystemVmCommand) cmd);
+ } else if (clazz == CheckSshCommand.class) {
+ return virtualroutingsupport.execute((CheckSshCommand) cmd);
+ } else if (clazz == NetworkUsageCommand.class) {
+ return virtualroutingsupport.execute((NetworkUsageCommand) cmd);
+ /* double check order! */
+ } else if (clazz == CopyCommand.class) {
+ return storageprocessor.execute((CopyCommand) cmd);
+ } else if (cmd instanceof StorageSubSystemCommand) {
+ return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd);
+ } else if (clazz == DeleteCommand.class) {
+ return storageprocessor.execute((DeleteCommand) cmd);
+ } else if (clazz == CreateCommand.class) {
+ return storageprocessor.execute((CreateCommand) cmd);
+ } else if (clazz == CreateObjectCommand.class) {
+ return storageprocessor.execute((CreateObjectCommand) cmd);
+ } else if (clazz == AttachIsoCommand.class) {
+ return storageprocessor.attachIso((AttachCommand) cmd);
+ } else if (clazz == DettachCommand.class) {
+ return storageprocessor.execute((DettachCommand) cmd);
+ } else if (clazz == AttachCommand.class) {
+ return storageprocessor.execute((AttachCommand) cmd);
+ } else if (clazz == CreatePrivateTemplateFromVolumeCommand.class) {
+ return storageprocessor
+ .execute((CreatePrivateTemplateFromVolumeCommand) cmd);
+ } else if (clazz == DestroyCommand.class) {
+ return storageprocessor.execute((DestroyCommand) cmd);
+ } else if (clazz == CopyVolumeCommand.class) {
+ return storageprocessor.execute((CopyVolumeCommand) cmd);
+ } else if (clazz == CreateStoragePoolCommand.class) {
+ return storagepool.execute((CreateStoragePoolCommand) cmd);
+ } else if (clazz == ModifyStoragePoolCommand.class) {
+ return storagepool.execute((ModifyStoragePoolCommand) cmd);
+ } else if (clazz == PrimaryStorageDownloadCommand.class) {
+ return storagepool.execute((PrimaryStorageDownloadCommand) cmd);
+ } else if (clazz == DeleteStoragePoolCommand.class) {
+ return storagepool.execute((DeleteStoragePoolCommand) cmd);
+ } else if (clazz == GetStorageStatsCommand.class) {
+ return storagepool.execute((GetStorageStatsCommand) cmd);
+ } else if (clazz == GetHostStatsCommand.class) {
+ return hypervisorsupport.execute((GetHostStatsCommand) cmd);
+ } else if (clazz == CheckVirtualMachineCommand.class) {
+ return hypervisorsupport.execute((CheckVirtualMachineCommand) cmd);
+ } else if (clazz == MaintainCommand.class) {
+ return hypervisorsupport.execute((MaintainCommand) cmd);
+ } else if (clazz == CheckHealthCommand.class) {
+ return hypervisorsupport.execute((CheckHealthCommand) cmd);
+ } else if (clazz == ReadyCommand.class) {
+ return hypervisorsupport.execute((ReadyCommand) cmd);
+ } else if (clazz == FenceCommand.class) {
+ return hypervisorsupport.execute((FenceCommand) cmd);
+ } else if (clazz == CheckOnHostCommand.class) {
+ return hypervisorsupport.execute((CheckOnHostCommand)cmd);
+ } else if (clazz == PingTestCommand.class) {
+ return hypervisornetwork.execute((PingTestCommand) cmd);
+ } else if (clazz == CheckNetworkCommand.class) {
+ return hypervisornetwork.execute((CheckNetworkCommand) cmd);
+ } else if (clazz == GetVmStatsCommand.class) {
+ return vmsupport.execute((GetVmStatsCommand) cmd);
+ } else if (clazz == PrepareForMigrationCommand.class) {
+ return vmsupport.execute((PrepareForMigrationCommand) cmd);
+ } else if (clazz == MigrateCommand.class) {
+ return vmsupport.execute((MigrateCommand) cmd);
+ } else if (clazz == GetVncPortCommand.class) {
+ return vmsupport.execute((GetVncPortCommand) cmd);
+ } else if (clazz == PlugNicCommand.class) {
+ return vmsupport.execute((PlugNicCommand) cmd);
+ } else if (clazz == UnPlugNicCommand.class) {
+ return vmsupport.execute((UnPlugNicCommand) cmd);
+ } else if (clazz == StartCommand.class) {
+ return execute((StartCommand) cmd);
+ } else if (clazz == StopCommand.class) {
+ return execute((StopCommand) cmd);
+ } else if (clazz == RebootCommand.class) {
+ return execute((RebootCommand) cmd);
+ }
+ LOGGER.debug("Can't find class for executeRequest " + cmd.getClass() +", is your direct call missing?");
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+
+ @Override
+ public void disconnected() {
+ LOGGER.debug("disconnected seems unused everywhere else");
+ }
+
+ @Override
+ public IAgentControl getAgentControl() {
+ LOGGER.debug("we don't use IAgentControl");
+ return null;
+ }
+
+ @Override
+ public void setAgentControl(IAgentControl agentControl) {
+ LOGGER.debug("No use in setting IAgentControl");
+ }
+
+ @Override
+ public String getName() {
+ return configuration.getAgentName();
+ }
+
+ @Override
+ public void setName(String name) {
+ configuration.setAgentName(name);
+ }
+
+ @Override
+ public void setConfigParams(Map<String, Object> params) {
+ configuration.setRawParams(params);
+ }
+
+ @Override
+ public Map<String, Object> getConfigParams() {
+ return configuration.getRawParams();
+ }
+
+ @Override
+ public int getRunLevel() {
+ return 0;
+ }
+
+ @Override
+ public void setRunLevel(int level) {
+ LOGGER.debug("runlevel seems unused in other hypervisors");
+ }
+
+ /**
+ * Base configuration of the plugins components.
+ */
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ LOGGER.debug("configure " + name + " with params: " + params);
+ /* check if we're master or not and if we can connect */
+ try {
+ configuration = new Ovm3Configuration(params);
+ if (!configuration.getIsTest()) {
+ c = new Connection(configuration.getAgentIp(),
+ configuration.getAgentOvsAgentPort(),
+ configuration.getAgentOvsAgentUser(),
+ configuration.getAgentOvsAgentPassword());
+ c.setHostName(configuration.getAgentHostname());
+ }
+ hypervisorsupport = new Ovm3HypervisorSupport(c, configuration);
+ if (!configuration.getIsTest()) {
+ hypervisorsupport.setupServer(configuration
+ .getAgentSshKeyFileName());
+ }
+ hypervisorsupport.masterCheck();
+ } catch (Exception e) {
+ throw new CloudRuntimeException("Base checks failed for "
+ + configuration.getAgentHostname(), e);
+ }
+ hypervisornetwork = new Ovm3HypervisorNetwork(c, configuration);
+ hypervisornetwork.configureNetworking();
+ virtualroutingresource = new Ovm3VirtualRoutingResource(c);
+ storagepool = new Ovm3StoragePool(c, configuration);
+ storagepool.prepareForPool();
+ storageprocessor = new Ovm3StorageProcessor(c, configuration,
+ storagepool);
+ vmsupport = new Ovm3VmSupport(c, configuration, hypervisorsupport,
+ storageprocessor, storagepool, hypervisornetwork);
+ vrResource = new VirtualRoutingResource(virtualroutingresource);
+ if (!vrResource.configure(name, params)) {
+ throw new ConfigurationException(
+ "Unable to configure VirtualRoutingResource");
+ }
+ guesttypes = new Ovm3VmGuestTypes();
+ storageHandler = new StorageSubsystemCommandHandlerBase(storageprocessor);
+ virtualroutingsupport = new Ovm3VirtualRoutingSupport(c, configuration,
+ virtualroutingresource);
+ this.setConfigParams(params);
+ return true;
+ }
+
+ public void setConnection(Connection con) {
+ LOGGER.debug("override connection: " + con.getIp());
+ c = con;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public synchronized StartAnswer execute(StartCommand cmd) {
+ VirtualMachineTO vmSpec = cmd.getVirtualMachine();
+ String vmName = vmSpec.getName();
+ State state = State.Stopped;
+ Xen xen = new Xen(c);
+
+ try {
+ hypervisorsupport.setVmStateStarting(vmName);
+ Xen.Vm vm = xen.getVmConfig();
+ /* max and min ? */
+ vm.setVmCpus(vmSpec.getCpus());
+ /* in mb not in bytes */
+ vm.setVmMemory(vmSpec.getMinRam() / 1024 / 1024);
+ vm.setVmUuid(UUID.nameUUIDFromBytes(vmSpec.getName().getBytes())
+ .toString());
+ vm.setVmName(vmName);
+
+ String domType = guesttypes.getOvm3GuestType(vmSpec.getOs());
+ if (domType == null || domType.isEmpty()) {
+ domType = "default";
+ LOGGER.debug("VM Virt type missing setting to: " + domType);
+ } else {
+ LOGGER.debug("VM Virt type set to " + domType + " for "
+ + vmSpec.getOs());
+ }
+ vm.setVmDomainType(domType);
+
+ if (vmSpec.getBootloader() == BootloaderType.CD) {
+ LOGGER.warn("CD booting is not supported");
+ }
+ /*
+ * officially CD boot is only supported on HVM, although there is a
+ * simple way around it..
+ */
+ vmsupport.createVbds(vm, vmSpec);
+
+ if (vmSpec.getType() != VirtualMachine.Type.User) {
+ // double check control network if we run a non user VM
+ hypervisornetwork.configureNetworking();
+ vm.setVmExtra(vmSpec.getBootArgs().replace(" ", "%"));
+ String svmPath = configuration.getAgentOvmRepoPath() + "/"
+ + ovmObject.deDash(vm.getPrimaryPoolUuid()) + "/ISOs";
+ String svmIso = svmPath + "/"
+ + storagepool.getSystemVMPatchIsoFile().getName();
+ vm.addIso(svmIso);
+ }
+ /* OVS/Network stuff should go here! */
+ vmsupport.createVifs(vm, vmSpec);
+ vm.setupVifs();
+
+ vm.setVnc("0.0.0.0", vmSpec.getVncPassword());
+ xen.createVm(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+ vm.getVmUuid());
+ xen.startVm(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+ vm.getVmUuid());
+ state = State.Running;
+
+ if (vmSpec.getType() != VirtualMachine.Type.User) {
+ String controlIp = null;
+ for (NicTO nic : vmSpec.getNics()) {
+ if (nic.getType() == TrafficType.Control) {
+ controlIp = nic.getIp();
+ }
+ }
+ /* fix is in cloudstack.py for xend restart timer */
+ for (int count = 0; count < 60; count++) {
+ CloudstackPlugin cSp = new CloudstackPlugin(c);
+ /* skip a beat to make sure we didn't miss start */
+ if (hypervisorsupport.getVmState(vmName) == null && count > 1) {
+ String msg = "VM " + vmName + " went missing on "
+ + configuration.getAgentHostname()
+ + ", returning stopped";
+ LOGGER.debug(msg);
+ state = State.Stopped;
+ return new StartAnswer(cmd, msg);
+ }
+ /* creative fix? */
+ try {
+ Boolean res = cSp.domrCheckSsh(controlIp);
+ LOGGER.debug("connected to " + controlIp
+ + " on attempt " + count + " result: " + res);
+ if (res) {
+ break;
+ }
+ } catch (Exception x) {
+ LOGGER.trace(
+ "unable to connect to " + controlIp
+ + " on attempt " + count + " "
+ + x.getMessage(), x);
+ }
+ Thread.sleep(5000);
+ }
+ }
+ /*
+ * Can't remember if HA worked if we were only a pool ?
+ */
+ if (configuration.getAgentInOvm3Pool()
+ && configuration.getAgentInOvm3Cluster()) {
+ xen.configureVmHa(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+ vm.getVmUuid(), true);
+ }
+ /* should be starting no ? */
+ state = State.Running;
+ return new StartAnswer(cmd);
+ } catch (Exception e) {
+ LOGGER.debug("Start vm " + vmName + " failed", e);
+ state = State.Stopped;
+ return new StartAnswer(cmd, e.getMessage());
+ } finally {
+ hypervisorsupport.setVmState(vmName, state);
+ }
+ }
+
+ /**
+ * Removes the vm and its configuration from the hypervisor.
+ */
+ @Override
+ public StopAnswer execute(StopCommand cmd) {
+ String vmName = cmd.getVmName();
+ State state = State.Error;
+ hypervisorsupport.setVmState(vmName, State.Stopping);
+
+ try {
+ Xen vms = new Xen(c);
+ Xen.Vm vm = null;
+ vm = vms.getRunningVmConfig(vmName);
+
+ if (vm == null) {
+ state = State.Stopping;
+ LOGGER.debug("Unable to get details of vm: " + vmName
+ + ", treating it as Stopping");
+ return new StopAnswer(cmd, "success", true);
+ }
+ String repoId = ovmObject.deDash(vm.getVmRootDiskPoolId());
+ String vmId = vm.getVmUuid();
+ /* can we do without the poolId ? */
+ vms.stopVm(repoId, vmId);
+ int tries = 30;
+ while (vms.getRunningVmConfig(vmName) != null && tries > 0) {
+ String msg = "Waiting for " + vmName + " to stop";
+ LOGGER.debug(msg);
+ tries--;
+ Thread.sleep(10 * 1000);
+ }
+ vms.deleteVm(repoId, vmId);
+ vmsupport.cleanup(vm);
+
+ if (vms.getRunningVmConfig(vmName) != null) {
+ String msg = "Stop " + vmName + " failed ";
+ LOGGER.debug(msg);
+ return new StopAnswer(cmd, msg, false);
+ }
+ state = State.Stopped;
+ return new StopAnswer(cmd, "success", true);
+ } catch (Exception e) {
+ LOGGER.debug("Stop " + vmName + " failed ", e);
+ return new StopAnswer(cmd, e.getMessage(), false);
+ } finally {
+ if (state != null) {
+ hypervisorsupport.setVmState(vmName, state);
+ } else {
+ hypervisorsupport.revmoveVmState(vmName);
+ }
+ }
+ }
+
+ @Override
+ public RebootAnswer execute(RebootCommand cmd) {
+ String vmName = cmd.getVmName();
+ hypervisorsupport.setVmStateStarting(vmName);
+ try {
+ Xen xen = new Xen(c);
+ Xen.Vm vm = xen.getRunningVmConfig(vmName);
+ if (vm == null) {
+ return new RebootAnswer(cmd, vmName + " not present", false);
+ }
+ xen.rebootVm(ovmObject.deDash(vm.getVmRootDiskPoolId()),
+ vm.getVmUuid());
+ vm = xen.getRunningVmConfig(vmName);
+ Integer vncPort = vm.getVncPort();
+ return new RebootAnswer(cmd, null, vncPort);
+ } catch (Exception e) {
+ LOGGER.debug("Reboot " + vmName + " failed", e);
+ return new RebootAnswer(cmd, e.getMessage(), false);
+ } finally {
+ hypervisorsupport.setVmState(vmName, State.Running);
+ }
+ }
+
+ @Override
+ protected String getDefaultScriptsDir() {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
new file mode 100644
index 0000000..b1a92bb
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
@@ -0,0 +1,835 @@
+/*******************************************************************************
+ * 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 com.cloud.hypervisor.ovm3.resources;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.UUID;
+
+import org.apache.cloudstack.storage.command.AttachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Linux;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin.FileProperties;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3StoragePool;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.resource.StorageProcessor;
+import com.cloud.vm.DiskProfile;
+
+/**
+ * Storage related bits
+ */
+public class Ovm3StorageProcessor implements StorageProcessor {
+ private final Logger LOGGER = Logger.getLogger(Ovm3StorageProcessor.class);
+ private Connection c;
+ private OvmObject ovmObject = new OvmObject();
+ private Ovm3StoragePool pool;
+ private Ovm3Configuration config;
+
+ public Ovm3StorageProcessor(Connection conn, Ovm3Configuration ovm3config,
+ Ovm3StoragePool ovm3pool) {
+ c = conn;
+ config = ovm3config;
+ pool = ovm3pool;
+ }
+
+ public final Answer execute(final CopyCommand cmd) {
+ LOGGER.debug("execute: "+ cmd.getClass());
+ DataTO srcData = cmd.getSrcTO();
+ DataStoreTO srcStore = srcData.getDataStore();
+ DataTO destData = cmd.getDestTO();
+ DataStoreTO destStore = destData.getDataStore();
+ String msg = "Not implemented yet";
+ try {
+ /* target and source are NFS and TEMPLATE */
+ if ((srcStore instanceof NfsTO)
+ && (srcData.getObjectType() == DataObjectType.TEMPLATE)
+ && (destData.getObjectType() == DataObjectType.TEMPLATE)) {
+ return copyTemplateToPrimaryStorage(cmd);
+ /* we assume the cache for templates is local */
+ } else if ((srcData.getObjectType() == DataObjectType.TEMPLATE)
+ && (destData.getObjectType() == DataObjectType.VOLUME)) {
+ if (srcStore.getUrl().equals(destStore.getUrl())) {
+ return cloneVolumeFromBaseTemplate(cmd);
+ } else {
+ msg = "Primary to Primary doesn't match";
+ LOGGER.debug(msg);
+ }
+ } else if ((srcData.getObjectType() == DataObjectType.SNAPSHOT)
+ && (destData.getObjectType() == DataObjectType.SNAPSHOT)) {
+ return backupSnapshot(cmd);
+ } else if ((srcData.getObjectType() == DataObjectType.SNAPSHOT)
+ && (destData.getObjectType() == DataObjectType.TEMPLATE)) {
+ return createTemplateFromSnapshot(cmd);
+ } else {
+ msg = "Unable to do stuff for " + srcStore.getClass() + ":"
+ + srcData.getObjectType() + " to "
+ + destStore.getClass() + ":" + destData.getObjectType();
+ LOGGER.debug(msg);
+ }
+ } catch (Exception e) {
+ msg = "Catch Exception " + e.getClass().getName()
+ + " for template due to " + e.toString();
+ LOGGER.warn(msg, e);
+ return new CopyCmdAnswer(msg);
+ }
+ LOGGER.warn(msg + " " + cmd.getClass());
+ return new CopyCmdAnswer(msg);
+ }
+
+ public Answer execute(DeleteCommand cmd) {
+ DataTO data = cmd.getData();
+ String msg;
+ LOGGER.debug("Deleting object: " + data.getObjectType());
+ if (data.getObjectType() == DataObjectType.VOLUME) {
+ return deleteVolume(cmd);
+ } else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
+ return deleteSnapshot(cmd);
+ } else if (data.getObjectType() == DataObjectType.TEMPLATE) {
+ msg = "Template deletion is not implemented yet.";
+ LOGGER.info(msg);
+ } else {
+ msg = data.getObjectType() + " deletion is not implemented yet.";
+ LOGGER.info(msg);
+ }
+ return new Answer(cmd, false, msg);
+ }
+
+ public CreateAnswer execute(CreateCommand cmd) {
+ LOGGER.debug("execute: "+ cmd.getClass());
+ StorageFilerTO primaryStorage = cmd.getPool();
+ DiskProfile disk = cmd.getDiskCharacteristics();
+ /* disk should have a uuid */
+ // should also be replaced with getVirtualDiskPath ?
+ String fileName = UUID.randomUUID().toString() + ".raw";
+ String dst = primaryStorage.getPath() + File.separator
+ + primaryStorage.getUuid() + File.separator + fileName;
+ try {
+ StoragePlugin store = new StoragePlugin(c);
+ if (cmd.getTemplateUrl() != null) {
+ LOGGER.debug("CreateCommand " + cmd.getTemplateUrl() + " "
+ + dst);
+ Linux host = new Linux(c);
+ host.copyFile(cmd.getTemplateUrl(), dst);
+ } else {
+ /* this is a dup with the createVolume ? */
+ LOGGER.debug("CreateCommand " + dst);
+ store.storagePluginCreate(primaryStorage.getUuid(),
+ primaryStorage.getHost(), dst, disk.getSize(), false);
+ }
+ FileProperties fp = store.storagePluginGetFileInfo(
+ primaryStorage.getUuid(), primaryStorage.getHost(), dst);
+ VolumeTO volume = new VolumeTO(cmd.getVolumeId(), disk.getType(),
+ primaryStorage.getType(), primaryStorage.getUuid(),
+ primaryStorage.getPath(), fileName, fp.getName(),
+ fp.getSize(), null);
+ return new CreateAnswer(cmd, volume);
+ } catch (Exception e) {
+ LOGGER.debug("CreateCommand failed", e);
+ return new CreateAnswer(cmd, e.getMessage());
+ }
+ }
+
+ /**
+ * src is Nfs and Template from secondary storage to primary
+ */
+ @Override
+ public CopyCmdAnswer copyTemplateToPrimaryStorage(CopyCommand cmd) {
+ LOGGER.debug("execute copyTemplateToPrimaryStorage: "+ cmd.getClass());
+ DataTO srcData = cmd.getSrcTO();
+ DataStoreTO srcStore = srcData.getDataStore();
+ DataTO destData = cmd.getDestTO();
+ NfsTO srcImageStore = (NfsTO) srcStore;
+ TemplateObjectTO destTemplate = (TemplateObjectTO) destData;
+ try {
+ String secPoolUuid = pool.setupSecondaryStorage(srcImageStore.getUrl());
+ String primaryPoolUuid = destData.getDataStore().getUuid();
+ String destPath = config.getAgentOvmRepoPath() + File.separator
+ + ovmObject.deDash(primaryPoolUuid) + File.separator
+ + config.getTemplateDir();
+ String sourcePath = config.getAgentSecStoragePath()
+ + File.separator + secPoolUuid;
+ Linux host = new Linux(c);
+ String destUuid = destTemplate.getUuid();
+ /*
+ * Would love to add dynamic formats (tolower), to also support
+ * VHD and QCOW2, although Ovm3.2 does not have tapdisk2 anymore
+ * so we can forget about that.
+ */
+ /* TODO: add checksumming */
+ String srcFile = sourcePath + File.separator
+ + srcData.getPath();
+ if (srcData.getPath().endsWith(File.separator)) {
+ srcFile = sourcePath + File.separator + srcData.getPath()
+ + File.separator + destUuid + ".raw";
+ }
+ String destFile = destPath + File.separator + destUuid + ".raw";
+ LOGGER.debug("CopyFrom: " + srcData.getObjectType() + ","
+ + srcFile + " to " + destData.getObjectType() + ","
+ + destFile);
+ host.copyFile(srcFile, destFile);
+ TemplateObjectTO newVol = new TemplateObjectTO();
+ newVol.setUuid(destUuid);
+ // was destfile
+ newVol.setPath(destUuid);
+ newVol.setFormat(ImageFormat.RAW);
+ return new CopyCmdAnswer(newVol);
+ } catch (Ovm3ResourceException e) {
+ String msg = "Error while copying template to primary storage: " + e.getMessage();
+ LOGGER.info(msg);
+ return new CopyCmdAnswer(msg);
+ }
+ }
+ /**
+ * Only copies in case of dest is NfsTO, xenserver also unmounts secstorage
+ */
+ @Override
+ public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
+ LOGGER.debug("execute copyVolumeFromPrimaryToSecondary: "+ cmd.getClass());
+ return new Answer(cmd);
+ }
+ /**
+ * dest is VolumeObject, src is a template
+ */
+ @Override
+ public CopyCmdAnswer cloneVolumeFromBaseTemplate(CopyCommand cmd) {
+ LOGGER.debug("execute cloneVolumeFromBaseTemplate: "+ cmd.getClass());
+ try {
+ // src
+ DataTO srcData = cmd.getSrcTO();
+ TemplateObjectTO src = (TemplateObjectTO) srcData;
+ String srcFile = getVirtualDiskPath(src.getUuid(), src.getDataStore().getUuid());
+ srcFile = srcFile.replace(config.getVirtualDiskDir(), config.getTemplateDir());
+
+ DataTO destData = cmd.getDestTO();
+ VolumeObjectTO dest = (VolumeObjectTO) destData;
+ String destFile = getVirtualDiskPath(dest.getUuid(), dest.getDataStore().getUuid());
+ Linux host = new Linux(c);
+ LOGGER.debug("CopyFrom: " + srcData.getObjectType() + ","
+ + srcFile + " to " + destData.getObjectType() + ","
+ + destFile);
+ host.copyFile(srcFile, destFile);
+ VolumeObjectTO newVol = new VolumeObjectTO();
+ newVol.setUuid(dest.getUuid());
+ // was destfile
+ newVol.setPath(dest.getUuid());
+ newVol.setFormat(ImageFormat.RAW);
+ return new CopyCmdAnswer(newVol);
+ } catch (Ovm3ResourceException e) {
+ String msg = "Error cloneVolumeFromBaseTemplate: " + e.getMessage();
+ LOGGER.info(msg);
+ return new CopyCmdAnswer(msg);
+ }
+ }
+ /**
+ * createprivatetemplate, also needs template.properties
+ */
+ @Override
+ public Answer createTemplateFromVolume(CopyCommand cmd) {
+ LOGGER.debug("execute createTemplateFromVolume: "+ cmd.getClass());
+ return new Answer(cmd);
+ }
+ /**
+ * Volume to Volume from NfsTO
+ */
+ @Override
+ public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
+ LOGGER.debug("execute copyVolumeFromImageCacheToPrimary: "+ cmd.getClass());
+ return new Answer(cmd);
+ }
+ /**
+ * Copies from secondary to secondary
+ */
+ @Override
+ public Answer createTemplateFromSnapshot(CopyCommand cmd) {
+ LOGGER.debug("execute createTemplateFromSnapshot: "+ cmd.getClass());
+ try {
+ // src.getPath contains the uuid of the snapshot.
+ DataTO srcData = cmd.getSrcTO();
+ SnapshotObjectTO srcSnap = (SnapshotObjectTO) srcData;
+ String secPoolUuid = pool.setupSecondaryStorage(srcData.getDataStore().getUrl());
+ String srcFile = config.getAgentSecStoragePath()
+ + File.separator + secPoolUuid + File.separator
+ + srcSnap.getPath();
+ // dest
+ DataTO destData = cmd.getDestTO();
+ TemplateObjectTO destTemplate = (TemplateObjectTO) destData;
+ String secPoolUuidTemplate = pool.setupSecondaryStorage(destData.getDataStore().getUrl());
+ String destDir = config.getAgentSecStoragePath()
+ + File.separator + secPoolUuidTemplate + File.separator
+ + destTemplate.getPath();
+ String destFile = destDir + File.separator
+ + destTemplate.getUuid() + ".raw";
+ CloudstackPlugin csp = new CloudstackPlugin(c);
+ csp.ovsMkdirs(destDir);
+
+ Linux host = new Linux(c);
+ host.copyFile(srcFile, destFile);
+ TemplateObjectTO newVol = new TemplateObjectTO();
+ newVol.setUuid(destTemplate.getUuid());
+ newVol.setPath(destTemplate.getUuid());
+ newVol.setFormat(ImageFormat.RAW);
+ return new CopyCmdAnswer(newVol);
+ } catch (Ovm3ResourceException e) {
+ String msg = "Error backupSnapshot: " + e.getMessage();
+ LOGGER.info(msg);
+ return new CopyCmdAnswer(msg);
+ }
+ }
+
+ /**
+ * use the cache, or the normal nfs, also delete the leftovers for us
+ * also contains object store storage in xenserver.
+ */
+ @Override
+ public CopyCmdAnswer backupSnapshot(CopyCommand cmd) {
+ LOGGER.debug("execute backupSnapshot: "+ cmd.getClass());
+ try {
+ DataTO srcData = cmd.getSrcTO();
+ DataTO destData = cmd.getDestTO();
+ SnapshotObjectTO src = (SnapshotObjectTO) srcData;
+ SnapshotObjectTO dest = (SnapshotObjectTO) destData;
+
+ // src.getPath contains the uuid of the snapshot.
+ String srcFile = getVirtualDiskPath(src.getPath(), src.getDataStore().getUuid());
+
+ // destination
+ String storeUrl = dest.getDataStore().getUrl();
+ String secPoolUuid = pool.setupSecondaryStorage(storeUrl);
+ String destDir = config.getAgentSecStoragePath()
+ + File.separator + secPoolUuid + File.separator
+ + dest.getPath();
+ String destFile = destDir + File.separator + src.getPath();
+ destFile = destFile.concat(".raw");
+ // copy
+ Linux host = new Linux(c);
+ CloudstackPlugin csp = new CloudstackPlugin(c);
+ csp.ovsMkdirs(destDir);
+ LOGGER.debug("CopyFrom: " + srcData.getObjectType() + ","
+ + srcFile + " to " + destData.getObjectType() + ","
+ + destFile);
+ host.copyFile(srcFile, destFile);
+ StoragePlugin sp = new StoragePlugin(c);
+ sp.storagePluginDestroy(secPoolUuid, srcFile);
+
+ SnapshotObjectTO newSnap = new SnapshotObjectTO();
+ // newSnap.setPath(destFile);
+ // damnit frickin crap, no reference whatsoever... could use parent ?
+ newSnap.setPath(dest.getPath() + File.separator + src.getPath() + ".raw");
+ newSnap.setParentSnapshotPath(null);
+ return new CopyCmdAnswer(newSnap);
+ } catch (Ovm3ResourceException e) {
+ String msg = "Error backupSnapshot: " + e.getMessage();
+ LOGGER.info(msg);
+ return new CopyCmdAnswer(msg);
+ }
+ }
+
+ public Answer execute(CreateObjectCommand cmd) {
+ LOGGER.debug("execute: "+ cmd.getClass());
+ DataTO data = cmd.getData();
+ if (data.getObjectType() == DataObjectType.VOLUME) {
+ return createVolume(cmd);
+ } else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
+ return createSnapshot(cmd);
+ } else if (data.getObjectType() == DataObjectType.TEMPLATE) {
+ LOGGER.debug("Template object creation not supported.");
+ }
+ return new CreateObjectAnswer(data.getObjectType()
+ + " object creation not supported");
+ }
+ /**
+ * Attach an iso
+ */
+ @Override
+ public AttachAnswer attachIso(AttachCommand cmd) {
+ LOGGER.debug("execute attachIso: "+ cmd.getClass());
+ String vmName = cmd.getVmName();
+ DiskTO disk = cmd.getDisk();
+ return attachDetach(cmd, vmName, disk, true);
+ }
+ /**
+ * Detach an iso
+ */
+ @Override
+ public AttachAnswer dettachIso(DettachCommand cmd) {
+ LOGGER.debug("execute dettachIso: "+ cmd.getClass());
+ String vmName = cmd.getVmName();
+ DiskTO disk = cmd.getDisk();
+ return attachDetach(cmd, vmName, disk, false);
+ }
+
+ /**
+ * Iso specific path return.
+ * @param disk
+ * @return
+ * @throws Ovm3ResourceException
+ */
+ private String getIsoPath(DiskTO disk) throws Ovm3ResourceException {
+ TemplateObjectTO isoTO = (TemplateObjectTO) disk.getData();
+ DataStoreTO store = isoTO.getDataStore();
+ NfsTO nfsStore = (NfsTO) store;
+ String secPoolUuid = pool.setupSecondaryStorage(nfsStore.getUrl());
+ return config.getAgentSecStoragePath() + File.separator
+ + secPoolUuid + File.separator + isoTO.getPath();
+ }
+
+ /**
+ * Returns the disk path
+ * @param diskUuid
+ * @return
+ * @throws Ovm3ResourceException
+ */
+ public String getVirtualDiskPath(String diskUuid, String storeUuid) throws Ovm3ResourceException {
+ String d = config.getAgentOvmRepoPath() +
+ File.separator +
+ ovmObject.deDash(storeUuid) +
+ File.separator +
+ config.getVirtualDiskDir() +
+ File.separator +
+ diskUuid;
+ if (!d.endsWith(".raw")) {
+ d = d.concat(".raw");
+ }
+ return d;
+ }
+ public String getVirtualDiskPath(DiskTO disk, String storeUuid) throws Ovm3ResourceException {
+ return getVirtualDiskPath(disk.getPath(), storeUuid);
+ }
+
+ /**
+ * Generic disk attach/detach.
+ * @param cmd
+ * @param vmName
+ * @param disk
+ * @param isAttach
+ * @return
+ */
+ private AttachAnswer attachDetach(Command cmd, String vmName, DiskTO disk,
+ boolean isAttach) {
+ Xen xen = new Xen(c);
+ String doThis = (isAttach) ? "Attach" : "Dettach";
+ LOGGER.debug(doThis + " volume type " + disk.getType() + " " + vmName);
+ String msg = "";
+ String path = "";
+ try {
+ Xen.Vm vm = xen.getVmConfig(vmName);
+ /* check running */
+ if (vm == null) {
+ msg = doThis + " can't find VM " + vmName;
+ LOGGER.debug(msg);
+ return new AttachAnswer(msg);
+ }
+ if (disk.getType() == Volume.Type.ISO) {
+ path = getIsoPath(disk);
+ } else if (disk.getType() == Volume.Type.DATADISK) {
+ path = getVirtualDiskPath(disk, vm.getPrimaryPoolUuid());
+ }
+ if ("".equals(path)) {
+ msg = doThis + " can't do anything with an empty path.";
+ LOGGER.debug(msg);
+ return new AttachAnswer(msg);
+ }
+ if (isAttach) {
+ if (disk.getType() == Volume.Type.ISO) {
+ vm.addIso(path);
+ } else {
+ vm.addDataDisk(path);
+ }
+ } else {
+ if (!vm.removeDisk(path)) {
+ msg = doThis + " failed for " + vmName + disk.getType()
+ + " was not attached " + path;
+ LOGGER.debug(msg);
+ return new AttachAnswer(msg);
+ }
+ }
+ xen.configureVm(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+ vm.getVmUuid());
+ return new AttachAnswer(disk);
+ } catch (Ovm3ResourceException e) {
+ msg = doThis + " failed for " + vmName + " " + e.getMessage();
+ LOGGER.warn(msg, e);
+ return new AttachAnswer(msg);
+ }
+ }
+ /**
+ * Attach a volume
+ */
+ @Override
+ public AttachAnswer attachVolume(AttachCommand cmd) {
+ LOGGER.debug("execute attachVolume: "+ cmd.getClass());
+ String vmName = cmd.getVmName();
+ DiskTO disk = cmd.getDisk();
+ return attachDetach(cmd, vmName, disk, true);
+ }
+ /**
+ * Detach a volume
+ */
+ @Override
+ public AttachAnswer dettachVolume(DettachCommand cmd) {
+ LOGGER.debug("execute dettachVolume: "+ cmd.getClass());
+ String vmName = cmd.getVmName();
+ DiskTO disk = cmd.getDisk();
+ return attachDetach(cmd, vmName, disk, false);
+ }
+
+ /**
+ * Creates a volume, just a normal empty volume.
+ */
+ @Override
+ public Answer createVolume(CreateObjectCommand cmd) {
+ LOGGER.debug("execute createVolume: "+ cmd.getClass());
+ DataTO data = cmd.getData();
+ VolumeObjectTO volume = (VolumeObjectTO) data;
+ try {
+ /*
+ * public Boolean storagePluginCreate(String uuid, String ssuuid,
+ * String host, String file, Integer size)
+ */
+ String poolUuid = data.getDataStore().getUuid();
+ String storeUrl = data.getDataStore().getUrl();
+ URI uri = new URI(storeUrl);
+ String host = uri.getHost();
+ String file = getVirtualDiskPath(volume.getUuid(), poolUuid);
+ Long size = volume.getSize();
+ StoragePlugin sp = new StoragePlugin(c);
+ FileProperties fp = sp.storagePluginCreate(poolUuid, host, file,
+ size, false);
+ if (!fp.getName().equals(file)) {
+ return new CreateObjectAnswer("Filename mismatch: "
+ + fp.getName() + " != " + file);
+ }
+ VolumeObjectTO newVol = new VolumeObjectTO();
+ newVol.setName(volume.getName());
+ newVol.setSize(fp.getSize());
+ newVol.setPath(volume.getUuid());
+ return new CreateObjectAnswer(newVol);
+ } catch (Ovm3ResourceException | URISyntaxException e) {
+ LOGGER.info("Volume creation failed: " + e.toString(), e);
+ return new CreateObjectAnswer(e.toString());
+ }
+ }
+
+ /**
+ * Creates a snapshot from a volume, but only if the VM is stopped.
+ * This due qemu not being able to snap raw volumes.
+ *
+ * if stopped yes, if running ... no, unless we have ocfs2 when
+ * using raw partitions (file:) if using tap:aio we cloud...
+ * The "ancient" way:
+ * We do however follow the "two stage" approach, of "snap"
+ * on primary first, with the create object... and then
+ * backup the snapshot with the copycmd....
+ * (should transfer to createSnapshot, backupSnapshot)
+ */
+ @Override
+ public Answer createSnapshot(CreateObjectCommand cmd) {
+ LOGGER.debug("execute createSnapshot: "+ cmd.getClass());
+ DataTO data = cmd.getData();
+ Xen xen = new Xen(c);
+ SnapshotObjectTO snap = (SnapshotObjectTO) data;
+ VolumeObjectTO vol = snap.getVolume();
+ try {
+ Xen.Vm vm = xen.getVmConfig(snap.getVmName());
+ if (vm != null) {
+ return new CreateObjectAnswer(
+ "Snapshot object creation not supported for running VMs."
+ + snap.getVmName());
+ }
+ Linux host = new Linux(c);
+ String uuid = host.newUuid();
+ /* for root volumes this works... */
+ String src = vol.getPath() + File.separator + vol.getUuid()
+ + ".raw";
+ String dest = vol.getPath() + File.separator + uuid + ".raw";
+ /* seems that sometimes the path is already contains a file
+ * in case, we just replace it.... (Seems to happen if not ROOT)
+ */
+ if (vol.getPath().contains(vol.getUuid())) {
+ src = getVirtualDiskPath(vol.getUuid(),data.getDataStore().getUuid());
+ dest = src.replace(vol.getUuid(), uuid);
+ }
+ LOGGER.debug("Snapshot " + src + " to " + dest);
+ host.copyFile(src, dest);
+ SnapshotObjectTO nsnap = new SnapshotObjectTO();
+ // nsnap.setPath(dest);
+ // move to something that looks the same as xenserver.
+ nsnap.setPath(uuid);
+ return new CreateObjectAnswer(nsnap);
+ } catch (Ovm3ResourceException e) {
+ return new CreateObjectAnswer(
+ "Snapshot object creation failed. " + e.getMessage());
+ }
+ }
+
+ @Override
+ public Answer deleteVolume(DeleteCommand cmd) {
+ LOGGER.debug("execute deleteVolume: "+ cmd.getClass());
+ DataTO data = cmd.getData();
+ VolumeObjectTO volume = (VolumeObjectTO) data;
+ try {
+ String poolUuid = data.getDataStore().getUuid();
+ String uuid = volume.getUuid();
+ String path = getVirtualDiskPath(uuid, poolUuid);
+ StoragePlugin sp = new StoragePlugin(c);
+ sp.storagePluginDestroy(poolUuid, path);
+ LOGGER.debug("Volume deletion success: " + path);
+ } catch (Ovm3ResourceException e) {
+ LOGGER.info("Volume deletion failed: " + e.toString(), e);
+ return new CreateObjectAnswer(e.toString());
+ }
+ return new Answer(cmd);
+ }
+
+ /*
+ * CopyVolumeCommand gets the storage_pool should use that for
+ * bumper bowling.
+ */
+ public CopyVolumeAnswer execute(CopyVolumeCommand cmd) {
+ LOGGER.debug("execute: "+ cmd.getClass());
+ String volumePath = cmd.getVolumePath();
+ /* is a repository */
+ String secondaryStorageURL = cmd.getSecondaryStorageURL();
+ int wait = cmd.getWait();
+ if (wait == 0) {
+ wait = 7200;
+ }
+
+ try {
+ Linux host = new Linux(c);
+
+ /* to secondary storage */
+ if (cmd.toSecondaryStorage()) {
+ LOGGER.debug("Copy to secondary storage " + volumePath
+ + " to " + secondaryStorageURL);
+ host.copyFile(volumePath, secondaryStorageURL);
+ /* from secondary storage */
+ } else {
+ LOGGER.debug("Copy from secondary storage "
+ + secondaryStorageURL + " to " + volumePath);
+ host.copyFile(secondaryStorageURL, volumePath);
+ }
+ /* check the truth of this */
+ return new CopyVolumeAnswer(cmd, true, null, null, null);
+ } catch (Ovm3ResourceException e) {
+ LOGGER.debug("Copy volume failed", e);
+ return new CopyVolumeAnswer(cmd, false, e.getMessage(), null, null);
+ }
+ }
+
+ /* Destroy a volume (image) */
+ public Answer execute(DestroyCommand cmd) {
+ LOGGER.debug("execute: "+ cmd.getClass());
+ VolumeTO vol = cmd.getVolume();
+ String vmName = cmd.getVmName();
+ try {
+ StoragePlugin store = new StoragePlugin(c);
+ store.storagePluginDestroy(vol.getPoolUuid(), vol.getPath());
+ return new Answer(cmd, true, "Success");
+ } catch (Ovm3ResourceException e) {
+ LOGGER.debug("Destroy volume " + vol.getName() + " failed for "
+ + vmName + " ", e);
+ return new Answer(cmd, false, e.getMessage());
+ }
+ }
+
+ /* check if a VM is running should be added */
+ public CreatePrivateTemplateAnswer execute(
+ final CreatePrivateTemplateFromVolumeCommand cmd) {
+ LOGGER.debug("execute: "+ cmd.getClass());
+ String volumePath = cmd.getVolumePath();
+ Long accountId = cmd.getAccountId();
+ Long templateId = cmd.getTemplateId();
+ int wait = cmd.getWait();
+ if (wait == 0) {
+ /* Defaut timeout 2 hours */
+ wait = 7200;
+ }
+
+ try {
+ /* missing uuid */
+ String installPath = config.getAgentOvmRepoPath() + File.separator
+ + config.getTemplateDir() + File.separator
+ + accountId + File.separator + templateId;
+ Linux host = new Linux(c);
+ host.copyFile(volumePath, installPath);
+ return new CreatePrivateTemplateAnswer(cmd, true, installPath);
+ } catch (Exception e) {
+ LOGGER.debug("Create template failed", e);
+ return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
+ }
+ }
+
+ /**
+ * SnapshotObjectTO secondary to VolumeObjectTO primary in xenserver,
+ */
+ @Override
+ public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+ LOGGER.debug("execute createVolumeFromSnapshot: "+ cmd.getClass());
+ try {
+ DataTO srcData = cmd.getSrcTO();
+ DataStoreTO srcStore = srcData.getDataStore();
+ NfsTO srcImageStore = (NfsTO) srcStore;
+
+ // source, should contain snap dir/filename
+ SnapshotObjectTO srcSnap = (SnapshotObjectTO) srcData;
+ String secPoolUuid = pool.setupSecondaryStorage(srcImageStore.getUrl());
+ String srcFile = config.getAgentSecStoragePath()
+ + File.separator + secPoolUuid + File.separator
+ + srcSnap.getPath();
+
+ // dest
+ DataTO destData = cmd.getDestTO();
+ VolumeObjectTO destVol = (VolumeObjectTO) destData;
+ String primaryPoolUuid = destData.getDataStore().getUuid();
+ String destFile = getVirtualDiskPath(destVol.getUuid(), ovmObject.deDash(primaryPoolUuid));
+
+ Linux host = new Linux(c);
+ host.copyFile(srcFile, destFile);
+
+ VolumeObjectTO newVol = new VolumeObjectTO();
+ newVol.setUuid(destVol.getUuid());
+ // newVol.setPath(destFile);
+ newVol.setPath(destVol.getUuid());
+ newVol.setFormat(ImageFormat.RAW);
+ return new CopyCmdAnswer(newVol);
+ /* we assume the cache for templates is local */
+ } catch (Ovm3ResourceException e) {
+ LOGGER.debug("Failed to createVolumeFromSnapshot: ", e);
+ return new CopyCmdAnswer(e.toString());
+ }
+ }
+
+ /**
+ * Is not used in normal operation, the SSVM takes care of this.
+ */
+ @Override
+ public Answer deleteSnapshot(DeleteCommand cmd) {
+ LOGGER.debug("execute deleteSnapshot: "+ cmd.getClass());
+ DataTO data = cmd.getData();
+ SnapshotObjectTO snap = (SnapshotObjectTO) data;
+ String storeUrl = data.getDataStore().getUrl();
+ String snapUuid = snap.getPath();
+ try {
+ // snapshots/accountid/volumeid
+ String secPoolUuid = pool.setupSecondaryStorage(storeUrl);
+ String filePath = config.getAgentSecStoragePath()
+ + File.separator + secPoolUuid + File.separator
+ + snapUuid + ".raw";
+ StoragePlugin sp = new StoragePlugin(c);
+ sp.storagePluginDestroy(secPoolUuid, filePath);
+ LOGGER.debug("Snapshot deletion success: " + filePath);
+ return new Answer(cmd, true, "Deleted Snapshot " + filePath);
+ } catch (Ovm3ResourceException e) {
+ LOGGER.info("Snapshot deletion failed: " + e.toString(), e);
+ return new CreateObjectAnswer(e.toString());
+ }
+ }
+ /**
+ * SR scan in xenserver
+ */
+ @Override
+ public Answer introduceObject(IntroduceObjectCmd cmd) {
+ LOGGER.debug("execute introduceObject: "+ cmd.getClass());
+ return new Answer(cmd, false, "not implemented yet");
+ }
+ /**
+ * used as unmount for VDIs in xenserver
+ */
+ @Override
+ public Answer forgetObject(ForgetObjectCmd cmd) {
+ LOGGER.debug("execute forgetObject: "+ cmd.getClass());
+ return new Answer(cmd, false, "not implemented yet");
+ }
+
+ /**
+ * make sure both mounts are there, snapshot source image
+ * copy snap to dest image, remove source snap and unmount
+ * iSCSI?
+ */
+ @Override
+ public Answer snapshotAndCopy(SnapshotAndCopyCommand cmd) {
+ LOGGER.debug("execute snapshotAndCopy: "+ cmd.getClass());
+ return new SnapshotAndCopyAnswer("not implemented yet");
+ }
+
+ /**
+ * Attach disks
+ * @param cmd
+ * @return
+ */
+ public Answer execute(AttachCommand cmd) {
+ LOGGER.debug("execute: "+ cmd.getClass());
+ String vmName = cmd.getVmName();
+ DiskTO disk = cmd.getDisk();
+ return attachDetach(cmd, vmName, disk, true);
+ }
+
+ /**
+ * Detach disks, calls a middle man which calls attachDetach for volumes.
+ * @param cmd
+ * @return
+ */
+ public Answer execute(DettachCommand cmd) {
+ LOGGER.debug("execute: "+ cmd.getClass());
+ String vmName = cmd.getVmName();
+ DiskTO disk = cmd.getDisk();
+ return attachDetach(cmd, vmName, disk, false);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResource.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResource.java
new file mode 100644
index 0000000..52409b1
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResource.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * 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 com.cloud.hypervisor.ovm3.resources;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.utils.ExecutionResult;
+
+@Local(value = VirtualRouterDeployer.class)
+public class Ovm3VirtualRoutingResource implements VirtualRouterDeployer {
+ private final Logger logger = Logger
+ .getLogger(Ovm3VirtualRoutingResource.class);
+ private String domRCloudPath = "/opt/cloud/bin/";
+ private int vrTimeout = 600;
+ private Connection c;
+ private String agentName;
+ public Ovm3VirtualRoutingResource() {
+ }
+ public Ovm3VirtualRoutingResource(Connection conn) {
+ c = conn;
+ agentName=c.getIp();
+ }
+ public void setConnection(Connection conn) {
+ c = conn;
+ }
+ @Override
+ public ExecutionResult executeInVR(String routerIp, String script,
+ String args) {
+ return executeInVR(routerIp, script, args, vrTimeout);
+ }
+
+ @Override
+ public ExecutionResult executeInVR(String routerIp, String script,
+ String args, int timeout) {
+ if (!script.contains(domRCloudPath)) {
+ script = domRCloudPath + "/" + script;
+ }
+ String cmd = script + " " + args;
+ logger.debug("executeInVR via " + agentName + " on " + routerIp + ": "
+ + cmd);
+ try {
+ CloudstackPlugin cSp = new CloudstackPlugin(c);
+ CloudstackPlugin.ReturnCode result;
+ result = cSp.domrExec(routerIp, cmd);
+ return new ExecutionResult(result.getRc(), result.getStdOut());
+ } catch (Exception e) {
+ logger.error("executeInVR FAILED via " + agentName + " on "
+ + routerIp + ":" + cmd + ", " + e.getMessage(), e);
+ }
+ return new ExecutionResult(false, "");
+ }
+
+ @Override
+ public ExecutionResult createFileInVR(String routerIp, String path,
+ String filename, String content) {
+ String error = null;
+ logger.debug("createFileInVR via " + agentName + " on " + routerIp
+ + ": " + path + "/" + filename + ", content: " + content);
+ try {
+ CloudstackPlugin cSp = new CloudstackPlugin(c);
+ boolean result = cSp.ovsDomrUploadFile(routerIp, path, filename,
+ content);
+ return new ExecutionResult(result, "");
+ } catch (Exception e) {
+ error = e.getMessage();
+ logger.warn(
+ "createFileInVR failed for " + path + "/" + filename
+ + " in VR " + routerIp + " via " + agentName + ": "
+ + error, e);
+ }
+ return new ExecutionResult(error == null, error);
+ }
+
+ @Override
+ public ExecutionResult prepareCommand(NetworkElementCommand cmd) {
+ // Update IP used to access router
+ cmd.setRouterAccessIp(cmd
+ .getAccessDetail(NetworkElementCommand.ROUTER_IP));
+ assert cmd.getRouterAccessIp() != null;
+
+ if (cmd instanceof IpAssocVpcCommand) {
+ return prepareNetworkElementCommand((IpAssocVpcCommand) cmd);
+ } else if (cmd instanceof IpAssocCommand) {
+ return prepareNetworkElementCommand((IpAssocCommand) cmd);
+ } else if (cmd instanceof SetupGuestNetworkCommand) {
+ return prepareNetworkElementCommand((SetupGuestNetworkCommand) cmd);
+ } else if (cmd instanceof SetSourceNatCommand) {
+ return prepareNetworkElementCommand((SetSourceNatCommand) cmd);
+ }
+ return new ExecutionResult(true, null);
+ }
+
+ @Override
+ public ExecutionResult cleanupCommand(NetworkElementCommand cmd) {
+ if (cmd instanceof IpAssocCommand
+ && !(cmd instanceof IpAssocVpcCommand)) {
+ return cleanupNetworkElementCommand((IpAssocCommand) cmd);
+ }
+ return new ExecutionResult(true, null);
+ }
+
+ private ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) {
+ return new ExecutionResult(true, null);
+ }
+
+ private ExecutionResult prepareNetworkElementCommand(
+ SetupGuestNetworkCommand cmd) {
+ return new ExecutionResult(true, null);
+ }
+
+ private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) {
+ return prepNetBoth(cmd
+ .getAccessDetail(NetworkElementCommand.ROUTER_NAME),
+ cmd.getIpAddresses(), "IpAssocVpcCommand");
+ }
+
+ private ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) {
+ return new ExecutionResult(true, null);
+ }
+
+ private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) {
+ return prepNetBoth(cmd
+ .getAccessDetail(NetworkElementCommand.ROUTER_NAME),
+ cmd.getIpAddresses(), "IpAssocCommand");
+ }
+
+ private ExecutionResult prepNetBoth(String routerName, IpAddressTO[] ips, String type) {
+ Xen xen = new Xen(c);
+ try {
+ Xen.Vm vm = xen.getVmConfig(routerName);
+ for (IpAddressTO ip : ips) {
+ Integer devId = vm.getVifIdByMac(ip.getVifMacAddress());
+ if (devId < 0 && "IpAssocVpcCommand".equals(type)) {
+ String msg = "No valid Nic devId found for " + vm.getVmName()
+ + " with " + ip.getVifMacAddress();
+ logger.error(msg);
+ return new ExecutionResult(false, msg);
+ } else if (devId < 0 && "IpAssocCommand".equals(type)) {
+ // vm.get
+ String msg = "No valid Nic devId found for " + vm.getVmName()
+ + " with " + ip.getVifMacAddress() + " "
+ + " Ignoring for now (routervm)";
+ logger.debug(msg);
+ devId=2;
+ }
+ ip.setNicDevId(devId);
+ }
+ } catch (Exception e) {
+ String msg = type + " failure on applying one ip due to exception: " + e;
+ logger.error(msg);
+ return new ExecutionResult(false, msg);
+ }
+ return new ExecutionResult(true, null);
+ }
+}