|
117 | 117 | import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase; |
118 | 118 | import com.cloud.network.IPAddressVO; |
119 | 119 | import com.cloud.network.dao.IPAddressDao; |
| 120 | +import com.cloud.resource.ResourceManager; |
| 121 | +import com.cloud.resource.ResourceState; |
120 | 122 | import com.cloud.resource.ServerResource; |
121 | 123 | import com.cloud.service.ServiceOfferingVO; |
122 | 124 | import com.cloud.storage.Storage; |
|
147 | 149 | import com.cloud.utils.db.Transaction; |
148 | 150 | import com.cloud.utils.exception.CloudRuntimeException; |
149 | 151 | import com.cloud.utils.exception.HypervisorVersionChangedException; |
| 152 | +import com.cloud.utils.fsm.NoTransitionException; |
| 153 | +import com.cloud.utils.fsm.StateMachine2; |
150 | 154 | import com.cloud.utils.net.Ip; |
151 | 155 | import com.cloud.utils.net.NetUtils; |
152 | 156 | import com.cloud.utils.nio.HandlerFactory; |
@@ -255,6 +259,10 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { |
255 | 259 | protected AgentMonitor _monitor = null; |
256 | 260 |
|
257 | 261 | protected ExecutorService _executor; |
| 262 | + |
| 263 | + protected StateMachine2<Status, Status.Event, Host> _statusStateMachine = Status.getStateMachine(); |
| 264 | + |
| 265 | + @Inject ResourceManager _resourceMgr; |
258 | 266 |
|
259 | 267 | @Override |
260 | 268 | public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException { |
@@ -1275,82 +1283,41 @@ protected boolean loadDirectlyConnectedHost(HostVO host, boolean forRebalance) { |
1275 | 1283 | } |
1276 | 1284 |
|
1277 | 1285 | if (forRebalance) { |
1278 | | - AgentAttache attache = simulateStart(host.getId(), resource, host.getDetails(), false, null, null, true); |
1279 | | - if (attache == null) { |
1280 | | - return false; |
1281 | | - } else { |
1282 | | - return true; |
1283 | | - } |
| 1286 | + Host h = _resourceMgr.createHostAndAgent(host.getId(), resource, host.getDetails(), false, null, null, true); |
| 1287 | + return (h == null ? false : true); |
1284 | 1288 | } else { |
1285 | 1289 | _executor.execute(new SimulateStartTask(host.getId(), resource, host.getDetails(), null)); |
1286 | 1290 | return true; |
1287 | 1291 | } |
1288 | 1292 | } |
1289 | 1293 |
|
1290 | 1294 | @Override |
1291 | | - public AgentAttache simulateStart(Long id, ServerResource resource, Map<String, String> details, boolean old, List<String> hostTags, String allocationState, boolean forRebalance) throws IllegalArgumentException { |
1292 | | - HostVO host = null; |
1293 | | - if (id != null) { |
1294 | | - synchronized (_loadingAgents) { |
1295 | | - s_logger.debug("Adding to loading agents " + id); |
1296 | | - _loadingAgents.add(id); |
1297 | | - } |
| 1295 | + public AgentAttache createAttacheForDirectConnect(HostVO host, StartupCommand[] cmds, ServerResource resource, boolean forRebalance) |
| 1296 | + throws ConnectionException { |
| 1297 | + if (resource instanceof DummySecondaryStorageResource || resource instanceof KvmDummyResourceBase) { |
| 1298 | + return new DummyAttache(this, host.getId(), false); |
| 1299 | + } |
| 1300 | + |
| 1301 | + s_logger.debug("create DirectAgentAttache for " + host.getId()); |
| 1302 | + DirectAgentAttache attache = new DirectAgentAttache(this, host.getId(), resource, host.isInMaintenanceStates(), this); |
| 1303 | + |
| 1304 | + AgentAttache old = null; |
| 1305 | + synchronized (_agents) { |
| 1306 | + old = _agents.put(host.getId(), attache); |
| 1307 | + } |
| 1308 | + if (old != null) { |
| 1309 | + old.disconnect(Status.Removed); |
1298 | 1310 | } |
1299 | | - AgentAttache attache = null; |
1300 | | - StartupCommand[] cmds = null; |
1301 | | - try { |
1302 | | - if (id != null) { |
1303 | | - host = _hostDao.findById(id); |
1304 | | - if (!_hostDao.directConnect(host, _nodeId)) { |
1305 | | - s_logger.info("MS " + host.getManagementServerId() + " is loading " + host); |
1306 | | - return null; |
1307 | | - } |
1308 | | - } |
1309 | | - |
1310 | | - cmds = resource.initialize(); |
1311 | | - if (cmds == null) { |
1312 | | - s_logger.info("Unable to fully initialize the agent because no StartupCommands are returned"); |
1313 | | - return null; |
1314 | | - } |
1315 | | - |
1316 | | - if (host != null) { |
1317 | | - if (!_hostDao.directConnect(host, _nodeId)) { |
1318 | | - host = _hostDao.findById(id); |
1319 | | - s_logger.info("MS " + host.getManagementServerId() + " is loading " + host + " after it has been initialized."); |
1320 | | - return null; |
1321 | | - } |
1322 | | - } |
1323 | | - |
1324 | | - if (s_logger.isDebugEnabled()) { |
1325 | | - new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true); |
1326 | | - } |
1327 | | - try { |
1328 | | - attache = handleDirectConnect(resource, cmds, details, old, hostTags, allocationState, forRebalance); |
1329 | | - } catch (IllegalArgumentException ex) { |
1330 | | - s_logger.warn("Unable to connect due to ", ex); |
1331 | | - throw ex; |
1332 | | - } catch (Exception e) { |
1333 | | - s_logger.warn("Unable to connect due to ", e); |
1334 | | - } |
1335 | 1311 |
|
1336 | | - } finally { |
1337 | | - if (id != null) { |
1338 | | - synchronized (_loadingAgents) { |
1339 | | - _loadingAgents.remove(id); |
1340 | | - } |
1341 | | - } |
1342 | | - if (attache == null) { |
1343 | | - if (cmds != null) { |
1344 | | - resource.disconnected(); |
1345 | | - } |
1346 | | - if (host != null) { |
1347 | | - _hostDao.updateStatus(host, Event.AgentDisconnected, _nodeId); |
1348 | | - } |
1349 | | - } |
| 1312 | + StartupAnswer[] answers = new StartupAnswer[cmds.length]; |
| 1313 | + for (int i = 0; i < answers.length; i++) { |
| 1314 | + answers[i] = new StartupAnswer(cmds[i], attache.getId(), _pingInterval); |
1350 | 1315 | } |
1351 | | - return attache; |
1352 | | - } |
| 1316 | + attache.process(answers); |
1353 | 1317 |
|
| 1318 | + return notifyMonitorsOfConnection(attache, cmds, forRebalance); |
| 1319 | + } |
| 1320 | + |
1354 | 1321 | @Override |
1355 | 1322 | public boolean stop() { |
1356 | 1323 | if (_monitor != null) { |
@@ -1758,26 +1725,6 @@ public void checkIPConflicts(Host.Type type, HostPodVO pod, DataCenterVO dc, Str |
1758 | 1725 | } |
1759 | 1726 | } |
1760 | 1727 |
|
1761 | | - @Override |
1762 | | - public Host addHost(long zoneId, ServerResource resource, Type hostType, Map<String, String> hostDetails) { |
1763 | | - // Check if the zone exists in the system |
1764 | | - if (_dcDao.findById(zoneId) == null) { |
1765 | | - throw new InvalidParameterValueException("Can't find zone with id " + zoneId); |
1766 | | - } |
1767 | | - |
1768 | | - Map<String, String> details = hostDetails; |
1769 | | - String guid = details.get("guid"); |
1770 | | - List<HostVO> currentHosts = _hostDao.listBy(hostType, zoneId); |
1771 | | - for (HostVO currentHost : currentHosts) { |
1772 | | - if (currentHost.getGuid().equals(guid)) { |
1773 | | - return currentHost; |
1774 | | - } |
1775 | | - } |
1776 | | - |
1777 | | - AgentAttache attache = simulateStart(null, resource, hostDetails, true, null, null, false); |
1778 | | - return _hostDao.findById(attache.getId()); |
1779 | | - } |
1780 | | - |
1781 | 1728 | public HostVO createHost(final StartupCommand startup, ServerResource resource, Map<String, String> details, boolean directFirst, List<String> hostTags, String allocationState) |
1782 | 1729 | throws IllegalArgumentException { |
1783 | 1730 | Host.Type type = null; |
@@ -2207,7 +2154,8 @@ public void run() { |
2207 | 2154 | if (s_logger.isDebugEnabled()) { |
2208 | 2155 | s_logger.debug("Simulating start for resource " + resource.getName() + " id " + id); |
2209 | 2156 | } |
2210 | | - simulateStart(id, resource, details, false, null, null, false); |
| 2157 | + |
| 2158 | + _resourceMgr.createHostAndAgent(id, resource, details, false, null, null, false); |
2211 | 2159 | } catch (Exception e) { |
2212 | 2160 | s_logger.warn("Unable to simulate start on resource " + id + " name " + resource.getName(), e); |
2213 | 2161 | } finally { |
@@ -2447,4 +2395,60 @@ protected void doTask(final Task task) throws Exception { |
2447 | 2395 | protected AgentManagerImpl() { |
2448 | 2396 | } |
2449 | 2397 |
|
| 2398 | + @Override |
| 2399 | + public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { |
| 2400 | + synchronized (_loadingAgents) { |
| 2401 | + if (action == TapAgentsAction.Add) { |
| 2402 | + _loadingAgents.add(hostId); |
| 2403 | + } else if (action == TapAgentsAction.Del) { |
| 2404 | + _loadingAgents.remove(hostId); |
| 2405 | + } else if (action == TapAgentsAction.Contains) { |
| 2406 | + return _loadingAgents.contains(hostId); |
| 2407 | + } else { |
| 2408 | + throw new CloudRuntimeException("Unkonwn TapAgentsAction " + action); |
| 2409 | + } |
| 2410 | + } |
| 2411 | + return true; |
| 2412 | + } |
| 2413 | + |
| 2414 | + private boolean isAgentEventAllowedByResourceState(HostVO host, Status.Event event) { |
| 2415 | + ResourceState state = host.getResourceState(); |
| 2416 | + boolean allow = true; |
| 2417 | + if (state == ResourceState.Enabled) { |
| 2418 | + |
| 2419 | + } else if (state == ResourceState.Disabled) { |
| 2420 | + if (event == Status.Event.AgentConnected) { |
| 2421 | + allow = false; |
| 2422 | + } |
| 2423 | + } else if (state == ResourceState.Unmanaged) { |
| 2424 | + if (event == Status.Event.AgentConnected) { |
| 2425 | + allow = false; |
| 2426 | + } |
| 2427 | + } else if (state == ResourceState.PrepareForMaintenace) { |
| 2428 | + |
| 2429 | + } else if (state == ResourceState.Maintenance) { |
| 2430 | + |
| 2431 | + } else { |
| 2432 | + throw new CloudRuntimeException("Unknown resource state " + state); |
| 2433 | + } |
| 2434 | + |
| 2435 | + return allow; |
| 2436 | + } |
| 2437 | + |
| 2438 | + @Override |
| 2439 | + public boolean agentStatusTransitTo(HostVO host, Status.Event e, long msId) { |
| 2440 | + if (!isAgentEventAllowedByResourceState(host, e)) { |
| 2441 | + s_logger.debug(String.format("Cannot proceed agent event %1$s because it is not allowed by current resource state %2$s fort host %3$s", e, host.getResourceState(), host.getId())); |
| 2442 | + return false; |
| 2443 | + } |
| 2444 | + |
| 2445 | + host.setManagementServerId(msId); |
| 2446 | + try { |
| 2447 | + return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao); |
| 2448 | + } catch (NoTransitionException e1) { |
| 2449 | + s_logger.debug("Cannot transit agent status with event " + e + " for host " + host.getId() + ", mangement server id is " + msId); |
| 2450 | + throw new CloudRuntimeException("Cannot transit agent status with event " + e + " for host " + host.getId() + ", mangement server id is " + msId + "," + e1.getMessage()); |
| 2451 | + } |
| 2452 | + } |
| 2453 | + |
2450 | 2454 | } |
0 commit comments