| 3951 | |
| 3952 | |
| 3953 | Future<Response> Master::Http::_reactivateAgent( |
| 3954 | const SlaveID& slaveId, |
| 3955 | const Owned<ObjectApprovers>& approvers) const |
| 3956 | { |
| 3957 | if (!approvers->approved<REACTIVATE_AGENT>()) { |
| 3958 | return Forbidden(); |
| 3959 | } |
| 3960 | |
| 3961 | // Check that the agent is deactivated. |
| 3962 | if (!master->slaves.deactivated.contains(slaveId)) { |
| 3963 | return BadRequest("Agent is not deactivated"); |
| 3964 | } |
| 3965 | |
| 3966 | if (master->slaves.draining.contains(slaveId) && |
| 3967 | master->slaves.draining.at(slaveId).state() == DRAINING) { |
| 3968 | return BadRequest("Agent is still in the DRAINING state"); |
| 3969 | } |
| 3970 | |
| 3971 | // Save the reactivation to the registry. |
| 3972 | return master->registrar->apply(Owned<RegistryOperation>( |
| 3973 | new ReactivateAgent(slaveId))) |
| 3974 | .onAny([](const Future<bool>& result) { |
| 3975 | CHECK_READY(result) |
| 3976 | << "Failed to reactivate agent in the registry"; |
| 3977 | }) |
| 3978 | .then(defer(master->self(), [this, slaveId](bool result) -> Response { |
| 3979 | // Reactivate the agent. |
| 3980 | master->slaves.draining.erase(slaveId); |
| 3981 | master->slaves.deactivated.erase(slaveId); |
| 3982 | |
| 3983 | Slave* slave = master->slaves.registered.get(slaveId); |
| 3984 | if (slave == nullptr) { |
| 3985 | return Conflict("Agent removed while processing the call"); |
| 3986 | } |
| 3987 | |
| 3988 | if (slave->connected) { |
| 3989 | LOG(INFO) << "Reactivating agent " << *slave; |
| 3990 | |
| 3991 | slave->active = true; |
| 3992 | master->allocator->activateSlave(slaveId); |
| 3993 | } else { |
| 3994 | LOG(INFO) << "Disconnected agent " << *slave |
| 3995 | << " will be reactivated upon reregistration."; |
| 3996 | } |
| 3997 | |
| 3998 | slave->estimatedDrainStartTime = None(); |
| 3999 | |
| 4000 | return OK(); |
| 4001 | })); |
| 4002 | } |
| 4003 | |
| 4004 | |
| 4005 | Future<Response> Master::Http::reactivateAgent( |