// Reads `ProcessIO::Data` records from a string containing "Record-IO" // data encoded in protobuf messages, and returns the stdout and stderr. // // NOTE: This function ignores any `ProcessIO::Control` records. // // TODO(gkleiman): This function is very similar to one in `api_tests.cpp`, we // should refactor them into a common helper when fixing MESOS-7903. static Try<tuple<string, string>> decodeProcessIOData(const string& data) { string stdoutReceived; string stderrReceived; ::recordio::Decoder<v1::agent::ProcessIO> decoder( lambda::bind( deserialize<v1::agent::ProcessIO>, ContentType::PROTOBUF, lambda::_1)); Try<std::deque<Try<v1::agent::ProcessIO>>> records = decoder.decode(data); if (records.isError()) { return Error(records.error()); } while (!records->empty()) { Try<v1::agent::ProcessIO> record = records->front(); records->pop_front(); if (record.isError()) { return Error(record.error()); } if (record->data().type() == v1::agent::ProcessIO::Data::STDOUT) { stdoutReceived += record->data().data(); } else if (record->data().type() == v1::agent::ProcessIO::Data::STDERR) { stderrReceived += record->data().data(); } } return std::make_tuple(stdoutReceived, stderrReceived); }
Future<string> StoreProcess::_fetchImage(const Image::Appc& appc) { VLOG(1) << "Fetching image '" << appc.name() << "'"; Try<string> _tmpFetchDir = os::mkdtemp( path::join(paths::getStagingDir(rootDir), "XXXXXX")); if (_tmpFetchDir.isError()) { return Failure( "Failed to create temporary fetch directory for image '" + appc.name() + "': " + _tmpFetchDir.error()); } const string tmpFetchDir = _tmpFetchDir.get(); return fetcher->fetch(appc, Path(tmpFetchDir)) .then(defer(self(), [=]() -> Future<string> { Try<list<string>> imageIds = os::ls(tmpFetchDir); if (imageIds.isError()) { return Failure( "Failed to list images under '" + tmpFetchDir + "': " + imageIds.error()); } if (imageIds->size() != 1) { return Failure( "Unexpected number of images under '" + tmpFetchDir + "': " + stringify(imageIds->size())); } const string& imageId = imageIds->front(); const string source = path::join(tmpFetchDir, imageId); const string target = paths::getImagePath(rootDir, imageId); if (os::exists(target)) { LOG(WARNING) << "Image id '" << imageId << "' already exists in the store"; } else { Try<Nothing> rename = os::rename(source, target); if (rename.isError()) { return Failure( "Failed to rename directory '" + source + "' to '" + target + "': " + rename.error()); } } Try<Nothing> addCache = cache->add(imageId); if (addCache.isError()) { return Failure( "Failed to add image '" + appc.name() + "' with image id '" + imageId + "' to the cache: " + addCache.error()); } Try<Nothing> rmdir = os::rmdir(tmpFetchDir); if (rmdir.isError()) { return Failure( "Failed to remove temporary fetch directory '" + tmpFetchDir + "' for image '" + appc.name() + "': " + rmdir.error()); } return imageId; })); }