@Override public boolean processAnswers(long agentId, long seq, Answer[] answers) { List<Long> affectedVms = new ArrayList<Long>(); int commandNum = 0; for (Answer ans : answers) { if (ans instanceof SecurityGroupRuleAnswer) { SecurityGroupRuleAnswer ruleAnswer = (SecurityGroupRuleAnswer) ans; if (ans.getResult()) { s_logger.debug( "Successfully programmed rule " + ruleAnswer.toString() + " into host " + agentId); _workDao.updateStep(ruleAnswer.getVmId(), ruleAnswer.getLogSequenceNumber(), Step.Done); recordSuccess(ruleAnswer.getVmId()); } else { _workDao.updateStep(ruleAnswer.getVmId(), ruleAnswer.getLogSequenceNumber(), Step.Error); ; s_logger.debug( "Failed to program rule " + ruleAnswer.toString() + " into host " + agentId + " due to " + ruleAnswer.getDetails() + " and updated jobs"); if (ruleAnswer.getReason() == FailureReason.CANNOT_BRIDGE_FIREWALL) { s_logger.debug( "Not retrying security group rules for vm " + ruleAnswer.getVmId() + " on failure since host " + agentId + " cannot do bridge firewalling"); } else if (ruleAnswer.getReason() == FailureReason.PROGRAMMING_FAILED) { if (checkShouldRetryOnFailure(ruleAnswer.getVmId())) { s_logger.debug( "Retrying security group rules on failure for vm " + ruleAnswer.getVmId()); affectedVms.add(ruleAnswer.getVmId()); } else { s_logger.debug( "Not retrying security group rules for vm " + ruleAnswer.getVmId() + " on failure: too many retries"); } } } commandNum++; if (_workTracker != null) _workTracker.processAnswers(agentId, seq, answers); } } if (affectedVms.size() > 0) { _securityGroupManager.scheduleRulesetUpdateToHosts(affectedVms, false, new Long(10 * 1000l)); } return true; }
@DB public void work() { if (s_logger.isTraceEnabled()) { s_logger.trace("Checking the database"); } final SecurityGroupWorkVO work = _workDao.take(_serverId); if (work == null) { if (s_logger.isTraceEnabled()) { s_logger.trace("Security Group work: no work found"); } return; } Long userVmId = work.getInstanceId(); if (work.getStep() == Step.Done) { if (s_logger.isDebugEnabled()) { s_logger.debug( "Security Group work: found a job in done state, rescheduling for vm: " + userVmId); } ArrayList<Long> affectedVms = new ArrayList<Long>(); affectedVms.add(userVmId); scheduleRulesetUpdateToHosts(affectedVms, false, _timeBetweenCleanups * 1000l); return; } UserVm vm = null; Long seqnum = null; s_logger.debug("Working on " + work); final Transaction txn = Transaction.currentTxn(); txn.start(); boolean locked = false; try { vm = _userVMDao.acquireInLockTable(work.getInstanceId()); if (vm == null) { vm = _userVMDao.findById(work.getInstanceId()); if (vm == null) { s_logger.info("VM " + work.getInstanceId() + " is removed"); locked = true; return; } s_logger.warn("Unable to acquire lock on vm id=" + userVmId); return; } locked = true; Long agentId = null; VmRulesetLogVO log = _rulesetLogDao.findByVmId(userVmId); if (log == null) { s_logger.warn("Cannot find log record for vm id=" + userVmId); return; } seqnum = log.getLogsequence(); if (vm != null && vm.getState() == State.Running) { Map<PortAndProto, Set<String>> rules = generateRulesForVM(userVmId); agentId = vm.getHostId(); if (agentId != null) { SecurityIngressRulesCmd cmd = generateRulesetCmd( vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), generateRulesetSignature(rules), seqnum, rules); Commands cmds = new Commands(cmd); try { _agentMgr.send(agentId, cmds, _answerListener); } catch (AgentUnavailableException e) { s_logger.debug( "Unable to send updates for vm: " + userVmId + "(agentid=" + agentId + ")"); _workDao.updateStep(work.getInstanceId(), seqnum, Step.Done); } } } } finally { if (locked) { _userVMDao.releaseFromLockTable(userVmId); _workDao.updateStep(work.getId(), Step.Done); } txn.commit(); } }