in nodemanager/core/RemoteExecutor.cpp [37:137]
pplx::task<json::value> RemoteExecutor::StartJobAndTask(StartJobAndTaskArgs&& args, std::string&& callbackUri)
{
{
WriterLock writerLock(&this->lock);
const auto& envi = args.StartInfo.EnvironmentVariables;
auto isAdminIt = envi.find("CCP_ISADMIN");
bool isAdmin = isAdminIt != envi.end() && isAdminIt->second == "1";
auto mapAdminUserIt = envi.find("CCP_MAP_ADMIN_USER");
bool mapAdminUser = mapAdminUserIt != envi.end() && mapAdminUserIt->second == "1";
const std::string WindowsSystemUser = "NT AUTHORITY\\SYSTEM";
bool mapAdminToRoot = isAdmin && !mapAdminUser;
bool mapAdminToUser = isAdmin && mapAdminUser;
bool isWindowsSystemAccount = boost::iequals(args.UserName, WindowsSystemUser);
std::string userName;
bool existed;
// Use root user in 3 scenarios:
// 1. This is old image, username is empty, we use root.
// 2. User is Windows or HPC Administrator and CCP_MAP_ADMIN_USER is not set
// 3. User is Windows local system account, which is mapped to Linux root user.
if (args.UserName.empty() || mapAdminToRoot || isWindowsSystemAccount)
{
userName = "root";
existed = true;
}
else
{
auto preserveDomainIt = envi.find("CCP_PRESERVE_DOMAIN");
bool preserveDomain = preserveDomainIt != envi.end() && preserveDomainIt->second == "1";
userName = preserveDomain ? args.UserName : String::GetUserName(args.UserName);
if (userName == "root") { userName = "hpc_faked_root"; }
int ret = System::CreateUser(userName, args.Password, isAdmin);
existed = ret == 9;
if (ret != 0 && ret != 9)
{
throw std::runtime_error(
String::Join(" ", "Create user", userName, "failed with error code", ret));
}
Logger::Debug(args.JobId, args.TaskId, this->UnknowId, "Create user {0} return code: {1}.", userName, ret);
}
bool privateKeyAdded = false;
bool publicKeyAdded = false;
bool authKeyAdded = false;
// Set SSH keys in 3 scenarios:
// 1. User is not a Windows or HPC Administrator.
// 2. User is Windows or HPC Administrator and it is mapped to non-root user in Linux.
// 3. User is Windows local system account, which is mapped to Linux root user.
if (!isAdmin || mapAdminToUser || isWindowsSystemAccount)
{
std::string privateKeyFile;
privateKeyAdded = 0 == System::AddSshKey(userName, args.PrivateKey, "id_rsa", "600", privateKeyFile);
if (privateKeyAdded && args.PublicKey.empty())
{
int ret = System::ExecuteCommandOut(args.PublicKey, "ssh-keygen -y -f ", privateKeyFile);
if (ret != 0)
{
Logger::Error(args.JobId, args.TaskId, this->UnknowId, "Retrieve public key failed with exitcode {0}.", ret);
}
}
std::string publicKeyFile;
publicKeyAdded = privateKeyAdded && (0 == System::AddSshKey(userName, args.PublicKey, "id_rsa.pub", "644", publicKeyFile));
std::string userAuthKeyFile;
authKeyAdded = privateKeyAdded && publicKeyAdded && (0 == System::AddAuthorizedKey(userName, args.PublicKey, "600", userAuthKeyFile));
Logger::Debug(args.JobId, args.TaskId, this->UnknowId,
"Add ssh key for user {0} result: private {1}, public {2}, auth {3}",
userName, privateKeyAdded, publicKeyAdded, authKeyAdded);
}
if (this->jobUsers.find(args.JobId) == this->jobUsers.end())
{
Logger::Debug(args.JobId, args.TaskId, this->UnknowId,
"Create user: jobUsers entry added.");
this->jobUsers[args.JobId] =
std::tuple<std::string, bool, bool, bool, bool, std::string>(userName, existed, privateKeyAdded, publicKeyAdded, authKeyAdded, args.PublicKey);
}
auto it = this->userJobs.find(userName);
if (it != this->userJobs.end())
{
it->second.insert(args.JobId);
}
else
{
this->userJobs[userName] = { args.JobId };
}
}
return this->StartTask(StartTaskArgs(args.JobId, args.TaskId, std::move(args.StartInfo)), std::move(callbackUri));
}