예제 #1
0
// 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);
}
예제 #2
0
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;
    }));
}