diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 7c486d8c8c8..cb9832ee1d1 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -89,6 +89,8 @@ 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.PlugNicAnswer; +import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PoolEjectCommand; import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationCommand; @@ -97,8 +99,11 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.api.SetSourceNatAnswer; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; @@ -107,6 +112,8 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.agent.api.UnPlugNicAnswer; +import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.ValidateSnapshotAnswer; import com.cloud.agent.api.ValidateSnapshotCommand; @@ -116,14 +123,19 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesAnswer; import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetNetworkACLAnswer; +import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; @@ -233,12 +245,15 @@ import com.vmware.vim25.VirtualMachineGuestOsIdentifier; import com.vmware.vim25.VirtualMachinePowerState; import com.vmware.vim25.VirtualMachineRuntimeInfo; import com.vmware.vim25.VirtualSCSISharing; - -public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService { - private static final Logger s_logger = Logger.getLogger(VmwareResource.class); - - protected String _name; - +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VM; + +public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService { + private static final Logger s_logger = Logger.getLogger(VmwareResource.class); + + protected String _name; + protected final long _ops_timeout = 900000; // 15 minutes time out to time protected final int _shutdown_waitMs = 300000; // wait up to 5 minutes for shutdown @@ -310,108 +325,123 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa mbean.addProp("Sequence", String.valueOf(cmdSequence)); mbean.addProp("Name", cmd.getClass().getSimpleName()); - if (cmd instanceof CreateCommand) { + Class clz = cmd.getClass(); + if (clz == CreateCommand.class) { answer = execute((CreateCommand) cmd); - } else if (cmd instanceof SetPortForwardingRulesCommand) { + } else if (clz == SetPortForwardingRulesCommand.class) { answer = execute((SetPortForwardingRulesCommand) cmd); - } else if (cmd instanceof SetStaticNatRulesCommand) { + } else if (clz == SetStaticNatRulesCommand.class) { answer = execute((SetStaticNatRulesCommand) cmd); - } else if (cmd instanceof LoadBalancerConfigCommand) { + } else if (clz == LoadBalancerConfigCommand.class) { answer = execute((LoadBalancerConfigCommand) cmd); - } else if (cmd instanceof IpAssocCommand) { + } else if (clz == IpAssocCommand.class) { answer = execute((IpAssocCommand) cmd); - } else if (cmd instanceof SavePasswordCommand) { + } else if (clz == SavePasswordCommand.class) { answer = execute((SavePasswordCommand) cmd); - } else if (cmd instanceof DhcpEntryCommand) { + } else if (clz == DhcpEntryCommand.class) { answer = execute((DhcpEntryCommand) cmd); - } else if (cmd instanceof VmDataCommand) { + } else if (clz == VmDataCommand.class) { answer = execute((VmDataCommand) cmd); - } else if (cmd instanceof ReadyCommand) { + } else if (clz == ReadyCommand.class) { answer = execute((ReadyCommand) cmd); - } else if (cmd instanceof GetHostStatsCommand) { + } else if (clz == GetHostStatsCommand.class) { answer = execute((GetHostStatsCommand) cmd); - } else if (cmd instanceof GetVmStatsCommand) { + } else if (clz == GetVmStatsCommand.class) { answer = execute((GetVmStatsCommand) cmd); - } else if (cmd instanceof CheckHealthCommand) { + } else if (clz == CheckHealthCommand.class) { answer = execute((CheckHealthCommand) cmd); - } else if (cmd instanceof StopCommand) { + } else if (clz == StopCommand.class) { answer = execute((StopCommand) cmd); - } else if (cmd instanceof RebootRouterCommand) { + } else if (clz == RebootRouterCommand.class) { answer = execute((RebootRouterCommand) cmd); - } else if (cmd instanceof RebootCommand) { + } else if (clz == RebootCommand.class) { answer = execute((RebootCommand) cmd); - } else if (cmd instanceof CheckVirtualMachineCommand) { + } else if (clz == CheckVirtualMachineCommand.class) { answer = execute((CheckVirtualMachineCommand) cmd); - } else if (cmd instanceof PrepareForMigrationCommand) { + } else if (clz == PrepareForMigrationCommand.class) { answer = execute((PrepareForMigrationCommand) cmd); - } else if (cmd instanceof MigrateCommand) { + } else if (clz == MigrateCommand.class) { answer = execute((MigrateCommand) cmd); - } else if (cmd instanceof DestroyCommand) { + } else if (clz == DestroyCommand.class) { answer = execute((DestroyCommand) cmd); - } else if (cmd instanceof CreateStoragePoolCommand) { + } else if (clz == CreateStoragePoolCommand.class) { return execute((CreateStoragePoolCommand) cmd); - } else if (cmd instanceof ModifyStoragePoolCommand) { + } else if (clz == ModifyStoragePoolCommand.class) { answer = execute((ModifyStoragePoolCommand) cmd); - } else if (cmd instanceof DeleteStoragePoolCommand) { + } else if (clz == DeleteStoragePoolCommand.class) { answer = execute((DeleteStoragePoolCommand) cmd); - } else if (cmd instanceof CopyVolumeCommand) { + } else if (clz == CopyVolumeCommand.class) { answer = execute((CopyVolumeCommand) cmd); - } else if (cmd instanceof AttachVolumeCommand) { + } else if (clz == AttachVolumeCommand.class) { answer = execute((AttachVolumeCommand) cmd); - } else if (cmd instanceof AttachIsoCommand) { + } else if (clz == AttachIsoCommand.class) { answer = execute((AttachIsoCommand) cmd); - } else if (cmd instanceof ValidateSnapshotCommand) { + } else if (clz == ValidateSnapshotCommand.class) { answer = execute((ValidateSnapshotCommand) cmd); - } else if (cmd instanceof ManageSnapshotCommand) { + } else if (clz == ManageSnapshotCommand.class) { answer = execute((ManageSnapshotCommand) cmd); - } else if (cmd instanceof BackupSnapshotCommand) { + } else if (clz == BackupSnapshotCommand.class) { answer = execute((BackupSnapshotCommand) cmd); - } else if (cmd instanceof CreateVolumeFromSnapshotCommand) { + } else if (clz == CreateVolumeFromSnapshotCommand.class) { answer = execute((CreateVolumeFromSnapshotCommand) cmd); - } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) { + } else if (clz == CreatePrivateTemplateFromVolumeCommand.class) { answer = execute((CreatePrivateTemplateFromVolumeCommand) cmd); - } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { + } else if (clz == CreatePrivateTemplateFromSnapshotCommand.class) { answer = execute((CreatePrivateTemplateFromSnapshotCommand) cmd); - } else if (cmd instanceof UpgradeSnapshotCommand) { + } else if (clz == UpgradeSnapshotCommand.class) { answer = execute((UpgradeSnapshotCommand) cmd); - } else if (cmd instanceof GetStorageStatsCommand) { + } else if (clz == GetStorageStatsCommand.class) { answer = execute((GetStorageStatsCommand) cmd); - } else if (cmd instanceof PrimaryStorageDownloadCommand) { + } else if (clz == PrimaryStorageDownloadCommand.class) { answer = execute((PrimaryStorageDownloadCommand) cmd); - } else if (cmd instanceof GetVncPortCommand) { + } else if (clz == GetVncPortCommand.class) { answer = execute((GetVncPortCommand) cmd); - } else if (cmd instanceof SetupCommand) { + } else if (clz == SetupCommand.class) { answer = execute((SetupCommand) cmd); - } else if (cmd instanceof MaintainCommand) { + } else if (clz == MaintainCommand.class) { answer = execute((MaintainCommand) cmd); - } else if (cmd instanceof PingTestCommand) { + } else if (clz == PingTestCommand.class) { answer = execute((PingTestCommand) cmd); - } else if (cmd instanceof CheckOnHostCommand) { + } else if (clz == CheckOnHostCommand.class) { answer = execute((CheckOnHostCommand) cmd); - } else if (cmd instanceof ModifySshKeysCommand) { + } else if (clz == ModifySshKeysCommand.class) { answer = execute((ModifySshKeysCommand) cmd); - } else if (cmd instanceof PoolEjectCommand) { + } else if (clz == PoolEjectCommand.class) { answer = execute((PoolEjectCommand) cmd); - } else if (cmd instanceof NetworkUsageCommand) { + } else if (clz == NetworkUsageCommand.class) { answer = execute((NetworkUsageCommand) cmd); - } else if (cmd instanceof StartCommand) { + } else if (clz == StartCommand.class) { answer = execute((StartCommand) cmd); - } else if (cmd instanceof RemoteAccessVpnCfgCommand) { + } else if (clz == RemoteAccessVpnCfgCommand.class) { answer = execute((RemoteAccessVpnCfgCommand) cmd); - } else if (cmd instanceof VpnUsersCfgCommand) { + } else if (clz == VpnUsersCfgCommand.class) { answer = execute((VpnUsersCfgCommand) cmd); - } else if (cmd instanceof CheckSshCommand) { + } else if (clz == CheckSshCommand.class) { answer = execute((CheckSshCommand) cmd); - } else if (cmd instanceof CheckRouterCommand) { + } else if (clz == CheckRouterCommand.class) { answer = execute((CheckRouterCommand) cmd); - } else if (cmd instanceof SetFirewallRulesCommand) { + } else if (clz == SetFirewallRulesCommand.class) { answer = execute((SetFirewallRulesCommand)cmd); - } else if (cmd instanceof BumpUpPriorityCommand) { + } else if (clz == BumpUpPriorityCommand.class) { answer = execute((BumpUpPriorityCommand)cmd); - } else if (cmd instanceof GetDomRVersionCmd) { + } else if (clz == GetDomRVersionCmd.class) { answer = execute((GetDomRVersionCmd)cmd); - } else if (cmd instanceof CheckNetworkCommand) { + } else if (clz == CheckNetworkCommand.class) { answer = execute((CheckNetworkCommand) cmd); + } else if (clz == SetupGuestNetworkCommand.class) { + answer = execute((SetupGuestNetworkCommand) cmd); + } else if (clz == IpAssocVpcCommand.class) { + answer = execute((IpAssocVpcCommand) cmd); + } else if (clz == PlugNicCommand.class) { + answer = execute((PlugNicCommand) cmd); + } else if (clz == UnPlugNicCommand.class) { + answer = execute((UnPlugNicCommand) cmd); + } else if (clz == SetSourceNatCommand.class) { + answer = execute((SetSourceNatCommand) cmd); + } else if (clz == SetNetworkACLCommand.class) { + answer = execute((SetNetworkACLCommand) cmd); + } else if (clz == SetPortForwardingRulesVpcCommand.class) { + answer = execute((SetPortForwardingRulesVpcCommand) cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); } @@ -709,6 +739,485 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } + // + // list available ethx devices + // ls /proc/sys/net/ipv4/conf + // + private int allocRouterEthDeviceIndex(String domrName, String routerIp) throws Exception { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "ls /proc/sys/net/ipv4/conf"); + + if(result.first()) { + String[] tokens = result.second().split("\\s+"); + HashMap deviceNames = new HashMap(); + for(String token: tokens) { + if(!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { + deviceNames.put(token, token); + } + } + + for(int i = 1; ; i++) { + if(!deviceNames.containsKey("eth" + i)) + return i; + } + } + + return -1; + } + +// +// find mac address of a specified ethx device +// ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 +// returns +// eth0:xx.xx.xx.xx + +// +// list IP with eth devices +// ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' +// | awk -F: '{ print $1 ": " $3 }' +// +// returns +// eth0:xx.xx.xx.xx +// +// + private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + s_logger.info("findRouterEthDeviceIndex. mac: " + mac); + + // TODO : this is a temporary very inefficient solution, will refactor it later + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "ls /proc/sys/net/ipv4/conf"); + + // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS + // we use a waiting loop here as a workaround to synchronize activities in systems + long startTick = System.currentTimeMillis(); + while(System.currentTimeMillis() - startTick < 15000) { + if(result.first()) { + String[] tokens = result.second().split("\\s+"); + for(String token : tokens) { + if(!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { + String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + + if(s_logger.isDebugEnabled()) + s_logger.debug("Run domr script " + cmd); + Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + // TODO need to find the dev index inside router based on IP address + cmd); + if(s_logger.isDebugEnabled()) + s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); + + if(result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) + return Integer.parseInt(token.substring(3)); + } + } + } + + s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry..."); + + try { + Thread.currentThread().sleep(1000); + } catch (InterruptedException e) { + } + } + + return -1; + } + + private VirtualDevice findVirtualNicDevice(VirtualMachineMO vmMo, String mac) throws Exception { + + VirtualDevice[] nics = vmMo.getNicDevices(); + for(VirtualDevice nic : nics) { + if(nic instanceof VirtualEthernetCard) { + if(((VirtualEthernetCard)nic).getMacAddress().equals(mac)) + return nic; + } + } + return null; + } + + private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + + s_logger.info("Executing resource SetupGuestNetworkCommand " + _gson.toJson(cmd)); + + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + NicTO nic = cmd.getNic(); + + String routerIp = getRouterSshControlIp(cmd); + String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); + String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); + String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask()));; + String domainName = cmd.getNetworkDomain(); + String dns = cmd.getDefaultDns1(); + if (dns == null || dns.isEmpty()) { + dns = cmd.getDefaultDns2(); + } else { + String dns2= cmd.getDefaultDns2(); + if ( dns2 != null && !dns2.isEmpty()) { + dns += "," + dns2; + } + } + + try { + int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, nic.getMac()); + s_logger.info("find interface index. routerIp: " + routerIp + ", mac: " + nic.getMac() + ", index: " + ethDeviceNum); + + String args = "-C "; + String dev = "eth" + ethDeviceNum; + args += " -d " + dev; + args += " -i " + domrGIP; + args += " -g " + gw; + args += " -m " + cidr; + args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); + if ( dns != null && !dns.isEmpty() ) { + args += " -s " + dns; + } + if ( domainName != null && !domainName.isEmpty() ) { + args += " -e " + domainName; + } + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_guestnw.sh " + args); + + if (!result.first()) { + String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); + s_logger.error(msg); + + return new SetupGuestNetworkAnswer(cmd, false, msg); + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("SetupGuestNetworkCommand on domain router " + routerIp + " completed"); + } + + return new SetupGuestNetworkAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = "SetupGuestNetwork failed due to " + e.toString(); + s_logger.warn(msg, e); + return new SetupGuestNetworkAnswer(cmd, false, msg); + } + } + + protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource IpAssocVpcCommand " + _gson.toJson(cmd)); + } + + String[] results = new String[cmd.getIpAddresses().length]; + int i = 0; + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + + assignVPCPublicIpAddress(routerName, routerIp, ip); + results[i++] = ip.getPublicIp() + " - success"; + } + } catch (Exception e) { + s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); + results[i++] = IpAssocAnswer.errorResult; + } + + return new IpAssocAnswer(cmd, results); + } + + protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource SetSourceNatCommand " + _gson.toJson(cmd)); + } + + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + IpAddressTO pubIp = cmd.getIpAddress(); + try { + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress()); + String args = ""; + args += " -A "; + args += " -l "; + args += pubIp.getPublicIp(); + + args += " -c "; + args += "eth" + ethDeviceNum; + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_snat.sh " + args); + + if (!result.first()) { + String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); + s_logger.error(msg); + + return new SetSourceNatAnswer(cmd, false, msg); + } + + return new SetSourceNatAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = "Ip SNAT failure due to " + e.toString(); + s_logger.error(msg, e); + return new SetSourceNatAnswer(cmd, false, msg); + } + } + + private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource SetNetworkACLCommand " + _gson.toJson(cmd)); + } + + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + + String[] results = new String[cmd.getRules().length]; + try { + String [][] rules = cmd.generateFwRules(); + StringBuilder sb = new StringBuilder(); + String[] aclRules = rules[0]; + if (aclRules.length == 0) { + return new SetNetworkACLAnswer(cmd, true, results); + } + + for (int i = 0; i < aclRules.length; i++) { + sb.append(aclRules[i]).append(','); + } + + NicTO nic = cmd.getNic(); + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, nic.getMac()); + String args = ""; + args += " -d " + "eth" + ethDeviceNum; + args += " -i " + nic.getIp(); + args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + args += " -a " + sb.toString(); + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_acl.sh " + args); + + if (!result.first()) { + String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.second(); + s_logger.error(msg); + + return new SetNetworkACLAnswer(cmd, false, results); + } + + return new SetNetworkACLAnswer(cmd, true, results); + } catch (Exception e) { + String msg = "SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new SetNetworkACLAnswer(cmd, false, results); + } + } + + protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource SetPortForwardingRulesVpcCommand " + _gson.toJson(cmd)); + } + + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + String routerIp = getRouterSshControlIp(cmd); + + String[] results = new String[cmd.getRules().length]; + int i = 0; + + boolean endResult = true; + for (PortForwardingRuleTO rule : cmd.getRules()) { + String args =""; + args += rule.revoked() ? " -D" : " -A"; + args += " -P " + rule.getProtocol().toLowerCase(); + args += " -l " + rule.getSrcIp(); + args += " -p " + rule.getStringSrcPortRange().replace(":", "-"); + args += " -r " + rule.getDstIp(); + args += " -d " + rule.getStringDstPortRange().replace(":", "-"); + + try { + Pair sshResult = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_portforwarding " + args); + + if (!sshResult.first()) { + results[i++] = "Failed"; + endResult = false; + } else { + results[i++] = null; + } + } catch(Exception e) { + results[i++] = "Failed"; + endResult = false; + } + } + return new SetPortForwardingRulesAnswer(cmd, results, endResult); + } + + + private PlugNicAnswer execute(PlugNicCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource PlugNicCommand " + _gson.toJson(cmd)); + } + + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + VmwareContext context = getServiceContext(); + try { + VmwareHypervisorHost hyperHost = getHyperHost(context); + + String vmName = cmd.getVirtualMachine().getName(); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); + + if(vmMo == null) { + if(hyperHost instanceof HostMO) { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), + ((HostMO)hyperHost).getParentMor()); + vmMo = clusterMo.findVmOnHyperHost(vmName); + } + } + + if (vmMo == null) { + String msg = "Router " + vmName + " no longer exists to execute PlugNic command"; + s_logger.error(msg); + throw new Exception(msg); + } + + // TODO need a way to specify the control of NIC device type + VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000; + + // find a usable device number in VMware environment + VirtualDevice[] nicDevices = vmMo.getNicDevices(); + int deviceNumber = -1; + for(VirtualDevice device : nicDevices) { + if(device.getUnitNumber() > deviceNumber) + deviceNumber = device.getUnitNumber(); + } + deviceNumber++; + + NicTO nicTo = cmd.getNic(); + VirtualDevice nic; + Pair networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo); + if (mgr.getNexusVSwitchGlobalParameter()) { + String dvSwitchUuid; + ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter(); + DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor); + ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first()); + dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor); + s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid); + nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), + dvSwitchUuid, nicTo.getMac(), deviceNumber, deviceNumber + 1, true, true); + } else { + s_logger.info("Preparing NIC device on network " + networkInfo.second()); + nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), + deviceNumber, deviceNumber + 1, true, true); + } + + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); + VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1]; + deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec(); + deviceConfigSpecArray[0].setDevice(nic); + deviceConfigSpecArray[0].setOperation(VirtualDeviceConfigSpecOperation.add); + + vmConfigSpec.setDeviceChange(deviceConfigSpecArray); + if(!vmMo.configureVm(vmConfigSpec)) { + throw new Exception("Failed to configure devices when running PlugNicCommand"); + } + + return new PlugNicAnswer(cmd, true, "success"); + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString()); + } + } + + private UnPlugNicAnswer execute(UnPlugNicCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource UnPlugNicCommand " + _gson.toJson(cmd)); + } + + VmwareContext context = getServiceContext(); + try { + VmwareHypervisorHost hyperHost = getHyperHost(context); + + String vmName = cmd.getVirtualMachine().getName(); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); + + if(vmMo == null) { + if(hyperHost instanceof HostMO) { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), + ((HostMO)hyperHost).getParentMor()); + vmMo = clusterMo.findVmOnHyperHost(vmName); + } + } + + if (vmMo == null) { + String msg = "VM " + vmName + " no longer exists to execute UnPlugNic command"; + s_logger.error(msg); + throw new Exception(msg); + } + + VirtualDevice nic = findVirtualNicDevice(vmMo, cmd.getNic().getMac()); + + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); + VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1]; + deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec(); + deviceConfigSpecArray[0].setDevice(nic); + deviceConfigSpecArray[0].setOperation(VirtualDeviceConfigSpecOperation.remove); + + vmConfigSpec.setDeviceChange(deviceConfigSpecArray); + if(!vmMo.configureVm(vmConfigSpec)) { + throw new Exception("Failed to configure devices when running unplugNicCommand"); + } + + return new UnPlugNicAnswer(cmd, true, "success"); + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + e.toString()); + } + } + + protected void assignVPCPublicIpAddress(String domrName, String routerIp, IpAddressTO ip) throws Exception { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource assignVPCPublicIpAddress. domrName: " + domrName + ", routerIp: " + routerIp + + ", ip: " + _gson.toJson(ip)); + } + + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + int ethDeviceNum = this.findRouterEthDeviceIndex(domrName, routerIp, ip.getVifMacAddress()); + if (ethDeviceNum < 0) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + String args = ""; + if (ip.isAdd()) { + args += " -A "; + } else { + args += " -D "; + } + + args += " -l "; + args += ip.getPublicIp(); + + args += " -c "; + args += "eth" + ethDeviceNum; + + args += " -g "; + args += ip.getVlanGateway(); + + args += " -m "; + args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + + args += " -n "; + args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_ipassoc.sh " + args); + + if (!result.first()) { + throw new InternalErrorException("Unable to assign public IP address"); + } + } + protected void assignPublicIpAddress(VirtualMachineMO vmMo, final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, String guestIp) throws Exception { @@ -792,23 +1301,23 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa nicMasks &= ~(1 << publicNicInfo.first().intValue()); vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks)); - HostMO hostMo = vmMo.getRunningHost(); - List networks = vmMo.getNetworksWithDetails(); - for (NetworkDetails netDetails : networks) { - if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { - if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { - cleanupNetwork(hostMo, netDetails); - } - } - } - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("ipassoc command on domain router " + privateIpAddress + " completed"); - } - } - - private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final String vifMacAddress) throws Exception { + HostMO hostMo = vmMo.getRunningHost(); + List networks = vmMo.getNetworksWithDetails(); + for (NetworkDetails netDetails : networks) { + if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { + if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { + cleanupNetwork(hostMo, netDetails); + } + } + } + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("ipassoc command on domain router " + privateIpAddress + " completed"); + } + } + + private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final String vifMacAddress) throws Exception { // TODO : probably need to set traffic shaping Pair networkInfo = null; @@ -1478,33 +1987,33 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vol.getType() != Volume.Type.ISO) { Pair volumeDsDetails = dataStoresDetails.get(vol.getPoolUuid()); assert (volumeDsDetails != null); - VirtualDevice device; - datastoreDiskPath = String.format("[%s] %s.vmdk", volumeDsDetails.second().getName(), vol.getPath()); - String chainInfo = vol.getChainInfo(); - - if (chainInfo != null && !chainInfo.isEmpty()) { - String[] diskChain = _gson.fromJson(chainInfo, String[].class); - if (diskChain == null || diskChain.length < 1) { - s_logger.warn("Empty previously-saved chain info, fall back to the original"); - device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, new String[] { datastoreDiskPath }, volumeDsDetails.first(), i, i + 1); - } else { - s_logger.info("Attach the disk with stored chain info: " + chainInfo); - for (int j = 0; j < diskChain.length; j++) { - diskChain[j] = String.format("[%s] %s", volumeDsDetails.second().getName(), diskChain[j]); - } - - device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, diskChain, volumeDsDetails.first(), i, i + 1); - } - } else { - device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, new String[] { datastoreDiskPath }, volumeDsDetails.first(), i, i + 1); - } - deviceConfigSpecArray[i].setDevice(device); - deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.add); - - if(s_logger.isDebugEnabled()) - s_logger.debug("Prepare volume at new device " + _gson.toJson(device)); - - i++; + VirtualDevice device; + datastoreDiskPath = String.format("[%s] %s.vmdk", volumeDsDetails.second().getName(), vol.getPath()); + String chainInfo = vol.getChainInfo(); + + if (chainInfo != null && !chainInfo.isEmpty()) { + String[] diskChain = _gson.fromJson(chainInfo, String[].class); + if (diskChain == null || diskChain.length < 1) { + s_logger.warn("Empty previously-saved chain info, fall back to the original"); + device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, new String[] { datastoreDiskPath }, volumeDsDetails.first(), i, i + 1); + } else { + s_logger.info("Attach the disk with stored chain info: " + chainInfo); + for (int j = 0; j < diskChain.length; j++) { + diskChain[j] = String.format("[%s] %s", volumeDsDetails.second().getName(), diskChain[j]); + } + + device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, diskChain, volumeDsDetails.first(), i, i + 1); + } + } else { + device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, new String[] { datastoreDiskPath }, volumeDsDetails.first(), i, i + 1); + } + deviceConfigSpecArray[i].setDevice(device); + deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.add); + + if(s_logger.isDebugEnabled()) + s_logger.debug("Prepare volume at new device " + _gson.toJson(device)); + + i++; } } @@ -1528,11 +2037,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), i, i + 1, true, true); } - deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); - deviceConfigSpecArray[i].setDevice(nic); - deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.add); - - if(s_logger.isDebugEnabled()) + deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); + deviceConfigSpecArray[i].setDevice(nic); + deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.add); + + if(s_logger.isDebugEnabled()) s_logger.debug("Prepare NIC at new device " + _gson.toJson(deviceConfigSpecArray[i])); // this is really a hacking for DomR, upon DomR startup, we will reset all the NIC allocation after eth3 @@ -1704,29 +2213,29 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } poolMors.put(vol.getPoolUuid(), new Pair (morDataStore, new DatastoreMO(context, morDataStore))); } - } - } - return poolMors; - } - - private String getVlanInfo(NicTO nicTo, String defaultVlan) { - if (nicTo.getBroadcastType() == BroadcastDomainType.Native) { - return defaultVlan; - } - - if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan) { - if (nicTo.getBroadcastUri() != null) { - return nicTo.getBroadcastUri().getHost(); - } else { - s_logger.warn("BroadcastType is not claimed as VLAN, but without vlan info in broadcast URI. Use vlan info from labeling: " + defaultVlan); - return defaultVlan; - } - } - - s_logger.warn("Unrecognized broadcast type in VmwareResource, type: " + nicTo.getBroadcastType().toString() + ". Use vlan info from labeling: " + defaultVlan); - return defaultVlan; - } - + } + } + return poolMors; + } + + private String getVlanInfo(NicTO nicTo, String defaultVlan) { + if (nicTo.getBroadcastType() == BroadcastDomainType.Native) { + return defaultVlan; + } + + if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan) { + if (nicTo.getBroadcastUri() != null) { + return nicTo.getBroadcastUri().getHost(); + } else { + s_logger.warn("BroadcastType is not claimed as VLAN, but without vlan info in broadcast URI. Use vlan info from labeling: " + defaultVlan); + return defaultVlan; + } + } + + s_logger.warn("Unrecognized broadcast type in VmwareResource, type: " + nicTo.getBroadcastType().toString() + ". Use vlan info from labeling: " + defaultVlan); + return defaultVlan; + } + private Pair prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo) throws Exception { Pair switchName = getTargetSwitch(nicTo); @@ -2350,131 +2859,131 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (pool.getType() != StoragePoolType.NetworkFilesystem && pool.getType() != StoragePoolType.VMFS) { throw new Exception("Unsupported storage pool type " + pool.getType()); - } - + } + ManagedObjectReference morDatastore = null; morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, pool.getUuid()); if(morDatastore == null) morDatastore = hyperHost.mountDatastore(pool.getType() == StoragePoolType.VMFS, pool.getHost(), - pool.getPort(), pool.getPath(), pool.getUuid().replace("-", "")); - - assert (morDatastore != null); - DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary(); - long capacity = summary.getCapacity(); - long available = summary.getFreeSpace(); - Map tInfo = new HashMap(); - ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo); - return answer; - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "ModifyStoragePoolCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - } - - protected Answer execute(DeleteStoragePoolCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource DeleteStoragePoolCommand: " + _gson.toJson(cmd)); - } - - StorageFilerTO pool = cmd.getPool(); + pool.getPort(), pool.getPath(), pool.getUuid().replace("-", "")); + + assert (morDatastore != null); + DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary(); + long capacity = summary.getCapacity(); + long available = summary.getFreeSpace(); + Map tInfo = new HashMap(); + ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo); + return answer; + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String msg = "ModifyStoragePoolCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new Answer(cmd, false, msg); + } + } + + protected Answer execute(DeleteStoragePoolCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource DeleteStoragePoolCommand: " + _gson.toJson(cmd)); + } + + StorageFilerTO pool = cmd.getPool(); try { // We will leave datastore cleanup management to vCenter. Since for cluster VMFS datastore, it will always // be mounted by vCenter. - - // VmwareHypervisorHost hyperHost = this.getHyperHost(getServiceContext()); - // hyperHost.unmountDatastore(pool.getUuid()); - Answer answer = new Answer(cmd, true, "success"); - return answer; - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "DeleteStoragePoolCommand (pool: " + pool.getHost() + ", path: " + pool.getPath() + ") failed due to " + VmwareHelper.getExceptionMessage(e); - return new Answer(cmd, false, msg); - } - } - - protected Answer execute(AttachVolumeCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource AttachVolumeCommand: " + _gson.toJson(cmd)); - } - - /* - * AttachVolumeCommand { "attach":true,"vmName":"i-2-1-KY","pooltype":"NetworkFilesystem", - * "volumeFolder":"/export/home/kelven/vmware-test/primary", "volumePath":"uuid", - * "volumeName":"volume name","deviceId":1 } - */ - try { - VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); - VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); - if (vmMo == null) { - String msg = "Unable to find the VM to execute AttachVolumeCommand, vmName: " + cmd.getVmName(); - s_logger.error(msg); - throw new Exception(msg); - } - - ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPoolUuid()); - if (morDs == null) { - String msg = "Unable to find the mounted datastore to execute AttachVolumeCommand, vmName: " + cmd.getVmName(); - s_logger.error(msg); - throw new Exception(msg); - } - - DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDs); - String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), cmd.getVolumePath()); - - AttachVolumeAnswer answer = new AttachVolumeAnswer(cmd, cmd.getDeviceId()); - if (cmd.getAttach()) { - vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); - } else { - vmMo.removeAllSnapshots(); - vmMo.detachDisk(datastoreVolumePath, false); - } - - return answer; - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "AttachVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new AttachVolumeAnswer(cmd, msg); - } - } - - protected Answer execute(AttachIsoCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource AttachIsoCommand: " + _gson.toJson(cmd)); - } - - try { - VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); - VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); - if (vmMo == null) { - String msg = "Unable to find VM in vSphere to execute AttachIsoCommand, vmName: " + cmd.getVmName(); - s_logger.error(msg); - throw new Exception(msg); - } - - String storeUrl = cmd.getStoreUrl(); - if (storeUrl == null) { - if (!cmd.getIsoPath().equalsIgnoreCase("vmware-tools.iso")) { - String msg = "ISO store root url is not found in AttachIsoCommand"; - s_logger.error(msg); - throw new Exception(msg); - } else { - if (cmd.isAttach()) { - vmMo.mountToolsInstaller(); + + // VmwareHypervisorHost hyperHost = this.getHyperHost(getServiceContext()); + // hyperHost.unmountDatastore(pool.getUuid()); + Answer answer = new Answer(cmd, true, "success"); + return answer; + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String msg = "DeleteStoragePoolCommand (pool: " + pool.getHost() + ", path: " + pool.getPath() + ") failed due to " + VmwareHelper.getExceptionMessage(e); + return new Answer(cmd, false, msg); + } + } + + protected Answer execute(AttachVolumeCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource AttachVolumeCommand: " + _gson.toJson(cmd)); + } + + /* + * AttachVolumeCommand { "attach":true,"vmName":"i-2-1-KY","pooltype":"NetworkFilesystem", + * "volumeFolder":"/export/home/kelven/vmware-test/primary", "volumePath":"uuid", + * "volumeName":"volume name","deviceId":1 } + */ + try { + VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); + if (vmMo == null) { + String msg = "Unable to find the VM to execute AttachVolumeCommand, vmName: " + cmd.getVmName(); + s_logger.error(msg); + throw new Exception(msg); + } + + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPoolUuid()); + if (morDs == null) { + String msg = "Unable to find the mounted datastore to execute AttachVolumeCommand, vmName: " + cmd.getVmName(); + s_logger.error(msg); + throw new Exception(msg); + } + + DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDs); + String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), cmd.getVolumePath()); + + AttachVolumeAnswer answer = new AttachVolumeAnswer(cmd, cmd.getDeviceId()); + if (cmd.getAttach()) { + vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); + } else { + vmMo.removeAllSnapshots(); + vmMo.detachDisk(datastoreVolumePath, false); + } + + return answer; + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String msg = "AttachVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new AttachVolumeAnswer(cmd, msg); + } + } + + protected Answer execute(AttachIsoCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource AttachIsoCommand: " + _gson.toJson(cmd)); + } + + try { + VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); + if (vmMo == null) { + String msg = "Unable to find VM in vSphere to execute AttachIsoCommand, vmName: " + cmd.getVmName(); + s_logger.error(msg); + throw new Exception(msg); + } + + String storeUrl = cmd.getStoreUrl(); + if (storeUrl == null) { + if (!cmd.getIsoPath().equalsIgnoreCase("vmware-tools.iso")) { + String msg = "ISO store root url is not found in AttachIsoCommand"; + s_logger.error(msg); + throw new Exception(msg); + } else { + if (cmd.isAttach()) { + vmMo.mountToolsInstaller(); } else { try{ vmMo.unmountToolsInstaller(); @@ -2525,223 +3034,223 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "AttachIsoCommand(detach) failed due to " + VmwareHelper.getExceptionMessage(e); s_logger.warn(msg, e); return new Answer(cmd, false, msg); - } - } - } - - private synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception { - String storeName = getSecondaryDatastoreUUID(storeUrl); - URI uri = new URI(storeUrl); - - VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); - ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", "")); - + } + } + } + + private synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception { + String storeName = getSecondaryDatastoreUUID(storeUrl); + URI uri = new URI(storeUrl); + + VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); + ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", "")); + if (morDatastore == null) - throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl); - - return morDatastore; - } - - private static String getSecondaryDatastoreUUID(String storeUrl) { - return UUID.nameUUIDFromBytes(storeUrl.getBytes()).toString(); - } - - protected Answer execute(ValidateSnapshotCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource ValidateSnapshotCommand: " + _gson.toJson(cmd)); - } - - // the command is no longer available - String expectedSnapshotBackupUuid = null; - String actualSnapshotBackupUuid = null; - String actualSnapshotUuid = null; - return new ValidateSnapshotAnswer(cmd, false, "ValidateSnapshotCommand is not supported for vmware yet", expectedSnapshotBackupUuid, actualSnapshotBackupUuid, actualSnapshotUuid); - } - - protected Answer execute(ManageSnapshotCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource ManageSnapshotCommand: " + _gson.toJson(cmd)); - } - - long snapshotId = cmd.getSnapshotId(); - - /* - * "ManageSnapshotCommand", - * "{\"_commandSwitch\":\"-c\",\"_volumePath\":\"i-2-3-KY-ROOT\",\"_snapshotName\":\"i-2-3-KY_i-2-3-KY-ROOT_20101102203827\",\"_snapshotId\":1,\"_vmName\":\"i-2-3-KY\"}" - */ - boolean success = false; - String cmdSwitch = cmd.getCommandSwitch(); - String snapshotOp = "Unsupported snapshot command." + cmdSwitch; - if (cmdSwitch.equals(ManageSnapshotCommand.CREATE_SNAPSHOT)) { - snapshotOp = "create"; - } else if (cmdSwitch.equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) { - snapshotOp = "destroy"; - } - - String details = "ManageSnapshotCommand operation: " + snapshotOp + " Failed for snapshotId: " + snapshotId; - String snapshotUUID = null; + throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl); + + return morDatastore; + } + + private static String getSecondaryDatastoreUUID(String storeUrl) { + return UUID.nameUUIDFromBytes(storeUrl.getBytes()).toString(); + } + + protected Answer execute(ValidateSnapshotCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource ValidateSnapshotCommand: " + _gson.toJson(cmd)); + } + + // the command is no longer available + String expectedSnapshotBackupUuid = null; + String actualSnapshotBackupUuid = null; + String actualSnapshotUuid = null; + return new ValidateSnapshotAnswer(cmd, false, "ValidateSnapshotCommand is not supported for vmware yet", expectedSnapshotBackupUuid, actualSnapshotBackupUuid, actualSnapshotUuid); + } + + protected Answer execute(ManageSnapshotCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource ManageSnapshotCommand: " + _gson.toJson(cmd)); + } + + long snapshotId = cmd.getSnapshotId(); + + /* + * "ManageSnapshotCommand", + * "{\"_commandSwitch\":\"-c\",\"_volumePath\":\"i-2-3-KY-ROOT\",\"_snapshotName\":\"i-2-3-KY_i-2-3-KY-ROOT_20101102203827\",\"_snapshotId\":1,\"_vmName\":\"i-2-3-KY\"}" + */ + boolean success = false; + String cmdSwitch = cmd.getCommandSwitch(); + String snapshotOp = "Unsupported snapshot command." + cmdSwitch; + if (cmdSwitch.equals(ManageSnapshotCommand.CREATE_SNAPSHOT)) { + snapshotOp = "create"; + } else if (cmdSwitch.equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) { + snapshotOp = "destroy"; + } + + String details = "ManageSnapshotCommand operation: " + snapshotOp + " Failed for snapshotId: " + snapshotId; + String snapshotUUID = null; // snapshot operation (create or destroy) is handled inside BackupSnapshotCommand(), we just fake // a success return here snapshotUUID = UUID.randomUUID().toString(); success = true; details = null; - - return new ManageSnapshotAnswer(cmd, snapshotId, snapshotUUID, success, details); - } - - protected Answer execute(BackupSnapshotCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource BackupSnapshotCommand: " + _gson.toJson(cmd)); - } - - try { - VmwareContext context = getServiceContext(); - VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - return mgr.getStorageManager().execute(this, cmd); - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String details = "BackupSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(details, e); - return new BackupSnapshotAnswer(cmd, false, details, null, true); - } - } - - - protected Answer execute(CreateVolumeFromSnapshotCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource CreateVolumeFromSnapshotCommand: " + _gson.toJson(cmd)); - } - - String details = null; - boolean success = false; - String newVolumeName = UUID.randomUUID().toString(); - - try { - VmwareContext context = getServiceContext(); - VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - return mgr.getStorageManager().execute(this, cmd); - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - details = "CreateVolumeFromSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(details, e); - } - - return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName); - } - - protected Answer execute(CreatePrivateTemplateFromVolumeCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource CreatePrivateTemplateFromVolumeCommand: " + _gson.toJson(cmd)); - } - - try { - VmwareContext context = getServiceContext(); - VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - return mgr.getStorageManager().execute(this, cmd); - - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String details = "CreatePrivateTemplateFromVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(details, e); - return new CreatePrivateTemplateAnswer(cmd, false, details); - } - } - - protected Answer execute(final UpgradeSnapshotCommand cmd) { - return new Answer(cmd, true, "success"); - } - - protected Answer execute(CreatePrivateTemplateFromSnapshotCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource CreatePrivateTemplateFromSnapshotCommand: " + _gson.toJson(cmd)); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - return mgr.getStorageManager().execute(this, cmd); - - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String details = "CreatePrivateTemplateFromSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(details, e); - return new CreatePrivateTemplateAnswer(cmd, false, details); - } - } - - protected Answer execute(GetStorageStatsCommand cmd) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing resource GetStorageStatsCommand: " + _gson.toJson(cmd)); - } - - try { - VmwareContext context = getServiceContext(); - VmwareHypervisorHost hyperHost = getHyperHost(context); - ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getStorageId()); - - if (morDs != null) { - DatastoreMO datastoreMo = new DatastoreMO(context, morDs); - DatastoreSummary summary = datastoreMo.getSummary(); - assert (summary != null); - - long capacity = summary.getCapacity(); - long free = summary.getFreeSpace(); - long used = capacity - free; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Datastore summary info, storageId: " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype() + ", capacity: " + capacity - + ", free: " + free + ", used: " + used); - } - - if (summary.getCapacity() <= 0) { - s_logger.warn("Something is wrong with vSphere NFS datastore, rebooting ESX(ESXi) host should help"); - } - - return new GetStorageStatsAnswer(cmd, capacity, used); - } else { - String msg = "Could not find datastore for GetStorageStatsCommand storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype(); - - s_logger.error(msg); - return new GetStorageStatsAnswer(cmd, msg); - } - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "Unable to execute GetStorageStatsCommand(storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype() + ") due to " - + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new GetStorageStatsAnswer(cmd, msg); - } - } - - protected Answer execute(GetVncPortCommand cmd) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing resource GetVncPortCommand: " + _gson.toJson(cmd)); - } - - try { - VmwareContext context = getServiceContext(); + + return new ManageSnapshotAnswer(cmd, snapshotId, snapshotUUID, success, details); + } + + protected Answer execute(BackupSnapshotCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource BackupSnapshotCommand: " + _gson.toJson(cmd)); + } + + try { + VmwareContext context = getServiceContext(); + VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + return mgr.getStorageManager().execute(this, cmd); + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String details = "BackupSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(details, e); + return new BackupSnapshotAnswer(cmd, false, details, null, true); + } + } + + + protected Answer execute(CreateVolumeFromSnapshotCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource CreateVolumeFromSnapshotCommand: " + _gson.toJson(cmd)); + } + + String details = null; + boolean success = false; + String newVolumeName = UUID.randomUUID().toString(); + + try { + VmwareContext context = getServiceContext(); + VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + return mgr.getStorageManager().execute(this, cmd); + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + details = "CreateVolumeFromSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(details, e); + } + + return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName); + } + + protected Answer execute(CreatePrivateTemplateFromVolumeCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource CreatePrivateTemplateFromVolumeCommand: " + _gson.toJson(cmd)); + } + + try { + VmwareContext context = getServiceContext(); + VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + return mgr.getStorageManager().execute(this, cmd); + + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String details = "CreatePrivateTemplateFromVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(details, e); + return new CreatePrivateTemplateAnswer(cmd, false, details); + } + } + + protected Answer execute(final UpgradeSnapshotCommand cmd) { + return new Answer(cmd, true, "success"); + } + + protected Answer execute(CreatePrivateTemplateFromSnapshotCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource CreatePrivateTemplateFromSnapshotCommand: " + _gson.toJson(cmd)); + } + + try { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + return mgr.getStorageManager().execute(this, cmd); + + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String details = "CreatePrivateTemplateFromSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(details, e); + return new CreatePrivateTemplateAnswer(cmd, false, details); + } + } + + protected Answer execute(GetStorageStatsCommand cmd) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Executing resource GetStorageStatsCommand: " + _gson.toJson(cmd)); + } + + try { + VmwareContext context = getServiceContext(); + VmwareHypervisorHost hyperHost = getHyperHost(context); + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getStorageId()); + + if (morDs != null) { + DatastoreMO datastoreMo = new DatastoreMO(context, morDs); + DatastoreSummary summary = datastoreMo.getSummary(); + assert (summary != null); + + long capacity = summary.getCapacity(); + long free = summary.getFreeSpace(); + long used = capacity - free; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Datastore summary info, storageId: " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype() + ", capacity: " + capacity + + ", free: " + free + ", used: " + used); + } + + if (summary.getCapacity() <= 0) { + s_logger.warn("Something is wrong with vSphere NFS datastore, rebooting ESX(ESXi) host should help"); + } + + return new GetStorageStatsAnswer(cmd, capacity, used); + } else { + String msg = "Could not find datastore for GetStorageStatsCommand storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype(); + + s_logger.error(msg); + return new GetStorageStatsAnswer(cmd, msg); + } + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String msg = "Unable to execute GetStorageStatsCommand(storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype() + ") due to " + + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new GetStorageStatsAnswer(cmd, msg); + } + } + + protected Answer execute(GetVncPortCommand cmd) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Executing resource GetVncPortCommand: " + _gson.toJson(cmd)); + } + + try { + VmwareContext context = getServiceContext(); VmwareHypervisorHost hyperHost = getHyperHost(context); assert(hyperHost instanceof HostMO); VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); @@ -2820,74 +3329,74 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } protected Answer execute(ModifySshKeysCommand cmd) { - //do not log the command contents for this command. do NOT log the ssh keys - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource ModifySshKeysCommand."); - } - - return new Answer(cmd); - } - - protected Answer execute(PoolEjectCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource PoolEjectCommand: " + _gson.toJson(cmd)); - } - - return new Answer(cmd, false, "PoolEjectCommand is not available for vmware"); - } - - @Override - public PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource PrimaryStorageDownloadCommand: " + _gson.toJson(cmd)); - } - - try { - VmwareContext context = getServiceContext(); - VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - return (PrimaryStorageDownloadAnswer) mgr.getStorageManager().execute(this, cmd); - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "PrimaryStorageDownloadCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new PrimaryStorageDownloadAnswer(msg); - } - } - - @Override - public Answer execute(DestroyCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource DestroyCommand: " + _gson.toJson(cmd)); - } - - /* - * DestroyCommand content example - * - * {"volume": {"id":5,"name":"Volume1", "mountPoint":"/export/home/kelven/vmware-test/primary", - * "path":"6bb8762f-c34c-453c-8e03-26cc246ceec4", "size":0,"type":"DATADISK","resourceType": - * "STORAGE_POOL","storagePoolType":"NetworkFilesystem", "poolId":0,"deviceId":0 } } - * - * {"volume": {"id":1, "name":"i-2-1-KY-ROOT", "mountPoint":"/export/home/kelven/vmware-test/primary", - * "path":"i-2-1-KY-ROOT","size":0,"type":"ROOT", "resourceType":"STORAGE_POOL", "storagePoolType":"NetworkFilesystem", - * "poolId":0,"deviceId":0 } } - */ - - try { - VmwareContext context = getServiceContext(); - VmwareHypervisorHost hyperHost = getHyperHost(context); - VolumeTO vol = cmd.getVolume(); - - ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, vol.getPoolUuid()); - if (morDs == null) { - String msg = "Unable to find datastore based on volume mount point " + cmd.getVolume().getMountPoint(); - s_logger.error(msg); - throw new Exception(msg); - } - + //do not log the command contents for this command. do NOT log the ssh keys + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource ModifySshKeysCommand."); + } + + return new Answer(cmd); + } + + protected Answer execute(PoolEjectCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource PoolEjectCommand: " + _gson.toJson(cmd)); + } + + return new Answer(cmd, false, "PoolEjectCommand is not available for vmware"); + } + + @Override + public PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource PrimaryStorageDownloadCommand: " + _gson.toJson(cmd)); + } + + try { + VmwareContext context = getServiceContext(); + VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + return (PrimaryStorageDownloadAnswer) mgr.getStorageManager().execute(this, cmd); + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String msg = "PrimaryStorageDownloadCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new PrimaryStorageDownloadAnswer(msg); + } + } + + @Override + public Answer execute(DestroyCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource DestroyCommand: " + _gson.toJson(cmd)); + } + + /* + * DestroyCommand content example + * + * {"volume": {"id":5,"name":"Volume1", "mountPoint":"/export/home/kelven/vmware-test/primary", + * "path":"6bb8762f-c34c-453c-8e03-26cc246ceec4", "size":0,"type":"DATADISK","resourceType": + * "STORAGE_POOL","storagePoolType":"NetworkFilesystem", "poolId":0,"deviceId":0 } } + * + * {"volume": {"id":1, "name":"i-2-1-KY-ROOT", "mountPoint":"/export/home/kelven/vmware-test/primary", + * "path":"i-2-1-KY-ROOT","size":0,"type":"ROOT", "resourceType":"STORAGE_POOL", "storagePoolType":"NetworkFilesystem", + * "poolId":0,"deviceId":0 } } + */ + + try { + VmwareContext context = getServiceContext(); + VmwareHypervisorHost hyperHost = getHyperHost(context); + VolumeTO vol = cmd.getVolume(); + + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, vol.getPoolUuid()); + if (morDs == null) { + String msg = "Unable to find datastore based on volume mount point " + cmd.getVolume().getMountPoint(); + s_logger.error(msg); + throw new Exception(msg); + } + DatastoreMO dsMo = new DatastoreMO(context, morDs); ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter(); @@ -3044,16 +3553,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VmwareHypervisorHost hyperHost = getHyperHost(context); DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter()); - ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, pool.getUuid()); + ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, pool.getUuid()); if (morDatastore == null) - throw new Exception("Unable to find datastore in vSphere"); - - DatastoreMO dsMo = new DatastoreMO(context, morDatastore); - - if (cmd.getDiskCharacteristics().getType() == Volume.Type.ROOT) { - if (cmd.getTemplateUrl() == null) { - // create a root volume for blank VM - String dummyVmName = getWorkerName(context, cmd, 0); + throw new Exception("Unable to find datastore in vSphere"); + + DatastoreMO dsMo = new DatastoreMO(context, morDatastore); + + if (cmd.getDiskCharacteristics().getType() == Volume.Type.ROOT) { + if (cmd.getTemplateUrl() == null) { + // create a root volume for blank VM + String dummyVmName = getWorkerName(context, cmd, 0); VirtualMachineMO vmMo = null; try { @@ -4053,23 +4562,23 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa _morHyperHost.setType(hostTokens[0]); _morHyperHost.set_value(hostTokens[1]); - VmwareContext context = getServiceContext(); - try { - VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - mgr.setupResourceStartupParams(params); - - CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager()); + VmwareContext context = getServiceContext(); + try { + VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + mgr.setupResourceStartupParams(params); + + CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager()); cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID); if (mgr.getNexusVSwitchGlobalParameter()) { cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP); - } else { + } else { cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC); - } + } cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID); cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK); - - VmwareHypervisorHost hostMo = this.getHyperHost(context); + + VmwareHypervisorHost hostMo = this.getHyperHost(context); _hostName = hostMo.getHyperHostName(); Map vsmCredentials; @@ -4083,17 +4592,17 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa _publicNetworkVSwitchName = mgr.getPublicVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); _guestNetworkVSwitchName = mgr.getGuestVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); } - - } catch (Exception e) { - s_logger.error("Unexpected Exception ", e); - } - + + } catch (Exception e) { + s_logger.error("Unexpected Exception ", e); + } + if(_privateNetworkVSwitchName == null) { _privateNetworkVSwitchName = (String) params.get("private.network.vswitch.name"); } - if(_publicNetworkVSwitchName == null) { + if(_publicNetworkVSwitchName == null) { _publicNetworkVSwitchName = (String) params.get("public.network.vswitch.name"); - } + } if(_guestNetworkVSwitchName == null) { _guestNetworkVSwitchName = (String) params.get("guest.network.vswitch.name"); } @@ -4128,42 +4637,42 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if(value != null && value.equalsIgnoreCase("true")) _nexusVSwitch = true; - s_logger.info("VmwareResource network configuration info. private vSwitch: " + _privateNetworkVSwitchName + ", public vSwitch: " + _publicNetworkVSwitchName + ", guest network: " - + _guestNetworkVSwitchName); - - return true; - } - - @Override - public String getName() { - return _name; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - private VmwareContext getServiceContext() { - return getServiceContext(null); - } - - private void invalidateServiceContext() { - invalidateServiceContext(null); - } - - private VmwareHypervisorHost getHyperHost(VmwareContext context) { - return getHyperHost(context, null); - } - - @Override - public synchronized VmwareContext getServiceContext(Command cmd) { - if (_serviceContext == null) { + s_logger.info("VmwareResource network configuration info. private vSwitch: " + _privateNetworkVSwitchName + ", public vSwitch: " + _publicNetworkVSwitchName + ", guest network: " + + _guestNetworkVSwitchName); + + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + private VmwareContext getServiceContext() { + return getServiceContext(null); + } + + private void invalidateServiceContext() { + invalidateServiceContext(null); + } + + private VmwareHypervisorHost getHyperHost(VmwareContext context) { + return getHyperHost(context, null); + } + + @Override + public synchronized VmwareContext getServiceContext(Command cmd) { + if (_serviceContext == null) { try { _serviceContext = VmwareContextFactory.create(_vCenterAddress, _username, _password); VmwareHypervisorHost hyperHost = getHyperHost(_serviceContext, cmd); @@ -4188,23 +4697,23 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if(bRefresh) firewallMo.refreshFirewall(); } - } catch (Exception e) { - s_logger.error("Unable to connect to vSphere server: " + _vCenterAddress, e); - throw new CloudRuntimeException("Unable to connect to vSphere server: " + _vCenterAddress); - } - } - return _serviceContext; - } - - @Override - public synchronized void invalidateServiceContext(VmwareContext context) { - if (_serviceContext != null) { - _serviceContext.close(); - } - _serviceContext = null; - } - - @Override + } catch (Exception e) { + s_logger.error("Unable to connect to vSphere server: " + _vCenterAddress, e); + throw new CloudRuntimeException("Unable to connect to vSphere server: " + _vCenterAddress); + } + } + return _serviceContext; + } + + @Override + public synchronized void invalidateServiceContext(VmwareContext context) { + if (_serviceContext != null) { + _serviceContext.close(); + } + _serviceContext = null; + } + + @Override public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) { if (_morHyperHost.getType().equalsIgnoreCase("HostSystem")) { return new HostMO(context, _morHyperHost);