diff --git a/.gitignore b/.gitignore index d7723b24bc6..01478d2c9b5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ cloud-*.tar.bz2 *.log *.pyc build.number +cloud.log.*.* diff --git a/core/src/com/cloud/dc/dao/VlanDao.java b/core/src/com/cloud/dc/dao/VlanDao.java index b70df875ed9..f96ff50d859 100644 --- a/core/src/com/cloud/dc/dao/VlanDao.java +++ b/core/src/com/cloud/dc/dao/VlanDao.java @@ -48,4 +48,8 @@ public interface VlanDao extends GenericDao { boolean zoneHasDirectAttachUntaggedVlans(long zoneId); + List listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId); + + List searchForZoneWideVlans(long dcId, String vlanType,String vlanId); + } diff --git a/core/src/com/cloud/dc/dao/VlanDaoImpl.java b/core/src/com/cloud/dc/dao/VlanDaoImpl.java index 76e78b7b6f7..d98e04edc21 100644 --- a/core/src/com/cloud/dc/dao/VlanDaoImpl.java +++ b/core/src/com/cloud/dc/dao/VlanDaoImpl.java @@ -18,6 +18,9 @@ package com.cloud.dc.dao; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -33,19 +36,24 @@ import com.cloud.dc.Vlan.VlanType; import com.cloud.network.dao.IPAddressDao; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; @Local(value={VlanDao.class}) public class VlanDaoImpl extends GenericDaoBase implements VlanDao { + private final String FindZoneWideVlans = "SELECT * FROM vlan WHERE data_center_id=? and vlan_type=? and vlan_id!=? and id not in (select vlan_db_id from account_vlan_map)"; + protected SearchBuilder ZoneVlanIdSearch; protected SearchBuilder ZoneSearch; protected SearchBuilder ZoneTypeSearch; protected SearchBuilder ZoneTypeAllPodsSearch; protected SearchBuilder ZoneTypePodSearch; - + protected SearchBuilder ZoneVlanSearch; protected PodVlanMapDaoImpl _podVlanMapDao = new PodVlanMapDaoImpl(); protected AccountVlanMapDao _accountVlanMapDao = new AccountVlanMapDaoImpl(); @@ -80,8 +88,18 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao ZoneTypeSearch.and("zoneId", ZoneTypeSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); ZoneTypeSearch.and("vlanType", ZoneTypeSearch.entity().getVlanType(), SearchCriteria.Op.EQ); ZoneTypeSearch.done(); + } + @Override + public List listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId){ + SearchCriteria sc = ZoneVlanSearch.create(); + sc.setParameters("zoneId", zoneId); + sc.setParameters("vlanId", vlanId); + sc.setParameters("vlanType", vlanType); + return listBy(sc); + } + @Override public List listByZoneAndType(long zoneId, VlanType vlanType) { SearchCriteria sc = ZoneTypeSearch.create(); @@ -254,5 +272,33 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao return new Pair(ipAddress, vlan); } + + @Override + @DB + public List searchForZoneWideVlans(long dcId, String vlanType, String vlanId){ + + StringBuilder sql = new StringBuilder(FindZoneWideVlans); + + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(sql.toString()); + pstmt.setLong(1, dcId); + pstmt.setString(2, vlanType); + pstmt.setString(3, vlanId); + + ResultSet rs = pstmt.executeQuery(); + List zoneWideVlans = new ArrayList(); + + while (rs.next()) { + zoneWideVlans.add(toEntityBean(rs, false)); + } + + return zoneWideVlans; + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); + } + + } } diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index c83ee3f189d..2eeddb267dd 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -153,7 +153,6 @@ import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor; import com.cloud.network.Network.BroadcastDomainType; import com.cloud.network.Network.TrafficType; -import com.cloud.hypervisor.xen.resource.XenServerConnectionPool.XenServerConnection; import com.cloud.resource.ServerResource; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; @@ -282,7 +281,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR s_logger.debug("Logging out of " + _host.uuid); if (_host.pool != null) { _connPool.disconnect(_host.uuid, _host.pool); - _host.pool = null; } } @@ -446,15 +444,26 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } protected boolean pingxenserver() { - String status; - status = callHostPlugin("vmops", "pingxenserver"); - - if (status == null || status.isEmpty()) { + Session slaveSession = null; + Connection slaveConn = null; + try { + URL slaveUrl = null; + slaveUrl = new URL("http://" + _host.ip); + slaveConn = new Connection(slaveUrl, 100); + slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, _username, _password); + return true; + } catch (Exception e) { return false; + } finally { + if( slaveSession != null ){ + try{ + Session.localLogout(slaveConn); + } catch (Exception e) { + + } + slaveConn.dispose(); + } } - - return true; - } protected String logX(XenAPIObject obj, String msg) { @@ -2536,42 +2545,45 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR - public boolean joinPool(String address, String username, String password) { - Connection conn = getConnection(); + public boolean joinPool(String masterIp, String username, String password) { + Connection slaveConn = null; Connection poolConn = null; + Session slaveSession = null; + URL slaveUrl = null; + try { - // set the _host.poolUuid to the old pool uuid in case it's not set. - _host.pool = getPoolUuid(); // Connect and find out about the new connection to the new pool. - poolConn = _connPool.connect(address, username, password, _wait); - Map pools = Pool.getAllRecords(poolConn); - Pool.Record pr = pools.values().iterator().next(); - - // Now join it. - String masterAddr = pr.master.getAddress(poolConn); - Pool.join(conn, masterAddr, username, password); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Joined the pool at " + masterAddr); + poolConn = _connPool.masterConnect(masterIp, username, password); + //check if this host is already in pool + Set hosts = Host.getAll(poolConn); + for( Host host : hosts ) { + if(host.getAddress(poolConn).equals(_host.ip)) { + return true; + } } - disconnected(); // Logout of our own session. + + slaveUrl = new URL("http://" + _host.ip); + slaveConn = new Connection(slaveUrl, 100); + slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, _username, _password); + + // Now join it. + + Pool.join(slaveConn, masterIp, username, password); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Joined the pool at " + masterIp); + } + try { // slave will restart xapi in 10 sec Thread.sleep(10000); } catch (InterruptedException e) { } - // Set the pool uuid now to the newest pool. - _host.pool = pr.uuid; - URL url; - try { - url = new URL("http://" + _host.ip); - } catch (MalformedURLException e1) { - throw new CloudRuntimeException("Problem with url " + _host.ip); - } - Connection c = null; + // check if the master of this host is set correctly. + Connection c = new Connection(slaveUrl, 100); for (int i = 0; i < 15; i++) { - c = new Connection(url, _wait); + try { Session.loginWithPassword(c, _username, _password, APIVersion.latest().toString()); s_logger.debug("Still waiting for the conversion to the master"); @@ -2597,18 +2609,33 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } catch (InterruptedException e) { } } + return true; + } catch (MalformedURLException e) { + throw new CloudRuntimeException("Problem with url " + _host.ip); } catch (XenAPIException e) { - String msg = "Unable to allow host " + _host.uuid + " to join pool " + address + " due to " + e.toString(); + String msg = "Unable to allow host " + _host.uuid + + " to join pool " + masterIp + " due to " + e.toString(); s_logger.warn(msg, e); throw new RuntimeException(msg); } catch (XmlRpcException e) { - String msg = "Unable to allow host " + _host.uuid + " to join pool " + address + " due to " + e.getMessage(); + String msg = "Unable to allow host " + _host.uuid + + " to join pool " + masterIp + " due to " + e.getMessage(); s_logger.warn(msg, e); throw new RuntimeException(msg); } finally { if (poolConn != null) { - XenServerConnectionPool.logout(poolConn); + try { + Session.logout(poolConn); + } catch (Exception e) { + } + poolConn.dispose(); + } + if(slaveSession != null) { + try { + Session.localLogout(slaveConn); + } catch (Exception e) { + } } } } @@ -3414,6 +3441,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR return false; return true; } + protected String callHostPlugin(String plugin, String cmd, String... params) { //default time out is 300 s return callHostPluginWithTimeOut(plugin, cmd, 300, params); @@ -3421,23 +3449,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected String callHostPluginWithTimeOut(String plugin, String cmd, int timeout, String... params) { Map args = new HashMap(); - Session slaveSession = null; - Connection slaveConn = null; - try { - URL slaveUrl = null; - try { - slaveUrl = new URL("http://" + _host.ip); - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - slaveConn = new Connection(slaveUrl, timeout); - 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); + try { + Connection conn = getConnection(); + for (int i = 0; i < params.length; i += 2) { args.put(params[i], params[i + 1]); } @@ -3445,8 +3460,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR if (s_logger.isTraceEnabled()) { s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); } - - String result = host.callPlugin(slaveConn, plugin, cmd, args); + if( _host.host == null ) { + _host.host = Host.getByUuid(conn, _host.uuid); + } + String result = _host.host.callPlugin(conn, plugin, cmd, args); if (s_logger.isTraceEnabled()) { s_logger.trace("callHostPlugin Result: " + result); } @@ -3455,13 +3472,6 @@ 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 { - Session.localLogout(slaveConn); - } catch (Exception e) { - } - } } return null; } @@ -3941,7 +3951,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR try { Host myself = Host.getByUuid(conn, _host.uuid); - _host.pool = getPoolUuid(); boolean findsystemvmiso = false; Set srs = SR.getByNameLabel(conn, "XenServer Tools"); @@ -4198,9 +4207,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR cmd.setCluster(_cluster); StartupStorageCommand sscmd = initializeLocalSR(); - - _host.pool = getPoolUuid(); - if (sscmd != null) { /* report pv driver iso */ getPVISO(sscmd); @@ -4503,7 +4509,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } public Connection getConnection() { - return _connPool.connect(_host.uuid, _host.ip, _username, _password, _wait); + return _connPool.connect(_host.uuid, _host.pool, _host.ip, _username, _password, _wait); } protected void fillHostInfo(StartupRoutingCommand cmd) { @@ -4635,8 +4641,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } catch (NumberFormatException e) { throw new ConfigurationException("Unable to get the zone " + params.get("zone")); } + _host.host = null; _name = _host.uuid; _host.ip = (String) params.get("url"); + _host.pool = (String) params.get("pool"); _username = (String) params.get("username"); _password = (String) params.get("password"); _pod = (String) params.get("pod"); @@ -4681,8 +4689,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR throw new ConfigurationException("Unable to get the uuid"); } - params.put("domr.scripts.dir", "scripts/network/domr"); - String patchPath = getPatchPath(); _patchPath = Script.findScript(patchPath, "patch"); @@ -6405,6 +6411,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR public String systemvmisouuid; public String uuid; public String ip; + public Host host; public String publicNetwork; public String privateNetwork; public String linkLocalNetwork; diff --git a/core/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java b/core/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java index 4dfb57dcca8..d975825c64a 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java +++ b/core/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java @@ -22,7 +22,6 @@ import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.URL; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -39,105 +38,144 @@ import com.xensource.xenapi.Types; import com.xensource.xenapi.Types.XenAPIException; public class XenServerConnectionPool { - private static final Logger s_logger = Logger.getLogger(XenServerConnectionPool.class); - - protected HashMap _conns = new HashMap(); - protected HashMap _infos = new HashMap(); - + private static final Logger s_logger = Logger + .getLogger(XenServerConnectionPool.class); + + protected HashMap _conns = new HashMap(); + protected HashMap _infos = new HashMap(); + protected int _retries; protected int _interval; - + protected XenServerConnectionPool() { - _retries = 10; + _retries = 3; _interval = 3; } - - public synchronized void switchMaster(String lipaddr, String poolUuid, Connection conn, Host host, String username, String password, int wait) throws XmlRpcException, XenAPIException { - String ipaddr = host.getAddress(conn); + + void forceSleep(long sec) { + long firetime = System.currentTimeMillis() + (sec * 1000); + long msec = sec * 1000; + while (true) { + if (msec < 100) + break; + try { + Thread.sleep(msec); + return; + } catch (InterruptedException e) { + msec = firetime - System.currentTimeMillis(); + } + } + } + + public synchronized void switchMaster(String slaveIp, String poolUuid, + Connection conn, Host host, String username, String password, + int wait) throws XmlRpcException, XenAPIException { + String masterIp = host.getAddress(conn); PoolSyncDB(conn); - s_logger.debug("Designating the new master to " + ipaddr); + s_logger.debug("Designating the new master to " + masterIp); Pool.designateNewMaster(conn, host); - XenServerConnection slaveConn = null; - XenServerConnection masterConn = null; + Connection slaveConn = null; + Connection masterConn = null; int retry = 30; for (int i = 0; i < retry; i++) { - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - } + forceSleep(5); try { if (s_logger.isDebugEnabled()) { - s_logger.debug("Logging on as the slave to " + lipaddr); + s_logger.debug("Logging on as the slave to " + slaveIp); } slaveConn = null; masterConn = null; URL slaveUrl = null; URL masterUrl = null; Session slaveSession = null; - - slaveUrl = new URL("http://" + lipaddr); - slaveConn = new XenServerConnection(slaveUrl, username, password, _retries, _interval, 10); - slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, username, password); + + slaveUrl = new URL("http://" + slaveIp); + slaveConn = new Connection(slaveUrl, 100); + slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, + username, password); if (s_logger.isDebugEnabled()) { - s_logger.debug("Slave logon successful. session= " + slaveSession); + s_logger.debug("Slave logon successful. session= " + + slaveSession); } - + Pool.Record pr = getPoolRecord(slaveConn); Host master = pr.master; String ma = master.getAddress(slaveConn); - if( !ma.trim().equals(ipaddr.trim()) ) { + if (!ma.trim().equals(masterIp.trim())) { continue; } Session.localLogout(slaveConn); - - masterUrl = new URL("http://" + ipaddr); - masterConn = new XenServerConnection(masterUrl, username, password, _retries, _interval, wait); - Session.loginWithPassword(masterConn, username, - password, - APIVersion.latest().toString()); + slaveConn = null; + s_logger.debug("Logging on as the master to " + masterIp); + masterUrl = new URL("http://" + masterIp); + masterConn = new Connection(masterUrl, 100); + Session.loginWithPassword(masterConn, username, password, + APIVersion.latest().toString()); cleanup(poolUuid); - Pool.recoverSlaves(masterConn); + ensurePoolIntegrity(masterConn, masterIp, username, password, + wait); PoolSyncDB(masterConn); return; } catch (Types.HostIsSlave e) { - s_logger.debug("HostIsSlaveException: Still waiting for the conversion to the master"); + s_logger + .debug("HostIsSlaveException: Still waiting for the conversion to the master"); } catch (XmlRpcException e) { - s_logger.debug("XmlRpcException: Still waiting for the conversion to the master " + e.getMessage()); + s_logger + .debug("XmlRpcException: Still waiting for the conversion to the master " + + e.getMessage()); } catch (Exception e) { - s_logger.debug("Exception: Still waiting for the conversion to the master" + e.getMessage()); + s_logger + .debug("Exception: Still waiting for the conversion to the master" + + e.getMessage()); } finally { - if (masterConn != null) { - try { - Session.logout(masterConn); - } catch (Exception e) { - s_logger.debug("Unable to log out of session: " + e.getMessage()); - } - masterConn.dispose(); - masterConn = null; - } + if (masterConn != null) { + try { + Session.logout(masterConn); + } catch (Exception e) { + s_logger.debug("Unable to log out of session: " + + e.getMessage()); + } + masterConn.dispose(); + masterConn = null; + } + if (slaveConn != null) { + try { + Session.localLogout(slaveConn); + } catch (Exception e) { + s_logger.debug("Unable to log out of session: " + + e.getMessage()); + } + slaveConn.dispose(); + slaveConn = null; + } + } } - - throw new CloudRuntimeException("Unable to logon to the new master after " + retry + " retries"); + + throw new CloudRuntimeException( + "Unable to logon to the new master after " + retry + " retries"); } - + protected synchronized void cleanup(String poolUuid) { ConnectionInfo info = _infos.remove(poolUuid); if (info == null) { - s_logger.debug("Unable to find any information for pool " + poolUuid); + s_logger.debug("Unable to find any information for pool " + + poolUuid); return; } - + + s_logger.debug("Cleaning up session for pool " + poolUuid); for (Member member : info.refs.values()) { + s_logger.debug("remove connection for host " + member.uuid); _conns.remove(member.uuid); } - + if (info.conn != null) { try { - s_logger.debug("Logging out of session " + info.conn.getSessionReference()); - + s_logger.debug("Logging out of session " + + info.conn.getSessionReference()); Session.logout(info.conn); } catch (XenAPIException e) { s_logger.debug("Unable to logout of the session"); @@ -148,58 +186,52 @@ public class XenServerConnectionPool { } s_logger.debug("Session is cleaned up"); } - + protected synchronized void cleanup(String poolUuid, ConnectionInfo info) { ConnectionInfo info2 = _infos.get(poolUuid); + s_logger + .debug("Cleanup for Session " + info.conn.getSessionReference()); if (info != info2) { - s_logger.debug("Session " + info.conn.getSessionReference() + " is already logged out."); + s_logger.debug("Session " + info.conn.getSessionReference() + + " is already logged out."); return; } - + cleanup(poolUuid); } - + public synchronized void disconnect(String uuid, String poolUuid) { Connection conn = _conns.remove(uuid); if (conn == null) { return; } - + if (s_logger.isDebugEnabled()) { - s_logger.debug("Logging out of " + conn.getSessionReference() + " for host " + uuid); + s_logger.debug("Logging out of " + conn.getSessionReference() + + " for host " + uuid); } - - conn.dispose(); - + ConnectionInfo info = _infos.get(poolUuid); if (info == null) { return; } - + if (s_logger.isDebugEnabled()) { - s_logger.debug("Connection for pool " + poolUuid + " found. session=" + info.conn.getSessionReference()); + s_logger.debug("Connection for pool " + poolUuid + + " found. session=" + info.conn.getSessionReference()); } + + Member member = info.refs.remove(uuid); - info.refs.remove(uuid); - if (info.refs.size() == 0) { - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Logging out of the session " + info.conn.getSessionReference()); - } - _infos.remove(poolUuid); - try { - Session.logout(info.conn); - info.conn.dispose(); - } catch (Exception e) { - s_logger.debug("Logout has a problem " + e.getMessage()); - } - info.conn = null; + if (info.refs.size() == 0 || ( member != null && member.ipAddr.equals(info.masterIp) )) { + cleanup(poolUuid); } } - + public static void logout(Connection conn) { try { - s_logger.debug("Logging out of the session " + conn.getSessionReference()); + s_logger.debug("Logging out of the session " + + conn.getSessionReference()); Session.logout(conn); } catch (Exception e) { s_logger.debug("Logout has problem " + e.getMessage()); @@ -207,319 +239,467 @@ public class XenServerConnectionPool { conn.dispose(); } } - - public Connection connect(String urlString, String username, String password, int wait) { - return connect(null, urlString, username, password, wait); + + public Connection masterConnect(String ip, String username, String password) { + Connection slaveConn = null; + Connection masterConn = null; + try{ + URL slaveUrl = new URL("http://" + ip); + slaveConn = new Connection(slaveUrl, 100); + Session.slaveLocalLoginWithPassword(slaveConn, username, password); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Slave logon to " + ip); + } + String masterIp = null; + try { + Pool.Record pr = getPoolRecord(slaveConn); + Host master = pr.master; + masterIp = master.getAddress(slaveConn); + + s_logger.debug("Logging on as the master to " + masterIp); + URL masterUrl = new URL("http://" + masterIp); + masterConn = new Connection(masterUrl, 100); + Session.loginWithPassword(masterConn, username, password, + APIVersion.latest().toString()); + return masterConn; + } catch (Exception e) { + s_logger.debug("Failed to log on as master to "); + if( masterConn != null ) { + try { + Session.logout(masterConn); + } catch (Exception e1) { + } + masterConn.dispose(); + masterConn = null; + } + } + }catch ( Exception e){ + s_logger.debug("Failed to slave local login to " + ip); + } finally { + if( slaveConn != null ) { + try { + Session.localLogout(slaveConn); + } catch (Exception e1) { + } + slaveConn.dispose(); + slaveConn = null; + } + + } + return null; } + public Connection slaveConnect(String ip, String username, String password) { + Connection conn = null; + try{ + URL url = new URL("http://" + ip); + conn = new Connection(url, 100); + Session.slaveLocalLoginWithPassword(conn, username, password); + return conn; + }catch ( Exception e){ + s_logger.debug("Failed to slave local login to " + ip); + } + return null; + } + protected ConnectionInfo getConnectionInfo(String poolUuid) { - synchronized(_infos) { + synchronized (_infos) { return _infos.get(poolUuid); } } - + protected XenServerConnection getConnection(String hostUuid) { - synchronized(_conns) { + synchronized (_conns) { return _conns.get(hostUuid); } } - + static void PoolSyncDB(Connection conn) { - try{ + try { Set hosts = Host.getAll(conn); - for(Host host : hosts) { + for (Host host : hosts) { try { host.enable(conn); } catch (Exception e) { } } } catch (Exception e) { - s_logger.debug("Enbale host failed due to " + e.getMessage() + e.toString()); + s_logger.debug("Enbale host failed due to " + e.getMessage() + + e.toString()); } - try{ + try { Pool.syncDatabase(conn); } catch (Exception e) { - s_logger.debug("Sync Database failed due to " + e.getMessage() + e.toString()); + s_logger.debug("Sync Database failed due to " + e.getMessage() + + e.toString()); } - - } - - protected synchronized URL ensurePoolIntegrity(Connection conn, Host master, Pool.Record poolr, String ipAddress, String username, String password, int wait) throws XenAPIException, XmlRpcException { - if (!ipAddress.equals(master.getAddress(conn))) { - return null; // Doesn't think it is the master anyways. - } - - String poolUuid = poolr.uuid; - ConnectionInfo info = _infos.get(poolUuid); - if (info != null) { - Connection poolConn = info.conn; - if (poolConn != null) { - Pool.recoverSlaves(poolConn); - PoolSyncDB(poolConn); - return info.masterUrl; + + void PoolEmergencyTransitionToMaster(String slaveIp, String username, String password) { + Connection slaveConn = null; + Connection c = null; + try{ + s_logger.debug("Trying to transition master to " + slaveIp); + URL slaveUrl = new URL("http://" + slaveIp); + slaveConn = new Connection(slaveUrl, 100); + Session.slaveLocalLoginWithPassword(slaveConn, username, password); + Pool.emergencyTransitionToMaster(slaveConn); + try { + Session.localLogout(slaveConn); + slaveConn = null; + } catch (Exception e) { + } + // restart xapi in 10 sec + forceSleep(10); + // check if the master of this host is set correctly. + c = new Connection(slaveUrl, 100); + for (int i = 0; i < 30; i++) { + try { + Session.loginWithPassword(c, username, password, APIVersion.latest().toString()); + s_logger.debug("Succeeded to transition master to " + slaveIp); + return; + } catch (Types.HostIsSlave e) { + s_logger.debug("HostIsSlave: Still waiting for the conversion to the master " + slaveIp); + } catch (Exception e) { + s_logger.debug("Exception: Still waiting for the conversion to the master"); + } + forceSleep(2); + } + throw new RuntimeException("EmergencyTransitionToMaster failed after retry 30 times"); + } catch (Exception e) { + throw new RuntimeException("EmergencyTransitionToMaster failed due to " + e.getMessage()); + } finally { + if(slaveConn != null) { + try { + Session.localLogout(slaveConn); + } catch (Exception e) { + } + } + if(c != null) { + try { + Session.logout(c); + c.dispose(); + } catch (Exception e) { + } } } + + } + void PoolEmergencyResetMaster(String slaveIp, String masterIp, + String username, String password) { + Connection slaveConn = null; + try { + s_logger.debug("Trying to reset master of slave " + slaveIp + + " to " + masterIp); + URL slaveUrl = new URL("http://" + slaveIp); + slaveConn = new Connection(slaveUrl, 10); + Session.slaveLocalLoginWithPassword(slaveConn, username, password); + Pool.emergencyResetMaster(slaveConn, masterIp); + if (slaveConn != null) { + try { + Session.localLogout(slaveConn); + } catch (Exception e) { + } + } + forceSleep(10); + for (int i = 0; i < 30; i++) { + try { + Session.slaveLocalLoginWithPassword(slaveConn, username, password); + Pool.Record pr = getPoolRecord(slaveConn); + String mIp = pr.master.getAddress(slaveConn); + if (mIp.trim().equals(masterIp.trim())) { + return; + } + } catch (Exception e) { + } + if (slaveConn != null) { + try { + Session.localLogout(slaveConn); + } catch (Exception e) { + } + } + // wait 2 second + forceSleep(2); + } + } catch (Exception e) { + + } finally { + if (slaveConn != null) { + try { + Session.localLogout(slaveConn); + slaveConn = null; + } catch (Exception e) { + } + } + } + } + + protected synchronized void ensurePoolIntegrity(Connection conn, + String masterIp, String username, String password, int wait) + throws XenAPIException, XmlRpcException { + try { + // try recoverSlave first + Set slaves = Pool.recoverSlaves(conn); + // wait 10 second + forceSleep(10); + for(Host slave : slaves ) { + for (int i = 0; i < 30; i++) { + Connection slaveConn = null; + try { + + String slaveIp = slave.getAddress(conn); + s_logger.debug("Logging on as the slave to " + slaveIp); + URL slaveUrl = new URL("http://" + slaveIp); + slaveConn = new Connection(slaveUrl, 10); + Session.slaveLocalLoginWithPassword(slaveConn, username, password); + Pool.Record pr = getPoolRecord(slaveConn); + String mIp = pr.master.getAddress(slaveConn); + if (mIp.trim().equals(masterIp.trim())) { + break; + } + } catch (Exception e) { + try { + Session.localLogout(slaveConn); + } catch (Exception e1) { + } + slaveConn.dispose(); + } + // wait 2 second + forceSleep(2); + } + + } + } catch (Exception e) { + } + + // then try emergency reset master Set slaves = Host.getAll(conn); - HashMap count = new HashMap(slaves.size()); for (Host slave : slaves) { - String slaveAddress = slave.getAddress(conn); + String slaveIp = slave.getAddress(conn); Connection slaveConn = null; try { - slaveConn = new Connection(new URL("http://" + slaveAddress), wait); + s_logger.debug("Logging on as the slave to " + slaveIp); + URL slaveUrl = new URL("http://" + slaveIp); + slaveConn = new Connection(slaveUrl, 10); + Session.slaveLocalLoginWithPassword(slaveConn, username, + password); + Pool.Record slavePoolr = getPoolRecord(slaveConn); + String ip = slavePoolr.master.getAddress(slaveConn); + if (!masterIp.trim().equals(ip.trim())) { + PoolEmergencyResetMaster(slaveIp, masterIp, username, + password); + } + } catch (MalformedURLException e) { + throw new CloudRuntimeException("Bad URL" + slaveIp, e); + } catch (Exception e) { + s_logger.debug("Unable to login to slave " + slaveIp + + " error " + e.getMessage()); + } finally { if (slaveConn != null) { - Session.slaveLocalLoginWithPassword(slaveConn, username, password); - Pool.Record slavePoolr = getPoolRecord(slaveConn); - String possibleMaster = slavePoolr.master.getAddress(slaveConn); - Integer c = count.get(possibleMaster); - if (c == null) { - c = 1; - } else { - c++; - } - count.put(possibleMaster, c); try { - Session.logout(slaveConn); + Session.localLogout(slaveConn); } catch (Exception e) { - s_logger.debug("client session logout: " + e.getMessage()); } slaveConn.dispose(); } - } catch (MalformedURLException e) { - throw new CloudRuntimeException("Bad URL" + slaveAddress, e); - } catch (Exception e) { - s_logger.debug("Unable to login to slave " + slaveAddress + " error " + e.getMessage()); - } finally { - if (slaveConn != null) { - slaveConn.dispose(); - } } } - - Iterator> it = count.entrySet().iterator(); - - Map.Entry newMaster = it.next(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - - if (newMaster.getValue() < entry.getValue()) { - newMaster = entry; - } - } - - String newMasterAddress = newMaster.getKey(); - if (count.size() > 1 && !ipAddress.equals(newMasterAddress)) { - s_logger.debug("Asking the correct master to recover the slaves: " + newMasterAddress); - - URL newMasterUrl = null; - try { - newMasterUrl = new URL("http://" + newMasterAddress); - } catch (MalformedURLException e) { - throw new CloudRuntimeException("Unable to get url from " + newMasterAddress, e); - } - - Connection newMasterConn = new Connection(newMasterUrl, wait); - try { - Session.loginWithPassword(newMasterConn, username, password, APIVersion.latest().toString()); - Pool.recoverSlaves(newMasterConn); - PoolSyncDB(newMasterConn); - } catch (Exception e) { - throw new CloudRuntimeException("Unable to login to the real master at " + newMaster.getKey()); - } finally { - try { - Session.logout(newMasterConn); - } catch (Exception e) { - s_logger.debug("Unable to logout of the session: " + e.getMessage()); - } - newMasterConn.dispose(); - } - - return newMasterUrl; - } - - return null; } - - public synchronized Connection connect(String hostUuid, String ipAddress, String username, String password, int wait) { + + public synchronized Connection connect(String hostUuid, String poolUuid, String ipAddress, + String username, String password, int wait) { + XenServerConnection masterConn = null; - if (hostUuid != null) { // Let's see if it is an existing connection. - masterConn = _conns.get(hostUuid); - if (masterConn != null) { - return masterConn; - } - } - - XenServerConnection slaveConn = null; + Connection slaveConn = null; URL slaveUrl = null; URL masterUrl = null; - Session slaveSession = null; - Session masterSession = null; - + String masterIp = null; + ConnectionInfo info = null; + if(hostUuid == null || poolUuid == null || ipAddress == null || username == null || password == null ) { + String msg = "Connect some parameter are null hostUuid:" + hostUuid + " ,poolUuid:" + + poolUuid + " ,ipAddress:" + ipAddress; + s_logger.debug(msg); + throw new CloudRuntimeException(msg); + } + // Let's see if it is an existing connection. + masterConn = _conns.get(hostUuid); + if (masterConn != null){ + try{ + Host.getByUuid(masterConn, hostUuid); + return masterConn; + } catch (Exception e) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Master Session " + masterConn.getSessionReference() + " is broken due to " + e.getMessage()); + } + cleanup(masterConn.get_poolUuid()); + masterConn = null; + } + } if (s_logger.isDebugEnabled()) { s_logger.debug("Creating connection to " + ipAddress); } - - // Well, it's not already in the existing connection list. - // Let's login and see what this connection should be. - // You might think this is slow. Why not cache the pool uuid - // you say? Well, this doesn't happen very often. + try { if (s_logger.isDebugEnabled()) { s_logger.debug("Logging on as the slave to " + ipAddress); } slaveUrl = new URL("http://" + ipAddress); - slaveConn = new XenServerConnection(slaveUrl, username, password, _retries, _interval, 10); - slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, username, password); + slaveConn = new Connection(slaveUrl, 100); + Session.slaveLocalLoginWithPassword(slaveConn, + username, password); if (s_logger.isDebugEnabled()) { - s_logger.debug("Slave logon successful. session= " + slaveSession); + s_logger.debug("Slave logon successful to " + ipAddress); } - - try { - Pool.Record pr = getPoolRecord(slaveConn); - Host master = pr.master; - String ma = master.getAddress(slaveConn); - masterUrl = new URL("http://" + ma); - s_logger.debug("Logging on as the master to " + ma); - masterConn = new XenServerConnection(masterUrl, username, password, _retries, _interval, wait); - masterSession = Session.loginWithPassword(masterConn, username, password, APIVersion.latest().toString()); - - URL realMasterUrl = ensurePoolIntegrity(masterConn, master, pr, ipAddress, username, password, wait); - if (realMasterUrl != null) { - s_logger.debug("The real master url is at " + realMasterUrl); - masterUrl = realMasterUrl; - masterConn.dispose(); - masterConn = new XenServerConnection(masterUrl, username, password, _retries, _interval, wait); - masterSession = Session.loginWithPassword(masterConn, username, password, APIVersion.latest().toString()); - - } - } catch (XmlRpcException e) { - Throwable c = e.getCause(); - if (c == null || (!(c instanceof SocketException) && !(c instanceof SocketTimeoutException))) { - s_logger.warn("Unable to connect to " + masterUrl, e); - throw e; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to connect to the " + masterUrl + ". Attempting switch to master"); - } - Pool.emergencyTransitionToMaster(slaveConn); - Pool.recoverSlaves(slaveConn); - - s_logger.info("Successfully converted to the master: " + ipAddress); - - masterUrl = slaveUrl; - masterConn = new XenServerConnection(masterUrl, username, password, _retries, _interval, wait); - masterSession = Session.loginWithPassword(masterConn, username, password, APIVersion.latest().toString()); - } - - if (slaveSession != null) { - s_logger.debug("Login to the master is successful. Signing out of the slave connection: " + slaveSession); - try { - Session.localLogout(slaveConn); - } catch (Exception e) { - s_logger.debug("Unable to logout of slave session " + slaveSession); - } - slaveConn.dispose(); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully logged on to the master. Session=" + masterConn.getSessionReference()); - } - if (hostUuid == null) { - s_logger.debug("Returning now. Client is responsible for logging out of " + masterConn.getSessionReference()); - return masterConn; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Logon is successfully. Let's see if we have other hosts logged onto the same master at " + masterUrl); - } - - Pool.Record poolr = getPoolRecord(masterConn); - String poolUuid = poolr.uuid; - - ConnectionInfo info = null; info = _infos.get(poolUuid); - if (info != null && info.conn != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("The pool already has a master connection. Session=" + info.conn.getSessionReference()); - } + boolean create_new_session = true; + if (info != null) { try { - s_logger.debug("Logging out of our own session: " + masterConn.getSessionReference()); - Session.logout(masterConn); - masterConn.dispose(); + masterConn = info.conn; + Host.getByUuid(masterConn, hostUuid); + ensurePoolIntegrity(masterConn, info.masterIp, username, + password, wait); + masterIp = info.masterIp; + create_new_session = false; } catch (Exception e) { - s_logger.debug("Caught Exception while logging on but pushing on...." + e.getMessage()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to connect to master " + info.masterIp); + } + + cleanup(poolUuid); + masterConn = null; + masterIp = null; } - masterConn = new XenServerConnection(info.conn); - } else { + } + if (create_new_session) { + try{ + cleanup(poolUuid); + s_logger.info("Attempting switch master to " + ipAddress); + + PoolEmergencyTransitionToMaster(ipAddress, username, password); + + s_logger.info("Successfully converted to master: " + ipAddress); + + s_logger.info("Loginning on as master to " + ipAddress); + masterUrl = slaveUrl; + masterConn = new XenServerConnection(masterUrl, username, + password, _retries, _interval, wait); + Session.loginWithPassword(masterConn, username, password, + APIVersion.latest().toString()); + s_logger.info("Logined on as master to " + ipAddress); + masterIp = ipAddress; + + ensurePoolIntegrity(masterConn, ipAddress, username, password, + wait); + } catch (Exception e) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("failed to switch master to Unable to " + ipAddress + " due to " + e.getMessage()); + } + cleanup(poolUuid); + masterConn = null; + masterIp = null; + } + } + + if( masterConn == null ) { + throw new CloudRuntimeException(" Can not create connection to pool " + poolUuid); + } + info = _infos.get(poolUuid); + + if ( info == null ) { if (s_logger.isDebugEnabled()) { - s_logger.debug("This is the very first connection"); + s_logger.debug("Create info on master :" + masterIp); } info = new ConnectionInfo(); info.conn = masterConn; - info.masterUrl = masterUrl; + info.masterIp = masterIp; info.refs = new HashMap(); - _infos.put(poolUuid, info); masterConn.setInfo(poolUuid, info); + _infos.put(poolUuid, info); if (s_logger.isDebugEnabled()) { - s_logger.debug("Pool " + poolUuid + " is matched with session " + info.conn.getSessionReference()); + s_logger.debug("Pool " + poolUuid + + " is matched with session " + + info.conn.getSessionReference()); } } - - s_logger.debug("Added a reference for host " + hostUuid + " to session " + masterConn.getSessionReference() + " in pool " + poolUuid); - info.refs.put(hostUuid, new Member(slaveUrl, hostUuid, username, password)); + masterConn = new XenServerConnection(info.conn); + + s_logger.debug("Added a reference for host " + hostUuid + + " to session " + masterConn.getSessionReference() + + " in pool " + poolUuid); + info.refs.put(hostUuid, new Member(ipAddress, hostUuid, username, + password)); _conns.put(hostUuid, masterConn); - - s_logger.info("Connection made to " + ipAddress + " for host " + hostUuid + ". Pool Uuid is " + poolUuid); - + + s_logger.info("Connection made to " + ipAddress + " for host " + + hostUuid + ". Pool Uuid is " + poolUuid); + return masterConn; } catch (XenAPIException e) { - s_logger.warn("Unable to make a connection to the server " + ipAddress, e); - throw new CloudRuntimeException("Unable to make a connection to the server " + ipAddress, e); + s_logger.warn("Unable to make a connection to the server " + + ipAddress); + throw new CloudRuntimeException( + "Unable to make a connection to the server " + ipAddress); } catch (XmlRpcException e) { - s_logger.warn("Unable to make a connection to the server " + ipAddress, e); - throw new CloudRuntimeException("Unable to make a connection to the server " + ipAddress, e); + s_logger.warn("Unable to make a connection to the server " + + ipAddress, e); + throw new CloudRuntimeException( + "Unable to make a connection to the server " + ipAddress); } catch (MalformedURLException e) { - throw new CloudRuntimeException("How can we get a malformed exception for this " + ipAddress, e); + throw new CloudRuntimeException( + "How can we get a malformed exception for this " + + ipAddress); + } finally { + if (slaveConn != null) { + try { + Session.localLogout(slaveConn); + } catch (Exception e) { + } + slaveConn.dispose(); + slaveConn = null; + } } } - - - - protected Pool.Record getPoolRecord(Connection conn) throws XmlRpcException, XenAPIException { + + protected Pool.Record getPoolRecord(Connection conn) + throws XmlRpcException, XenAPIException { Map pools = Pool.getAllRecords(conn); - assert pools.size() == 1 : "Pool size is not one....hmmm....wth? " + pools.size(); - + assert pools.size() == 1 : "Pool size is not one....hmmm....wth? " + + pools.size(); + return pools.values().iterator().next(); } private static final XenServerConnectionPool s_instance = new XenServerConnectionPool(); + public static XenServerConnectionPool getInstance() { return s_instance; } - + protected class ConnectionInfo { - public URL masterUrl; + public String masterIp; public XenServerConnection conn; public HashMap refs = new HashMap(); } - + protected class Member { - public URL url; + public String ipAddr; public String uuid; public String username; public String password; - - public Member(URL url, String uuid, String username, String password) { - this.url = url; + + + public Member(String ipAddr, String uuid, String username, String password) { + this.ipAddr = ipAddr; this.uuid = uuid; this.username = username; this.password = password; } } - + public class XenServerConnection extends Connection { long _interval; int _retries; @@ -528,16 +708,17 @@ public class XenServerConnectionPool { URL _url; ConnectionInfo _info; String _poolUuid; - - public XenServerConnection(URL url, String username, String password, int retries, int interval, int wait) { + + public XenServerConnection(URL url, String username, String password, + int retries, int interval, int wait) { super(url, wait); _url = url; _retries = retries; _username = username; _password = password; - _interval = (long)interval * 1000; + _interval = (long) interval * 1000; } - + public XenServerConnection(XenServerConnection that) { super(that._url, that.getSessionReference(), that._wait); this._url = that._url; @@ -547,28 +728,40 @@ public class XenServerConnectionPool { this._interval = that._interval; this._info = that._info; this._poolUuid = that._poolUuid; - + } - + + public void setInfo(String poolUuid, ConnectionInfo info) { this._poolUuid = poolUuid; this._info = info; } - + public int getWaitTimeout() { return _wait; } + public String get_poolUuid() { + return _poolUuid; + } + @Override - protected Map dispatch(String method_call, Object[] method_params) throws XmlRpcException, XenAPIException { - if (method_call.equals("session.login_with_password") || method_call.equals("session.slave_local_login_with_password") || method_call.equals("session.logout")) { + protected Map dispatch(String method_call, Object[] method_params) throws XmlRpcException, XenAPIException { + if (method_call.equals("session.local_logout") + || method_call.equals("session.slave_local_login_with_password") + || method_call.equals("session.logout")) { + return super.dispatch(method_call, method_params); + } + + if (method_call.equals("session.login_with_password")) { int retries = 0; while (retries++ < _retries) { try { return super.dispatch(method_call, method_params); } catch (XmlRpcException e) { Throwable cause = e.getCause(); - if (cause == null || !(cause instanceof SocketException)) { + if (cause == null + || !(cause instanceof SocketException)) { throw e; } if (retries >= _retries) { @@ -578,60 +771,68 @@ public class XenServerConnectionPool { } try { Thread.sleep(_interval); - } catch(InterruptedException e) { - s_logger.debug("Man....I was just getting comfortable there....who woke me up?"); + } catch (InterruptedException e) { + s_logger + .debug("Man....I was just getting comfortable there....who woke me up?"); } } - } - - int retries = 0; - while (retries++ < _retries) { - try { - return super.dispatch(method_call, method_params); - } catch (Types.SessionInvalid e) { - if (retries >= _retries) { + } else { + int retries = 0; + while (retries++ < _retries) { + try { + return super.dispatch(method_call, method_params); + } catch (Types.SessionInvalid e) { + if (retries >= _retries) { + if (_poolUuid != null) { + cleanup(_poolUuid, _info); + } + throw e; + } + s_logger.debug("Session is invalid. Reconnecting...retry=" + + retries); + Session.loginWithPassword(this, _username, + _password, APIVersion.latest().toString()); + method_params[0] = getSessionReference(); + } catch (XmlRpcException e) { + if (retries >= _retries) { + if (_poolUuid != null) { + cleanup(_poolUuid, _info); + } + throw e; + } + Throwable cause = e.getCause(); + if (cause == null || !(cause instanceof SocketException)) { + if (_poolUuid != null) { + cleanup(_poolUuid, _info); + } + throw e; + } + s_logger.debug("Connection couldn't be made for method " + method_call + + " Reconnecting....retry=" + retries); + } catch (Types.HostIsSlave e) { if (_poolUuid != null) { cleanup(_poolUuid, _info); } throw e; } - s_logger.debug("Session is invalid. Reconnecting...retry=" + retries); - } catch (XmlRpcException e) { - if (retries >= _retries) { - if (_poolUuid != null) { - cleanup(_poolUuid, _info); - } - throw e; + + try { + Thread.sleep(_interval); + } catch (InterruptedException e) { + s_logger.info("Who woke me from my slumber?"); } - Throwable cause = e.getCause(); - if (cause == null || !(cause instanceof SocketException)) { - if (_poolUuid != null) { - cleanup(_poolUuid, _info); - } - throw e; - } - s_logger.debug("Connection couldn't be made. Reconnecting....retry=" + retries); - } catch (Types.HostIsSlave e) { - if (_poolUuid != null) { - cleanup(_poolUuid, _info); - } - throw e; - } - - try { - Thread.sleep(_interval); - } catch (InterruptedException e) { - s_logger.info("Who woke me from my slumber?"); - } + - Session session = Session.loginWithPassword(this, _username, _password, APIVersion.latest().toString()); - method_params[0] = getSessionReference(); + } + assert false : "We should never get here"; + if (_poolUuid != null) { + cleanup(_poolUuid, _info); + } } - assert false : "We should never get here"; - if (_poolUuid != null) { - cleanup(_poolUuid, _info); - } - throw new CloudRuntimeException("After " + _retries + " retries, we cannot contact the host "); + throw new CloudRuntimeException("After " + _retries + + " retries, we cannot contact the host "); } + + } } diff --git a/core/src/com/cloud/server/ManagementServer.java b/core/src/com/cloud/server/ManagementServer.java index 073ae465ba6..8e5a88f40e2 100755 --- a/core/src/com/cloud/server/ManagementServer.java +++ b/core/src/com/cloud/server/ManagementServer.java @@ -2234,4 +2234,7 @@ public interface ManagementServer { List searchForVmGroups(Criteria c); InstanceGroupVO getGroupForVm(long vmId); + + List searchForZoneWideVlans(long dcId, String vlanType,String vlanId); + } diff --git a/core/src/com/cloud/storage/StoragePoolVO.java b/core/src/com/cloud/storage/StoragePoolVO.java index 41cabb559b7..f3a3460157c 100644 --- a/core/src/com/cloud/storage/StoragePoolVO.java +++ b/core/src/com/cloud/storage/StoragePoolVO.java @@ -181,6 +181,7 @@ public class StoragePoolVO implements StoragePool { this.path = hostPath; this.port = port; this.podId = podId; + this.setStatus(Status.Up); } public StoragePoolVO(StoragePoolType type, String hostAddress, int port, String path) { @@ -188,6 +189,7 @@ public class StoragePoolVO implements StoragePool { this.hostAddress = hostAddress; this.port = port; this.path = path; + this.setStatus(Status.Up); } public void setStatus(Status status) diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 915f95ba7ab..ffa53b5b53d 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -690,11 +690,12 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { long seq = _hostDao.getNextSequence(hostId); Request req = new Request(seq, hostId, _nodeId, new Command[] { new CheckHealthCommand() }, true, true); Answer[] answers = agent.send(req, 50 * 1000); - if (answers[0].getResult()) { + if (answers != null && answers[0] != null ) { + Status status = answers[0].getResult() ? Status.Up : Status.Down; if (s_logger.isDebugEnabled()) { - s_logger.debug("agent (" + hostId + ") responded to checkHeathCommand, reporting that agent is up"); + s_logger.debug("agent (" + hostId + ") responded to checkHeathCommand, reporting that agent is " + status); } - return answers[0].getResult() ? Status.Up : Status.Down; + return status; } } catch (AgentUnavailableException e) { s_logger.debug("Agent is unavailable so we move on."); diff --git a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java index 2465d7a01ae..2570cb94aef 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java @@ -99,7 +99,7 @@ public class FirstFitAllocator implements HostAllocator { while (it.hasNext()) { HostVO host = it.next(); if (avoid.contains(host)) { - clusterHosts.remove(host); + it.remove(); } else { if (s_logger.isDebugEnabled()) { s_logger.debug("Adding host " + host + " as possible pod host"); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index e2f22c3989d..03b24c200fb 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -47,7 +47,7 @@ public enum Config { StorageOverprovisioningFactor("Storage", StoragePoolAllocator.class, String.class, "storage.overprovisioning.factor", "2", "Used for storage overprovisioning calculation; available storage will be (actualStorageSize * storage.overprovisioning.factor)", null), StorageStatsInterval("Storage", ManagementServer.class, String.class, "storage.stats.interval", "60000", "The interval in milliseconds when storage stats (per host) are retrieved from agents.", null), - MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "max.volume.size.gb", "2000", "The maximum size for a volume in Gb.", null), + MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "max.volume.size.gb", "2097152000", "The maximum size for a volume in Gb.", null), TotalRetries("Storage", AgentManager.class, Integer.class, "total.retries", "4", "The number of times each command sent to a host should be retried in case of failure.", null), // Network diff --git a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index e7dc2a20fbb..0f5ff922677 100644 --- a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -102,6 +102,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L public Map> find(long dcId, Long podId, Long clusterId, URI url, String username, String password) throws DiscoveryException { Map> resources = new HashMap>(); Connection conn = null; + Connection slaveConn = null; if (!url.getScheme().equals("http")) { String msg = "urlString is not http so we're not taking care of the discovery for this: " + url; s_logger.debug(msg); @@ -113,7 +114,8 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L InetAddress ia = InetAddress.getByName(hostname); String addr = ia.getHostAddress(); - conn = _connPool.connect(addr, username, password, _wait); + conn = _connPool.masterConnect(addr, username, password); + if (conn == null) { String msg = "Unable to get a connection to " + url; s_logger.debug(msg); @@ -133,33 +135,33 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L if (clusterId != null) { cluster = Long.toString(clusterId); } - + Set pools = Pool.getAll(conn); + Pool pool = pools.iterator().next(); + String poolUuid = pool.getUuid(conn); Map hosts = Host.getAllRecords(conn); if (_checkHvm) { - for (Map.Entry entry : hosts.entrySet()) { - Host.Record record = entry.getValue(); - - boolean support_hvm = false; - for ( String capability : record.capabilities ) { - if(capability.contains("hvm")) { - support_hvm = true; - break; + for (Map.Entry entry : hosts.entrySet()) { + Host.Record record = entry.getValue(); + + boolean support_hvm = false; + for ( String capability : record.capabilities ) { + if(capability.contains("hvm")) { + support_hvm = true; + break; + } + } + if( !support_hvm ) { + String msg = "Unable to add host " + record.address + " because it doesn't support hvm"; + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, msg, msg); + s_logger.debug(msg); + throw new RuntimeException(msg); } } - if( !support_hvm ) { - String msg = "Unable to add host " + record.address + " because it doesn't support hvm"; - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, msg, msg); - s_logger.debug(msg); - throw new RuntimeException(msg); - } - } - } for (Map.Entry entry : hosts.entrySet()) { - Host.Record record = entry.getValue(); Host host = entry.getKey(); - + Host.Record record = entry.getValue(); String hostAddr = record.address; String prodVersion = record.softwareVersion.get("product_version"); @@ -180,6 +182,8 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L Map params = new HashMap(); details.put("url", hostAddr); params.put("url", hostAddr); + details.put("pool", poolUuid); + params.put("pool", poolUuid); details.put("username", username); params.put("username", username); details.put("password", password); @@ -253,10 +257,13 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L return null; } finally { if (conn != null) { - XenServerConnectionPool.logout(conn); + try{ + Session.logout(conn); + } catch (Exception e ) { + } + conn.dispose(); } } - return resources; } @@ -333,20 +340,30 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L username = host.getDetail("username"); password = host.getDetail("password"); address = host.getDetail("url"); - Connection hostConn = _connPool.connect(address, username, password, _wait); + Connection hostConn = _connPool.slaveConnect(address, username, password); + if (hostConn == null) { + continue; + } try { - if (hostConn == null) { - continue; - } Set pools = Pool.getAll(hostConn); Pool pool = pools.iterator().next(); poolUuid1 = pool.getUuid(hostConn); poolMaster = pool.getMaster(hostConn).getAddress(hostConn); - Session.logout(hostConn); - } finally { - hostConn.dispose(); + break; + + } catch (Exception e ) { + s_logger.warn("Can not get master ip address from host " + address); + } + finally { + try{ + Session.localLogout(hostConn); + } catch (Exception e ) { + } + hostConn.dispose(); + hostConn = null; + poolMaster = null; + poolUuid1 = null; } - break; } if (poolMaster == null) { diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 641ceddb94b..b8139961922 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -461,7 +461,7 @@ public class ManagementServerImpl implements ManagementServer { // and set them in the right places String maxVolumeSizeInGbString = _configs.get("max.volume.size.gb"); - int maxVolumeSizeGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, 2000); + int maxVolumeSizeGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, 2097152000); _maxVolumeSizeInGb = maxVolumeSizeGb; @@ -3431,29 +3431,77 @@ public class ManagementServerImpl implements ManagementServer { // check for ip address/port conflicts by checking existing forwarding and load balancing rules List existingRulesOnPubIp = _firewallRulesDao.listIPForwarding(ipAddress); - Map> mappedPublicPorts = new HashMap>(); - + Map mappedPublicPorts = new HashMap(); + Map publicPortToProtocolMapping=new HashMap(); if (existingRulesOnPubIp != null) { for (FirewallRuleVO fwRule : existingRulesOnPubIp) { - mappedPublicPorts.put(fwRule.getPublicPort(), new Pair(fwRule.getPrivateIpAddress(), fwRule.getPrivatePort())); + + //mappedPublicPorts.put(fwRule.getPublicPort(), new Pair(fwRule.getPrivateIpAddress(), fwRule.getPrivatePort())); + if(mappedPublicPorts.containsKey(fwRule.getPublicPort())){ + mappedPublicPorts.put(fwRule.getPublicPort(), mappedPublicPorts.get(fwRule.getPublicPort()).append(";").append(fwRule.getPrivateIpAddress().concat(",").concat(fwRule.getPrivatePort()))); + } + else{ + mappedPublicPorts.put(fwRule.getPublicPort(), new StringBuilder(fwRule.getPrivateIpAddress()+","+fwRule.getPrivatePort())); + } + + if(publicPortToProtocolMapping.containsKey(fwRule.getPublicPort())){ + publicPortToProtocolMapping.put(fwRule.getPublicPort(), publicPortToProtocolMapping.get(fwRule.getPublicPort()).append(";").append(fwRule.getProtocol())); + } + else{ + publicPortToProtocolMapping.put(fwRule.getPublicPort(),new StringBuilder(fwRule.getProtocol())); + } } } - if (userVm != null) { - Pair privateIpPort = mappedPublicPorts.get(publicPort); - if (privateIpPort != null) { - if (privateIpPort.first().equals(userVm.getGuestIpAddress()) && privateIpPort.second().equals(privatePort)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("skipping the creating of firewall rule " + ipAddress + ":" + publicPort + " to " + userVm.getGuestIpAddress() + ":" + privatePort + "; rule already exists."); - } - return null; // already mapped - } else { - throw new NetworkRuleConflictException("An existing port forwarding service rule for " + ipAddress + ":" + publicPort - + " already exists, found while trying to create mapping to " + userVm.getGuestIpAddress() + ":" + privatePort + ((securityGroupId == null) ? "." : " from port forwarding service " - + securityGroupId.toString() + ".")); - } - } - + if (userVm != null) + { + if(mappedPublicPorts.size()>0) + { + StringBuilder privateIpPortIntermediate = mappedPublicPorts.get(publicPort); + String privateIpPort = null; + if(privateIpPortIntermediate != null && privateIpPortIntermediate.length()>0) + privateIpPort = privateIpPortIntermediate.toString();//eg: 10.1.1.2,30 ; 10.1.1.2,34 + + if (privateIpPort != null && privateIpPort.length()>0) + { + String publicPortProtocol = publicPortToProtocolMapping.get(publicPort).toString(); + String[] privateIpPortPairs = privateIpPort.toString().split(";"); //eg. 10.1.1.2,30 + String[] privateIpAndPortStr; + boolean errFlag = false; + + for(String pair: privateIpPortPairs) + { + privateIpAndPortStr = pair.split(",");//split into 10.1.1.2 & 30 + + if (privateIpAndPortStr[0].equals(userVm.getGuestIpAddress()) && privateIpAndPortStr[1].equals(privatePort)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("skipping the creating of firewall rule " + ipAddress + ":" + publicPort + " to " + userVm.getGuestIpAddress() + ":" + privatePort + "; rule already exists."); + } + return null; // already mapped + } + //at this point protocol string looks like: eg. tcp;udp || tcp || udp || udp;tcp + else if(!publicPortProtocol.contains(protocol))//check if this public port is mapped to the protocol or not + { + //this is the case eg: + //pub:1 pri:2 pro: tcp + //pub 1 pri:3 pro: udp + break; //we break here out of the loop, for the record to be created + } + else + { + errFlag = true; + // throw new NetworkRuleConflictException("An existing port forwarding service rule for " + ipAddress + ":" + publicPort + // + " already exists, found while trying to create mapping to " + userVm.getGuestIpAddress() + ":" + privatePort + ((securityGroupId == null) ? "." : " from port forwarding service " + // + securityGroupId.toString() + ".")); + } + } + + if(errFlag) + throw new NetworkRuleConflictException("An existing port forwarding service rule for " + ipAddress + ":" + publicPort + + " already exists, found while trying to create mapping to " + userVm.getGuestIpAddress() + ":" + privatePort + ((securityGroupId == null) ? "." : " from port forwarding service " + + securityGroupId.toString() + ".")); + } + } FirewallRuleVO newFwRule = new FirewallRuleVO(); newFwRule.setEnabled(true); newFwRule.setForwarding(true); @@ -8792,7 +8840,7 @@ public class ManagementServerImpl implements ManagementServer { return false; } - //Move this section to UserVmManager when merge with api refactor branch is done + //Move vmGroup section to UserVmManager when merge with api refactor branch is done @Override public InstanceGroupVO createVmGroup(String name, Long accountId){ return _vmMgr.createVmGroup(name, accountId); @@ -8885,5 +8933,10 @@ public class ManagementServerImpl implements ManagementServer { //Move section above to UserVmManager when merge with api refactor branch is done + @Override + public List searchForZoneWideVlans(long dcId, String vlanType, String vlanId){ + return _vlanDao.searchForZoneWideVlans(dcId, vlanType, vlanId); + } + } diff --git a/server/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/com/cloud/storage/LocalStoragePoolListener.java index b113ec1a909..2c82edfe064 100644 --- a/server/src/com/cloud/storage/LocalStoragePoolListener.java +++ b/server/src/com/cloud/storage/LocalStoragePoolListener.java @@ -91,9 +91,7 @@ public class LocalStoragePoolListener implements Listener { pool = new StoragePoolVO(poolId, name, pInfo.getUuid(), pInfo.getPoolType(), host.getDataCenterId(), host.getPodId(), pInfo.getAvailableBytes(), pInfo.getCapacityBytes(), pInfo.getHost(), 0, pInfo.getHostPath()); - pool.setStatus(Status.Up); pool.setClusterId(host.getClusterId()); - pool.setStatus(Status.Up); _storagePoolDao.persist(pool, pInfo.getDetails()); StoragePoolHostVO poolHost = new StoragePoolHostVO(pool.getId(), host.getId(), pInfo.getLocalPath()); _storagePoolHostDao.persist(poolHost); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 864825ed87a..4f8176eada9 100644 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -308,7 +308,7 @@ public class StorageManagerImpl implements StorageManager { { StoragePoolVO sp = _storagePoolDao.findById(vol.getPoolId()); - if(sp.getStatus().equals(Status.PrepareForMaintenance)) + if(sp!=null && sp.getStatus().equals(Status.PrepareForMaintenance)) { recreateVols.add(vol); continue; diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index 1f2e6b0db21..b51a99f3af4 100644 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -49,6 +49,7 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; +import com.cloud.host.Status; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.service.ServiceOfferingVO; @@ -529,7 +530,7 @@ public class DatabaseConfig { String storageType = _currentObjectParams.get("storageType"); String uuid = UUID.nameUUIDFromBytes(new String(hostAddress+hostPath).getBytes()).toString(); - String insertSql1 = "INSERT INTO `storage_pool` (`id`, `name`, `uuid` , `pool_type` , `port`, `data_center_id` ,`available_bytes` , `capacity_bytes` ,`host_address`, `path`, `created`, `pod_id` ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; + String insertSql1 = "INSERT INTO `storage_pool` (`id`, `name`, `uuid` , `pool_type` , `port`, `data_center_id` ,`available_bytes` , `capacity_bytes` ,`host_address`, `path`, `created`, `pod_id`,`status` ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"; // String insertSql2 = "INSERT INTO `netfs_storage_pool` VALUES (?,?,?)"; Transaction txn = Transaction.currentTxn(); @@ -550,6 +551,7 @@ public class DatabaseConfig { stmt.setString(10, hostPath); stmt.setDate(11, new Date(new java.util.Date().getTime())); stmt.setLong(12, podId); + stmt.setString(13, Status.Up.toString()); stmt.executeUpdate(); // stmt = txn.prepareAutoCloseStatement(insertSql2); // stmt.setLong(1, 2); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 1efdbde6783..bc41517624e 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -84,6 +84,7 @@ import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; @@ -224,6 +225,7 @@ public class UserVmManagerImpl implements UserVmManager { @Inject AsyncJobManager _asyncMgr; @Inject protected StoragePoolHostDao _storagePoolHostDao; @Inject VlanDao _vlanDao; + @Inject AccountVlanMapDao _accountVlanMapDao; @Inject StoragePoolDao _storagePoolDao; @Inject VMTemplateHostDao _vmTemplateHostDao; @Inject NetworkGroupManager _networkGroupManager; @@ -1873,6 +1875,7 @@ public class UserVmManagerImpl implements UserVmManager { Enumeration it = ipAllocators.enumeration(); _IpAllocator = it.nextElement(); } + return true; } @@ -2653,15 +2656,30 @@ public class UserVmManagerImpl implements UserVmManager { List vlansForAccount = _vlanDao.listVlansForAccountByType(dc.getId(), account.getId(), VlanType.DirectAttached); boolean forAccount = false; + boolean forZone = false; if (vlansForAccount.size() > 0) { forAccount = true; guestVlan = vlansForAccount.get(0);//FIXME: iterate over all vlans } +// else //TODO PLEASE DO NOT REMOVE THIS COMMENTED PART +// { +// //list zone wide vlans that are direct attached and tagged +// //if exists pick random one +// //set forZone = true +// +// //note the dao method below does a NEQ on vlan id, hence passing untagged +// List zoneWideVlans = _vlanDao.searchForZoneWideVlans(dc.getId(),VlanType.DirectAttached.toString(),"untagged"); +// +// if(zoneWideVlans!=null && zoneWideVlans.size()>0){ +// forZone = true; +// guestVlan = zoneWideVlans.get(0);//FIXME: iterate over all vlans +// } +// } while ((pod = _agentMgr.findPod(template, offering, dc, account.getId(), avoids)) != null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Attempting to create direct attached vm in pod " + pod.first().getName()); } - if (!forAccount) { + if (!forAccount && !forZone) { List vlansForPod = _vlanDao.listVlansForPodByType(pod.first().getId(), VlanType.DirectAttached); if (vlansForPod.size() < 1) { avoids.add(pod.first().getId()); diff --git a/ui/new/css/main.css b/ui/new/css/main.css index ecb08741008..24058dc9571 100644 --- a/ui/new/css/main.css +++ b/ui/new/css/main.css @@ -38,7 +38,8 @@ a { } a:link, a:visited { - text-decoration:none; + text-decoration:none; + } a:visited { @@ -232,7 +233,7 @@ a:visited { width:420px; height:auto; float:left; - background:#ffe5e5 repeat top left; + background:#ffe5e5 url(../images/errormsg_bg.gif) repeat-x top left; border:1px solid #CCC; margin:7px 0 0 0; padding:0 0 5px 0; @@ -833,7 +834,7 @@ a:visited { padding:0; } -.rev_wiztemplist_actionsbox a:link { +.rev_wiztemplist_actionsbox a { width:auto; height:auto; float:left; @@ -846,30 +847,13 @@ a:visited { padding:0; } -.rev_wiztemplist_actionsbox a:visted { - width:auto; - height:auto; - float:left; - color:#2c8bbc; - font-size:12px; - text-align:left; - font-weight:normal; +.rev_wiztemplist_actionsbox a:link, rev_wiztemplist_actionsbox a:visted { text-decoration:none; - margin:0 15px 0 0; - padding:0; } .rev_wiztemplist_actionsbox a:hover { - width:auto; - height:auto; - float:left; - color:#2c8bbc; - font-size:12px; - text-align:left; - font-weight:normal; text-decoration:underline; - margin:0 15px 0 0; - padding:0; + } @@ -1837,11 +1821,14 @@ a:visited { width:100%; height:auto; float:left; + position:relative; margin:0; padding:5px 0 5px 0; border-bottom:1px solid #e2e2e2; } + + .grid_rows.even { background:#FFF repeat top left; } @@ -1855,6 +1842,70 @@ a:visited { float:left; margin:0; padding:0; + border-right:1px solid #fff; +} + + +.grid_row_cell .text { + width:92%; + height:13px; + float:left; + margin:0 0 0 10px; + display:inline; + padding:0; + border:1px solid #999; + background:#FFF; + color:#333; + font-size:11px; +} + +.grid_row_cell .select { + width:92%; + height:15px; + float:left; + margin:0 0 0 10px; + display:inline; + padding:0; + border:1px solid #999; + background:#FFF; + color:#333; + font-size:11px; +} + +.gridrow_loaderbox { + width:100%; + height:23px; + float:right; + position:absolute; + background:#99b2c3 url(../images/gridheader_loadingbg.gif) repeat-x top left; + border-left:1px solid #999; + margin:0 0 0 0; + padding:0; + z-index:1001; + top:0; + right:0; +} + +.gridrow_loaderbox p{ + width:auto; + height:auto; + float:left; + color:#FFF; + font-size:11px; + font-weight:bold; + margin:5px 5px 0 5px; + display:inline; + padding:0; +} + +.gridrow_loader { + width:16px; + height:16px; + float:left; + background:url(../images/grid_actionloader.gif) no-repeat top left; + margin:3px 0 0 5px; + display:inline; + padding:0; } .row_celltitles { @@ -1870,6 +1921,8 @@ a:visited { padding:0; } + + .row_celltitles a{ width:auto; height:auto; @@ -2064,7 +2117,7 @@ a:visited { width:100%; height:auto; float:left; - background:#fffbe6 repeat top left; + background:#fffbe6 url(../images/infomsg_bg.gif) repeat-x top left; border:1px dashed #CCC; color:#333; margin:0 0 0 0; @@ -2082,7 +2135,7 @@ a:visited { } .info_detailbox.errorbox { - background:#ffe5e5 repeat top left; + background:#ffe5e5 url(../images/errormsg_bg.gif) repeat-x top left; color:#a90000; } @@ -2148,8 +2201,7 @@ a:visited { position:absolute; background:#99b2c3 url(../images/gridheader_loadingbg.gif) repeat-x top left; border-left:1px solid #999; - margin:0px 0 0 0; - padding:0; + padding:0 5px 0 0; z-index:1001; right:0; } @@ -2161,7 +2213,7 @@ a:visited { color:#FFF; font-size:11px; font-weight:bold; - margin:2px 5px 0 5px; + margin:3px 5px 0 5px; display:inline; padding:0; } @@ -2176,6 +2228,68 @@ a:visited { padding:0; } +.gridheader_message { + width:auto; + height:20px; + float:right; + position:absolute; + border-left:1px solid #999; + background:#fffbe6 url(../images/infomsg_bg.gif) repeat-x top left; + margin:0px 0 0 0; + padding:0 5px 0 0; + z-index:1005; + right:0; +} + +.gridheader_message p { + width:auto; + height:auto; + float:left; + color:#333; + font-size:11px; + font-size:11px; + font-weight:bold; + margin:2px 0 0 5px; + display:inline; + padding:0; +} + + +.gridheader_message.error { + background:#ffe5e5 url(../images/errormsg_bg.gif) repeat-x top left; +} + +.gridheader_message.error p{ + width:auto; + height:auto; + float:left; + color:#ae0000; + font-size:11px; + font-size:11px; + font-weight:bold; + margin:2px 0 0 5px; + display:inline; + padding:0; +} + +.close_button { + width:38px; + height:17px; + float:left; + background:url(../images/close_button.png) no-repeat top left; + display:inline; + padding:0; + cursor:pointer; + cursor:hand; + margin:1px 0 0 5px; + padding:0; + +} + +.close_button:hover{ + background:url(../images/close_button_hover.png) no-repeat top left; +} + .grid_editbox { width:27px; height:17px; @@ -2244,5 +2358,6 @@ a:visited { top:17px; right:6px; margin:0; - padding:0 + padding:0; + z-index:1002; } \ No newline at end of file diff --git a/ui/new/images/close_button.png b/ui/new/images/close_button.png new file mode 100644 index 00000000000..593048b0e46 Binary files /dev/null and b/ui/new/images/close_button.png differ diff --git a/ui/new/images/close_button_hover.png b/ui/new/images/close_button_hover.png new file mode 100644 index 00000000000..db1f19c0949 Binary files /dev/null and b/ui/new/images/close_button_hover.png differ diff --git a/ui/new/images/errormsg_bg.gif b/ui/new/images/errormsg_bg.gif new file mode 100644 index 00000000000..e148cbdac94 Binary files /dev/null and b/ui/new/images/errormsg_bg.gif differ diff --git a/ui/new/images/infomsg_bg.gif b/ui/new/images/infomsg_bg.gif new file mode 100644 index 00000000000..dda40b6dc1a Binary files /dev/null and b/ui/new/images/infomsg_bg.gif differ diff --git a/ui/new/images/midmenuicon_storage_centostemplate.png b/ui/new/images/midmenuicon_template_centos.png similarity index 100% rename from ui/new/images/midmenuicon_storage_centostemplate.png rename to ui/new/images/midmenuicon_template_centos.png diff --git a/ui/new/images/midmenuicon_storage_linuxtemplate.png b/ui/new/images/midmenuicon_template_linux.png similarity index 100% rename from ui/new/images/midmenuicon_storage_linuxtemplate.png rename to ui/new/images/midmenuicon_template_linux.png diff --git a/ui/new/images/midmenuicon_storage_windowstemplate.png b/ui/new/images/midmenuicon_template_windows.png similarity index 100% rename from ui/new/images/midmenuicon_storage_windowstemplate.png rename to ui/new/images/midmenuicon_template_windows.png diff --git a/ui/new/images/accountstitle_icons.gif b/ui/new/images/title_accountsicon.gif similarity index 100% rename from ui/new/images/accountstitle_icons.gif rename to ui/new/images/title_accountsicon.gif diff --git a/ui/new/images/alerttitle_icons.gif b/ui/new/images/title_alerticon.gif similarity index 100% rename from ui/new/images/alerttitle_icons.gif rename to ui/new/images/title_alerticon.gif diff --git a/ui/new/images/cproxytitle_icons.gif b/ui/new/images/title_cproxyicon.gif similarity index 100% rename from ui/new/images/cproxytitle_icons.gif rename to ui/new/images/title_cproxyicon.gif diff --git a/ui/new/images/dashboardtitle_icons.gif b/ui/new/images/title_dashboardicon.gif similarity index 100% rename from ui/new/images/dashboardtitle_icons.gif rename to ui/new/images/title_dashboardicon.gif diff --git a/ui/new/images/domaintitle_icons.gif b/ui/new/images/title_domainicon.gif similarity index 100% rename from ui/new/images/domaintitle_icons.gif rename to ui/new/images/title_domainicon.gif diff --git a/ui/new/images/eventstitle_icons.gif b/ui/new/images/title_eventsicon.gif similarity index 100% rename from ui/new/images/eventstitle_icons.gif rename to ui/new/images/title_eventsicon.gif diff --git a/ui/new/images/hosttitle_icons.gif b/ui/new/images/title_hosticon.gif similarity index 100% rename from ui/new/images/hosttitle_icons.gif rename to ui/new/images/title_hosticon.gif diff --git a/ui/new/images/instancetitle_icons.gif b/ui/new/images/title_instanceicons.gif similarity index 100% rename from ui/new/images/instancetitle_icons.gif rename to ui/new/images/title_instanceicons.gif diff --git a/ui/new/images/iptitle_icons.gif b/ui/new/images/title_ipicon.gif similarity index 100% rename from ui/new/images/iptitle_icons.gif rename to ui/new/images/title_ipicon.gif diff --git a/ui/new/images/title_isoicon.gif b/ui/new/images/title_isoicon.gif new file mode 100644 index 00000000000..8fed65bf823 Binary files /dev/null and b/ui/new/images/title_isoicon.gif differ diff --git a/ui/new/images/loadtitle_icons.gif b/ui/new/images/title_loadicon.gif similarity index 100% rename from ui/new/images/loadtitle_icons.gif rename to ui/new/images/title_loadicon.gif diff --git a/ui/new/images/loadnetwork_titleicon.gif b/ui/new/images/title_loadnetworkicon.gif similarity index 100% rename from ui/new/images/loadnetwork_titleicon.gif rename to ui/new/images/title_loadnetworkicon.gif diff --git a/ui/new/images/routerstitle_icons.gif b/ui/new/images/title_routersicon.gif similarity index 100% rename from ui/new/images/routerstitle_icons.gif rename to ui/new/images/title_routersicon.gif diff --git a/ui/new/images/sgtitle_icons.gif b/ui/new/images/title_secgroupicons.gif similarity index 100% rename from ui/new/images/sgtitle_icons.gif rename to ui/new/images/title_secgroupicons.gif diff --git a/ui/new/images/serviceofftitle_icons.gif b/ui/new/images/title_serviceofficon.gif similarity index 100% rename from ui/new/images/serviceofftitle_icons.gif rename to ui/new/images/title_serviceofficon.gif diff --git a/ui/new/images/title_snapshoticon.gif b/ui/new/images/title_snapshoticon.gif new file mode 100644 index 00000000000..2c6736cb0a3 Binary files /dev/null and b/ui/new/images/title_snapshoticon.gif differ diff --git a/ui/new/images/title_templatesicon.gif b/ui/new/images/title_templatesicon.gif new file mode 100644 index 00000000000..db8b1239683 Binary files /dev/null and b/ui/new/images/title_templatesicon.gif differ diff --git a/ui/new/images/title_volumeicons.gif b/ui/new/images/title_volumeicons.gif new file mode 100644 index 00000000000..bffcfafa3d0 Binary files /dev/null and b/ui/new/images/title_volumeicons.gif differ diff --git a/ui/new/index.jsp b/ui/new/index.jsp index a60dc348803..f3a3b430569 100644 --- a/ui/new/index.jsp +++ b/ui/new/index.jsp @@ -50,6 +50,10 @@ long milliseconds = new Date().getTime(); + + + + Cloud.com CloudStack @@ -105,7 +109,7 @@ long milliseconds = new Date().getTime(); -