//when the task before starting, //it should check task.data() to determin //what it will do, whether copy config? //whether start fileserver? // //task.data() here format is : //<isInitialMonNode>.<TaskType> void CephExecutor::launchTask(ExecutorDriver* driver, const TaskInfo& task) { //set class member localSharedConfDirRoot string cmd = "echo ~"; string r = runShellCommand(cmd); localSharedConfigDirRoot = r == " " ? r :"/root"; LOG(INFO) << "localSharedConfigDirRoot is " << localSharedConfigDirRoot; bool needCopyConfig = true; bool needStartFileServer = false; int taskType; if (task.has_data()){ LOG(INFO) << "Got TaskInfo data: " << task.data(); vector<string> tokens = StringUtil::explode(task.data(),'.'); //split by '.', the first part is isInitialMonNode, //second part is used for task type if (tokens[0] == "1"){ needCopyConfig = false; } taskType = lexical_cast<int>(tokens[1]); } string localMountDir = localSharedConfigDirRoot + "/" +localConfigDirName; TaskStatus status; status.mutable_task_id()->MergeFrom(task.task_id()); //make local shared dir, all type of task need this: //TODO: check if already exists valid dirctory tree if (!createLocalSharedConfigDir(localConfigDirName)) { LOG(INFO) << "created local shared directory failed!"; status.set_state(TASK_FAILED); driver->sendStatusUpdate(status); return; } LOG(INFO) << "Create directory tree done."; //mount shared local dir if (needCopyConfig) { string abPath = localMountDir + "/" + "/etc/ceph/"; if (!copySharedConfigDir(abPath)) { LOG(INFO) << "Copy shared config file failed!"; status.set_state(TASK_FAILED); driver->sendStatusUpdate(status); return; } LOG(INFO) << "Copy config files done."; } //run docker command for MON and RADOSGW string cName = getContainerName(task.task_id().value()); //set class member containerName, and myTaskId //TODO: see if put these in registed is more proper containerName = cName; myTaskId = task.task_id(); //TODO: kill existing container in case conflict runShellCommand("docker rm -f " + containerName); string dockerCommand; switch (taskType) { case static_cast<int>(TaskType::MON): needStartFileServer = true; dockerCommand = constructMonCommand( localMountDir, cName); downloadDockerImage("ceph/mon"); break; case static_cast<int>(TaskType::OSD): downloadDockerImage("ceph/osd"); //Will get osdId in FrameworkMessage dockerCommand = ""; status.set_state(TASK_STARTING); driver->sendStatusUpdate(status); return; case static_cast<int>(TaskType::RADOSGW): downloadDockerImage("ceph/radosgw"); dockerCommand = constructRADOSGWCommand( localMountDir, cName); break; } if (needStartFileServer) { thread fileServerThread(fileServer, 7777, localSharedConfigDirRoot + "/" + localConfigDirName + "/etc/ceph/"); fileServerThread.detach(); LOG(INFO) << "Mon fileserver started"; } LOG(INFO) << "Stating container with command: "; LOG(INFO) << dockerCommand; //fork a thread to enable docker long running. //TODO: <thread> here seems not working, figure it out //to find a better way myPID = fork(); if (0 == myPID){ //child long running docker thread //TODO: we use fork here. Need to check why below line will hung the executor //thread(&CephExecutor::startLongRunning,*this,"docker", dockerCommand).detach(); startLongRunning("docker",dockerCommand); } else { //parent thread //check if started normally bool started = block_until_started(cName, "30"); if (started) { LOG(INFO) << "Starting task " << task.task_id().value(); status.set_state(TASK_RUNNING); } else { LOG(INFO) << "Failed to start task " << task.task_id().value(); status.set_state(TASK_FAILED); } driver->sendStatusUpdate(status); } }