// Returns the resulting file or in case of extraction the destination // directory (for logging). static Try<string> fetchFromCache( const FetcherInfo::Item& item, const string& cacheDirectory, const string& sandboxDirectory) { LOG(INFO) << "Fetching from cache"; if (item.uri().has_output_file()) { string dirname = Path(item.uri().output_file()).dirname(); if (dirname != ".") { Try<Nothing> result = os::mkdir(path::join(sandboxDirectory, dirname), true); if (result.isError()) { return Error( "Unable to create subdirectory " + dirname + "in sandbox"); } } } Try<string> outputFile = item.uri().has_output_file() ? item.uri().output_file() : Fetcher::basename(item.uri().value()); if (outputFile.isError()) { return Error(outputFile.error()); } string destinationPath = path::join(sandboxDirectory, outputFile.get()); // Non-empty cache filename is guaranteed by the callers of this function. CHECK(!item.cache_filename().empty()); string sourcePath = path::join(cacheDirectory, item.cache_filename()); if (item.uri().executable()) { Try<string> copied = copyFile(sourcePath, destinationPath); if (copied.isError()) { return Error(copied.error()); } return chmodExecutable(copied.get()); } else if (item.uri().extract()) { Try<bool> extracted = extract(sourcePath, sandboxDirectory); if (extracted.isError()) { return Error(extracted.error()); } else if (extracted.get()) { return sandboxDirectory; } else { LOG(WARNING) << "Copying instead of extracting resource from URI with " << "'extract' flag, because it does not seem to be an " << "archive: " << item.uri().value(); } } return copyFile(sourcePath, destinationPath); }
// Returns the resulting file or in case of extraction the destination // directory (for logging). static Try<string> fetchFromCache( const FetcherInfo::Item& item, const string& cacheDirectory, const string& sandboxDirectory) { LOG(INFO) << "Fetching from cache"; Try<string> basename = Fetcher::basename(item.uri().value()); if (basename.isError()) { return Error(basename.error()); } string destinationPath = path::join(sandboxDirectory, basename.get()); // Non-empty cache filename is guaranteed by the callers of this function. CHECK(!item.cache_filename().empty()); string sourcePath = path::join(cacheDirectory, item.cache_filename()); if (item.uri().executable()) { Try<string> copied = copyFile(sourcePath, destinationPath); if (copied.isError()) { return Error(copied.error()); } return chmodExecutable(copied.get()); } else if (item.uri().extract()) { Try<bool> extracted = extract(sourcePath, sandboxDirectory); if (extracted.isError()) { return Error(extracted.error()); } else if (extracted.get()) { return sandboxDirectory; } else { LOG(WARNING) << "Copying instead of extracting resource from URI with " << "'extract' flag, because it does not seem to be an " << "archive: " << item.uri().value(); } } return copyFile(sourcePath, destinationPath); }
// Returns the resulting file or in case of extraction the destination // directory (for logging). static Try<string> fetch( const FetcherInfo::Item& item, const Option<string>& cacheDirectory, const string& sandboxDirectory, const Option<string>& frameworksHome) { LOG(INFO) << "Fetching URI '" << item.uri().value() << "'"; if (item.action() == FetcherInfo::Item::BYPASS_CACHE) { return fetchBypassingCache( item.uri(), sandboxDirectory, frameworksHome); } return fetchThroughCache( item, cacheDirectory, sandboxDirectory, frameworksHome); }
// Returns the resulting file or in case of extraction the destination // directory (for logging). static Try<string> fetchThroughCache( const FetcherInfo::Item& item, const Option<string>& cacheDirectory, const string& sandboxDirectory, const Option<string>& frameworksHome) { if (cacheDirectory.isNone() || cacheDirectory.get().empty()) { return Error("Cache directory not specified"); } if (!item.has_cache_filename() || item.cache_filename().empty()) { // This should never happen if this program is used by the Mesos // slave and could then be a CHECK. But other uses are possible. return Error("No cache file name for: " + item.uri().value()); } CHECK_NE(FetcherInfo::Item::BYPASS_CACHE, item.action()) << "Unexpected fetcher action selector"; if (item.action() == FetcherInfo::Item::DOWNLOAD_AND_CACHE) { LOG(INFO) << "Downloading into cache"; Try<Nothing> mkdir = os::mkdir(cacheDirectory.get()); if (mkdir.isError()) { return Error("Failed to create fetcher cache directory '" + cacheDirectory.get() + "': " + mkdir.error()); } Try<string> downloaded = download( item.uri().value(), path::join(cacheDirectory.get(), item.cache_filename()), frameworksHome); if (downloaded.isError()) { return Error(downloaded.error()); } } return fetchFromCache(item, cacheDirectory.get(), sandboxDirectory); }