void CephSchedulerAgent<T>::resourceOffers( T* driver, const vector<Offer>& offers) { LOG(INFO) << "Received " << offers.size() << " offers! "; TaskType taskType; int token; int isInitialMonNode = 0; //handle waiting OSD task, give them osdID to start docker handleWaitingOSDTasks(driver); Phase currentPhase = stateMachine->getCurrentPhase(); //try start new node foreach (const Offer& offer, offers) { //check offer with the correct role LOG(INFO) << "Hostname: " << offer.hostname(); if (!hasRole(offer, config->role)) { LOG(INFO) << "Decline this offer. Host " << offer.hostname() << " don't have correct role:" << config->role; Filters refuse; refuse.set_refuse_seconds(86400.0); driver->declineOffer(offer.id(),refuse); continue; } //reload or new hostconfig stateMachine->addConfig(offer.hostname()); tryLaunchDiskTask(driver, offer, offer.hostname()); bool accept = stateMachine->nextMove(taskType,token,offer.hostname()); if (!accept) { LOG(INFO) << "In the " << static_cast<int>(currentPhase) << " Staging Phase, cannot accept offer from " << offer.hostname() << " in this phase"; driver->declineOffer(offer.id()); continue; } LOG(INFO) << "Check offer's resources from " <<offer.hostname(); if (offerNotEnoughResources(offer,taskType)) { LOG(INFO) << "Not enough, decline it from " << offer.hostname(); driver->declineOffer(offer.id()); continue; } if (currentPhase == Phase::WAINTING_REQUEST){ accept = fetchPendingRESTfulRequest(); if (!accept){ LOG(INFO) << "No pending OSD RESTful request."; driver->declineOffer(offer.id()); stateMachine->decreaseOSDIndex(); continue; } } LOG(INFO) << "Accepted offer from" << offer.hostname() << ", launch " << static_cast<int>(taskType) <<":" << token << " node"; if (taskType == TaskType::MON && token == 0) { LOG(INFO) << "This is the initial MON"; isInitialMonNode = 1; } string taskId; string executorId; launchNode( driver, offer, taskType, token, isInitialMonNode, taskId, executorId); stateMachine->addStagingTask( taskId, executorId, taskType, offer.hostname(), offer.slave_id().value()); if (!isInitialMonNode && taskType == TaskType::OSD) { ceph::TaskState initialMon = stateMachine->getInitialMon(); const string m = lexical_cast<string>(static_cast<int>(MessageToExecutor::REGISTER_OSD)); ExecutorID eId; eId.set_value(initialMon.executorId); SlaveID sId; sId.set_value(initialMon.slaveId); driver->sendFrameworkMessage( eId, sId, m); }//end if }//end foreach
inline bool operator==(const SlaveID& left, const SlaveID& right) { return left.value() == right.value(); }
inline std::size_t hash_value(const SlaveID& slaveId) { size_t seed = 0; boost::hash_combine(seed, slaveId.value()); return seed; }
inline bool operator==(const SlaveID& left, const std::string& right) { return left.value() == right; }
// This test ensures we don't break the API when it comes to JSON // representation of tasks. TEST(HTTPTest, ModelTask) { TaskID taskId; taskId.set_value("t"); SlaveID slaveId; slaveId.set_value("s"); ExecutorID executorId; executorId.set_value("t"); FrameworkID frameworkId; frameworkId.set_value("f"); TaskState state = TASK_RUNNING; vector<TaskStatus> statuses; TaskStatus status; status.mutable_task_id()->CopyFrom(taskId); status.set_state(state); status.mutable_slave_id()->CopyFrom(slaveId); status.mutable_executor_id()->CopyFrom(executorId); status.set_timestamp(0.0); statuses.push_back(status); Labels labels; labels.add_labels()->CopyFrom(createLabel("ACTION", "port:7987 DENY")); Ports ports; Port* port = ports.add_ports(); port->set_number(80); port->mutable_labels()->CopyFrom(labels); DiscoveryInfo discovery; discovery.set_visibility(DiscoveryInfo::CLUSTER); discovery.set_name("discover"); discovery.mutable_ports()->CopyFrom(ports); TaskInfo taskInfo; taskInfo.set_name("task"); taskInfo.mutable_task_id()->CopyFrom(taskId); taskInfo.mutable_slave_id()->CopyFrom(slaveId); taskInfo.mutable_command()->set_value("echo hello"); taskInfo.mutable_discovery()->CopyFrom(discovery); Task task = createTask(taskInfo, state, frameworkId); task.add_statuses()->CopyFrom(statuses[0]); JSON::Value object = model(task); Try<JSON::Value> expected = JSON::parse( "{" " \"executor_id\":\"\"," " \"framework_id\":\"f\"," " \"id\":\"t\"," " \"name\":\"task\"," " \"resources\":" " {" " \"cpus\":0," " \"disk\":0," " \"gpus\":0," " \"mem\":0" " }," " \"slave_id\":\"s\"," " \"state\":\"TASK_RUNNING\"," " \"statuses\":" " [" " {" " \"state\":\"TASK_RUNNING\"," " \"timestamp\":0" " }" " ]," " \"discovery\":" " {" " \"name\":\"discover\"," " \"ports\":" " {" " \"ports\":" " [" " {" " \"number\":80," " \"labels\":" " {" " \"labels\":" " [" " {" " \"key\":\"ACTION\"," " \"value\":\"port:7987 DENY\"" " }" " ]" " }" " }" " ]" " }," " \"visibility\":\"CLUSTER\"" " }" "}"); ASSERT_SOME(expected); EXPECT_EQ(expected.get(), object); }