bug 6363:

1. delete local storage when delete host
    2. delete host detail when delete host
    3. allow one host in maintance mode in a cluster instead of in a pod

    status 6363: resolved fixed
This commit is contained in:
anthony 2010-10-01 10:40:08 -07:00
parent 9d5d1084d7
commit f433a4d360
9 changed files with 113 additions and 55 deletions

View File

@ -28,4 +28,6 @@ public interface DetailsDao extends GenericDao<DetailVO, Long> {
void persist(long hostId, Map<String, String> details);
DetailVO findDetail(long hostId, String name);
void deleteDetails(long hostId);
}

View File

@ -66,6 +66,17 @@ public class DetailsDaoImpl extends GenericDaoBase<DetailVO, Long> implements De
}
return details;
}
@Override
public void deleteDetails(long hostId) {
SearchCriteria sc = HostSearch.create();
sc.setParameters("hostId", hostId);
List<DetailVO> results = search(sc, null);
for (DetailVO result : results) {
remove(result.getId());
}
}
@Override
public void persist(long hostId, Map<String, String> details) {

View File

@ -35,7 +35,7 @@ import com.cloud.utils.db.GenericDao;
public interface HostDao extends GenericDao<HostVO, Long> {
List<HostVO> listBy(Host.Type type, Long clusterId, Long podId, long dcId);
long countBy(long podId, Status... statuses);
long countBy(long clusterId, Status... statuses);
List<HostVO> listByDataCenter(long dcId);
List<HostVO> listByHostPod(long podId);

View File

@ -77,7 +77,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
protected final SearchBuilder<HostVO> SequenceSearch;
protected final SearchBuilder<HostVO> DirectlyConnectedSearch;
protected final SearchBuilder<HostVO> UnmanagedDirectConnectSearch;
protected final GenericSearchBuilder<HostVO, Long> MaintenanceCountSearch;
protected final SearchBuilder<HostVO> MaintenanceCountSearch;
protected final SearchBuilder<HostVO> ClusterSearch;
protected final Attribute _statusAttr;
@ -88,9 +88,8 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
public HostDaoImpl() {
MaintenanceCountSearch = createSearchBuilder(Long.class);
MaintenanceCountSearch.and("pod", MaintenanceCountSearch.entity().getPodId(), SearchCriteria.Op.EQ);
MaintenanceCountSearch.select(null, Func.COUNT, null);
MaintenanceCountSearch = createSearchBuilder();
MaintenanceCountSearch.and("cluster", MaintenanceCountSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
MaintenanceCountSearch.and("status", MaintenanceCountSearch.entity().getStatus(), SearchCriteria.Op.IN);
MaintenanceCountSearch.done();
@ -200,18 +199,14 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
}
@Override
public long countBy(long podId, Status... statuses) {
SearchCriteria<Long> sc = MaintenanceCountSearch.create();
public long countBy(long clusterId, Status... statuses) {
SearchCriteria<HostVO> sc = MaintenanceCountSearch.create();
sc.setParameters("status", (Object[])statuses);
sc.setParameters("pod", podId);
List<Long> rs = searchIncludingRemoved(sc, null);
if (rs.size() == 0) {
return 0;
}
return rs.get(0);
sc.setParameters("cluster", clusterId);
List<HostVO> hosts = listBy(sc);
return hosts.size();
}
@Override

View File

@ -2541,15 +2541,19 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
public boolean joinPool(String masterIp, String username, String password) {
Connection slaveConn = null;
Connection hostConn = null;
Connection poolConn = null;
Session slaveSession = null;
URL slaveUrl = null;
Session hostSession = null;
URL hostUrl = null;
try {
// Connect and find out about the new connection to the new pool.
poolConn = _connPool.masterConnect(masterIp, username, password);
Set<Pool> pools = Pool.getAll(poolConn);
Pool pool = pools.iterator().next();
String poolUUID = pool.getUuid(poolConn);
//check if this host is already in pool
Set<Host> hosts = Host.getAll(poolConn);
for( Host host : hosts ) {
@ -2558,13 +2562,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
}
}
slaveUrl = new URL("http://" + _host.ip);
slaveConn = new Connection(slaveUrl, 100);
slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, _username, _password);
hostUrl = new URL("http://" + _host.ip);
hostConn = new Connection(hostUrl, 100);
hostSession = Session.loginWithPassword(hostConn, _username, _password, APIVersion.latest().toString());
// Now join it.
Pool.join(slaveConn, masterIp, username, password);
Pool.join(hostConn, masterIp, username, password);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Joined the pool at " + masterIp);
}
@ -2576,12 +2580,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
}
// check if the master of this host is set correctly.
Connection c = new Connection(slaveUrl, 100);
for (int i = 0; i < 15; i++) {
Connection c = new Connection(hostUrl, 100);
int i;
for (i = 0 ; i < 15; i++) {
try {
Session.loginWithPassword(c, _username, _password, APIVersion.latest().toString());
s_logger.debug("Still waiting for the conversion to the master");
s_logger.debug(_host.ip + " is still master, waiting for the conversion to the slave");
Session.logout(c);
c.dispose();
} catch (Types.HostIsSlave e) {
@ -2604,7 +2609,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
} catch (InterruptedException e) {
}
}
if( i >= 15 ) {
throw new CloudRuntimeException(_host.ip + " didn't change to slave after waiting 30 secondary");
}
_host.pool = poolUUID;
return true;
} catch (MalformedURLException e) {
throw new CloudRuntimeException("Problem with url " + _host.ip);
@ -2626,9 +2634,9 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
}
poolConn.dispose();
}
if(slaveSession != null) {
if(hostSession != null) {
try {
Session.localLogout(slaveConn);
Session.logout(hostConn);
} catch (Exception e) {
}
}
@ -6166,7 +6174,19 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
protected Answer execute(PoolEjectCommand cmd) {
Connection conn = getConnection();
String hostuuid = cmd.getHostuuid();
try {
Map<Host, Host.Record> hostrs = Host.getAllRecords(conn);
boolean found = false;
for( Host.Record hr : hostrs.values() ) {
if( hr.uuid.equals(hostuuid)) {
found = true;
}
}
if( ! found) {
s_logger.debug("host " + hostuuid + " has already been ejected from pool " + _host.pool);
return new Answer(cmd);
}
Host host = Host.getByUuid(conn, hostuuid);
// remove all tags cloud stack add before eject
Host.Record hr = host.getRecord(conn);

View File

@ -49,7 +49,7 @@ public class StoragePoolVO implements StoragePool {
@Column(name="name", updatable=false, nullable=false, length=255)
private String name = null;
@Column(name="uuid", updatable=false, nullable=false, length=255)
@Column(name="uuid", length=255)
private String uuid = null;
@Column(name="pool_type", updatable=false, nullable=false, length=32)

View File

@ -529,18 +529,24 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory {
if (host.getType() == Type.Routing && host.getHypervisorType() == HypervisorType.XenServer ) {
if (host.getClusterId() != null) {
List<HostVO> hosts = _hostDao.listBy(Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId());
boolean success = false;
for( HostVO thost: hosts ) {
long thostId = thost.getId();
if( thostId == hostId ) continue;
PoolEjectCommand eject = new PoolEjectCommand(host.getGuid());
Answer answer = easySend(thostId, eject);
if( answer == null || !answer.getResult()) {
if( answer != null && answer.getResult()) {
s_logger.debug("Eject Host: " + hostId + " from " + thostId + " Succeed");
success = true;
break;
} else {
s_logger.debug("Eject Host: " + hostId + " from " + thostId + " failed due to " + answer.getDetails());
continue;
}
break;
}
if( !success ){
throw new CloudRuntimeException("Unable to delete host " + hostId + " due to unable to eject it from pool");
}
}
}
txn.start();
@ -548,6 +554,10 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory {
_dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
AgentAttache attache = _agents.get(hostId);
handleDisconnect(attache, Status.Event.Remove, false);
//delete host details
_hostDetailsDao.deleteDetails(hostId);
host.setGuid(null);
host.setClusterId(null);
_hostDao.update(host.getId(), host);
@ -567,8 +577,14 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory {
_storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
//3.For pool ids you got, delete entries in pool table where type='FileSystem' || 'LVM'
if(!pool_ids.isEmpty()) {
_storagePoolDao.deleteStoragePoolRecords(pool_ids);
for( Long poolId : pool_ids) {
StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
if( storagePool.isLocal()) {
storagePool.setUuid(null);
storagePool.setClusterId(null);
_storagePoolDao.update(poolId, storagePool);
_storagePoolDao.remove(poolId);
}
}
txn.commit();
return true;

View File

@ -104,14 +104,38 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
public Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI url, String username, String password) throws DiscoveryException {
Map<CitrixResourceBase, Map<String, String>> resources = new HashMap<CitrixResourceBase, Map<String, String>>();
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);
return null;
}
try {
String cluster = null;
if (clusterId == null) {
String msg = "must specify cluster Id when add host";
s_logger.debug(msg);
throw new RuntimeException(msg);
} else {
cluster = Long.toString(clusterId);
}
String pod;
if (podId == null) {
String msg = "must specify pod Id when add host";
s_logger.debug(msg);
throw new RuntimeException(msg);
} else {
pod = Long.toString(podId);
}
try {
String poolUuid = null;
List<HostVO> eHosts = _hostDao.listByCluster(clusterId);
if( eHosts.size() > 0 ) {
HostVO eHost = eHosts.get(0);
_hostDao.loadDetails(eHost);
poolUuid = eHost.getDetail("pool");
}
String hostname = url.getHost();
InetAddress ia = InetAddress.getByName(hostname);
String addr = ia.getHostAddress();
@ -123,26 +147,14 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
s_logger.debug(msg);
return null;
}
String pod;
if (podId == null) {
Map<Pool, Pool.Record> pools = Pool.getAllRecords(conn);
assert pools.size() == 1 : "Pools are not one....where on earth have i been? " + pools.size();
pod = pools.values().iterator().next().uuid;
} else {
pod = Long.toString(podId);
if( poolUuid == null ) {
Set<Pool> pools = Pool.getAll(conn);
Pool pool = pools.iterator().next();
Pool.Record pr = pool.getRecord(conn);
poolUuid = pr.uuid;
}
String cluster = null;
if (clusterId != null) {
cluster = Long.toString(clusterId);
}
Set<Pool> pools = Pool.getAll(conn);
Pool pool = pools.iterator().next();
Pool.Record pr = pool.getRecord(conn);
String poolUuid = pr.uuid;
Map<Host, Host.Record> hosts = Host.getAllRecords(conn);
Host master = pr.master;
if (_checkHvm) {
for (Map.Entry<Host, Host.Record> entry : hosts.entrySet()) {
@ -195,6 +207,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
params.put("zone", Long.toString(dcId));
params.put("guid", record.uuid);
params.put("pod", pod);
params.put("cluster", cluster);
if (_increase != null) {
params.put(Config.XenPreallocatedLunSizeRange.name(), _increase);
@ -402,6 +415,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
throw new DiscoveryException("Unable to join the pool");
}
return true;
}

View File

@ -684,7 +684,7 @@ public class ManagementServerImpl implements ManagementServer {
throw new InvalidParameterValueException("Unable to find host with ID: " + hostId + ". Please specify a valid host ID.");
}
if (_hostDao.countBy(host.getPodId(), Status.PrepareForMaintenance, Status.ErrorInMaintenance, Status.Maintenance) > 0) {
if (_hostDao.countBy(host.getClusterId(), Status.PrepareForMaintenance, Status.ErrorInMaintenance, Status.Maintenance) > 0) {
throw new InvalidParameterValueException("There are other servers in maintenance mode.");
}