From 0366dd093c63d386a882c6c26dbbd3b24c0adf4c Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Mon, 23 Aug 2010 18:01:39 -0700 Subject: [PATCH] use slaveconnection instead of masterconnection for all host plugin calls. tested by creating domr and user vm and migrating them 1. if you add host for kvm , you need specify kvm://ip_address, otherwiset there is no to differ kvm and xenserver hosts, edison cloud you please test this, may need some minor fixes. 2. if you want to session inside your plugin call, you can not use the one which is passed in, due to it is a slavesession, you need to call get_xapi_session() to get a new local session and use it. I have modified some of these, I may ignore some. Please let me know if you see XENAPI_PLUGIN_EXCEPTION. --- client/tomcatconf/components.xml.in | 1 + .../xen/resource/CitrixResourceBase.java | 39 ++++++++++++++++-- .../vm/hypervisor/xenserver/hostvmstats.py | 8 +--- scripts/vm/hypervisor/xenserver/vmops | 41 +++++++++++++++---- .../kvm/discoverer/KvmServerDiscoverer.java | 4 +- .../xen/discoverer/XcpServerDiscoverer.java | 37 ++++++++--------- 6 files changed, 89 insertions(+), 41 deletions(-) diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 986ac065f6d..ce698854bbe 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -149,6 +149,7 @@ + diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 24997f1110a..bdb4de079a1 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -3491,9 +3491,25 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected String callHostPlugin(String plugin, String cmd, String... params) { Map args = new HashMap(); + Session slaveSession = null; + Connection slaveConn = null; try { - Connection conn = getConnection(); - Host host = Host.getByUuid(conn, _host.uuid); + URL slaveUrl = null; + try { + slaveUrl = new URL("http://" + _host.ip); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + slaveConn = new Connection(slaveUrl, 10); + slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, _username, _password); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Slave logon successful. session= " + slaveSession); + } + Host host = Host.getByUuid(slaveConn, _host.uuid); + + for (int i = 0; i < params.length; i += 2) { args.put(params[i], params[i + 1]); } @@ -3502,7 +3518,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); } - String result = host.callPlugin(conn, plugin, cmd, args); + String result = host.callPlugin(slaveConn, plugin, cmd, args); if (s_logger.isTraceEnabled()) { s_logger.trace("callHostPlugin Result: " + result); } @@ -3511,6 +3527,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString()); } catch (XmlRpcException e) { s_logger.debug("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage()); + } finally { + if( slaveSession != null) { + try { + slaveSession.localLogout(slaveConn); + } catch (Exception e) { + } + } } return null; } @@ -3979,6 +4002,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR s_logger.debug("Can't get xs-tools.iso: " + e.toString()); } } + + protected boolean can_bridge_firewall() { + return false; + } protected boolean getHostInfo() throws IllegalArgumentException{ Connection conn = getConnection(); @@ -3998,7 +4025,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR return false; } - _canBridgeFirewall = Boolean.valueOf(callHostPlugin("vmops", "can_bridge_firewall", "host_uuid", _host.uuid)); + _canBridgeFirewall = can_bridge_firewall(); Nic privateNic = getLocalNetwork(conn, name); if (privateNic == null) { @@ -4008,6 +4035,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR s_logger.warn("Unable to determine the private network for host " + _host.ip); return false; } + _privateNetworkName = name; privateNic = getLocalNetwork(conn, name); if (privateNic == null) { s_logger.warn("Unable to get private network " + name); @@ -4026,6 +4054,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } } else { guestNic = privateNic; + _guestNetworkName = _privateNetworkName; } _host.guestNetwork = guestNic.nr.uuid; _host.guestPif = guestNic.pr.uuid; @@ -4039,6 +4068,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } } else { publicNic = guestNic; + _publicNetworkName = _guestNetworkName; } _host.publicPif = publicNic.pr.uuid; _host.publicNetwork = publicNic.nr.uuid; @@ -4061,6 +4091,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR _host.storagePif2 = storageNic2.pr.uuid; s_logger.info("Private Network is " + _privateNetworkName + " for host " + _host.ip); + s_logger.info("Guest Network is " + _guestNetworkName + " for host " + _host.ip); s_logger.info("Public Network is " + _publicNetworkName + " for host " + _host.ip); s_logger.info("Storage Network 1 is " + _storageNetworkName1 + " for host " + _host.ip); s_logger.info("Storage Network 2 is " + _storageNetworkName2 + " for host " + _host.ip); diff --git a/scripts/vm/hypervisor/xenserver/hostvmstats.py b/scripts/vm/hypervisor/xenserver/hostvmstats.py index 89af959db61..8aa3eede4f9 100644 --- a/scripts/vm/hypervisor/xenserver/hostvmstats.py +++ b/scripts/vm/hypervisor/xenserver/hostvmstats.py @@ -7,14 +7,8 @@ import time import logging logging.basicConfig(filename='/tmp/xapilog',level=logging.DEBUG) -def get_xapi_session(): - xapi = XenAPI.xapi_local(); - xapi.login_with_password("","") - return xapi._session - -def get_stats(collect_host_stats, consolidation_function, interval, start_time): +def get_stats(session, collect_host_stats, consolidation_function, interval, start_time): try: - session = get_xapi_session() if collect_host_stats == "true" : url = "http://localhost/rrd_updates?" diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 3ac93f4abd5..dfc0c1d168e 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -4,6 +4,7 @@ import os, sys, time import XenAPIPlugin +import XenAPI sys.path.append("/opt/xensource/sm/") import SR, VDI, SRCommand, util, lvutil from util import CommandException @@ -35,13 +36,20 @@ def echo(fn): return res return wrapped + +def get_xapi_session(): + xapi = XenAPI.xapi_local(); + xapi.login_with_password("","") + return xapi._session + @echo def gethostvmstats(session, args): collect_host_stats = args['collectHostStats'] consolidation_function = args['consolidationFunction'] interval = args['interval'] start_time = args['startTime'] - result = hostvmstats.get_stats(collect_host_stats, consolidation_function, interval, start_time) + session = get_xapi_session() + result = hostvmstats.get_stats(session, collect_host_stats, consolidation_function, interval, start_time) return result @echo @@ -454,7 +462,9 @@ def heartbeat(session, args): txt='fail' return txt -def get_private_nic(session, args): +def get_private_nic( args): + session = get_xapi_session() + vms = session.xenapi.VM.get_all() host_uuid = args.get('host_uuid') host = session.xenapi.host.get_by_uuid(host_uuid) piflist = session.xenapi.host.get_PIFs(host) @@ -481,7 +491,7 @@ def can_bridge_firewall(session, args): util.pread2(['iptables', '-D', 'FORWARD', '-j', 'RH-Firewall-1-INPUT']) except: util.SMlog('Chain BRIDGE-FIREWALL already exists') - privnic = get_private_nic(session, args) + privnic = get_private_nic(args) result = 'true' try: util.pread2(['/bin/bash', '-c', 'iptables -n -L FORWARD | grep BRIDGE-FIREWALL']) @@ -496,8 +506,8 @@ def can_bridge_firewall(session, args): if not os.path.exists('/var/run/cloud'): os.makedirs('/var/run/cloud') - cleanup_rules_for_dead_vms(session) - cleanup_rules(session) + cleanup_rules_for_dead_vms() + cleanup_rules() return result @@ -875,6 +885,8 @@ def get_rule_log_for_vm(session, vmName): def get_rule_logs_for_vms(session, args): host_uuid = args.pop('host_uuid') try: + session = get_xapi_session() + thishost = session.xenapi.host.get_by_uuid(host_uuid) hostrec = session.xenapi.host.get_record(thishost) vms = hostrec.get('resident_VMs') @@ -897,7 +909,9 @@ def get_rule_logs_for_vms(session, args): return ";".join(result) @echo -def cleanup_rules_for_dead_vms(session): +def cleanup_rules_for_dead_vms(): + try: + session = get_xapi_session() vms = session.xenapi.VM.get_all() cleaned = 0 for vm_name in [session.xenapi.VM.get_name_label(x) for x in vms]: @@ -913,9 +927,16 @@ def cleanup_rules_for_dead_vms(session): cleaned = cleaned+1 util.SMlog("Cleaned up rules for " + str(cleaned) + " vms") + except: + util.SMlog("Failed to cleanup rules for dead vms!") + + @echo -def cleanup_rules(session): +def cleanup_rules(): + try: + session = get_xapi_session() + chainscmd = "iptables-save | grep '^:' | awk '{print $1}' | cut -d':' -f2" chains = util.pread2(['/bin/bash', '-c', chainscmd]).split('\n') cleaned = 0 @@ -942,6 +963,8 @@ def cleanup_rules(session): destroy_network_rules_for_vm(session, {'vmName':vmname}) util.SMlog("Cleaned up rules for " + str(len(cleanup)) + " chains") + except: + util.SMlog("Failed to cleanup rules !") @echo def check_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno): @@ -1005,6 +1028,8 @@ def remove_rule_log_for_vm(vmName): @echo def network_rules(session, args): + try: + session = get_xapi_session() vm_name = args.get('vmName') vmName = vm_name vm_ip = args.get('vmIP') @@ -1101,6 +1126,8 @@ def network_rules(session, args): return 'false' return 'true' + except: + util.SMlog("Failed to network rule !") diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java index 19c1aea8bee..2f043069012 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java @@ -99,8 +99,8 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, String password) throws DiscoveryException { Map> resources = new HashMap>(); Map details = new HashMap(); - if (!uri.getScheme().equals("http")) { - String msg = "urlString is not http so we're not taking care of the discovery for this: " + uri; + if (!uri.getScheme().equals("kvm")) { + String msg = "urlString is not kvm so we're not taking care of the discovery for this: " + uri; s_logger.debug(msg); return null; } diff --git a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index e7017710f9e..cc1fb72b343 100644 --- a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -53,6 +53,7 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.xen.resource.CitrixResourceBase; import com.cloud.hypervisor.xen.resource.XcpServerResource; import com.cloud.hypervisor.xen.resource.XenServerConnectionPool; +import com.cloud.hypervisor.xen.resource.XenServerResource; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; import com.cloud.resource.ServerResource; @@ -170,15 +171,10 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L if (_hostDao.findByGuid(record.uuid) != null) { s_logger.debug("Skipping " + record.address + " because " + record.uuid + " is already in the database."); continue; - } - - - if (!checkServer(conn, dcId, podId, host, record)) { - continue; - } - + } + + CitrixResourceBase resource = createServerResource(dcId, podId, record); s_logger.info("Found host " + record.hostname + " ip=" + record.address + " product version=" + prodVersion); - CitrixResourceBase resource = createServerResource(record); Map details = new HashMap(); Map params = new HashMap(); @@ -379,22 +375,21 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L return true; } - - protected boolean checkServer(Connection conn, long dcId, Long podId, Host host, Host.Record record) { + + protected CitrixResourceBase createServerResource(long dcId, Long podId, Host.Record record) { String prodBrand = record.softwareVersion.get("product_brand").trim(); String prodVersion = record.softwareVersion.get("product_version").trim(); - if(!prodBrand.equals("XenCloudPlatform") || !prodVersion.equals("0.1.1")) { - String msg = "Only support XCP 0.1.1, but this one is " + prodBrand + " " + prodVersion; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, msg, msg); - s_logger.debug(msg); - throw new RuntimeException(msg); - } - return true; - } - - protected CitrixResourceBase createServerResource(Host.Record record) { - return new XcpServerResource(); + if(prodBrand.equals("XenCloudPlatform") && prodVersion.equals("0.1.1")) + return new XcpServerResource(); + + if(prodBrand.equals("XenServer") && prodVersion.equals("5.6.0")) + return new XenServerResource(); + + String msg = "Only support XCP 0.1.1 and Xerver 5.6.0, but this one is " + prodBrand + " " + prodVersion; + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, msg, msg); + s_logger.debug(msg); + throw new RuntimeException(msg); } protected void serverConfig() {