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