Image::Appc getTestImage() const { Image::Appc appc; appc.set_name("foo.com/bar"); Label version; version.set_key("version"); version.set_value("1.0.0"); Label arch; arch.set_key("arch"); arch.set_value("amd64"); Label os; os.set_key("os"); os.set_value("linux"); Labels labels; labels.add_labels()->CopyFrom(version); labels.add_labels()->CopyFrom(arch); labels.add_labels()->CopyFrom(os); appc.mutable_labels()->CopyFrom(labels); return appc; }
Future<vector<string>> StoreProcess::fetchDependencies( const string& imageId, bool cached) { const string imagePath = paths::getImagePath(rootDir, imageId); Try<spec::ImageManifest> manifest = spec::getManifest(imagePath); if (manifest.isError()) { return Failure( "Failed to get dependencies for image id '" + imageId + "': " + manifest.error()); } vector<Image::Appc> dependencies; foreach (const spec::ImageManifest::Dependency& dependency, manifest->dependencies()) { Image::Appc appc; appc.set_name(dependency.imagename()); if (dependency.has_imageid()) { appc.set_id(dependency.imageid()); } // TODO(jojy): Make Image::Appc use appc::spec::Label instead of // mesos::Label so that we can avoid this loop here. foreach (const spec::ImageManifest::Label& label, dependency.labels()) { mesos::Label appcLabel; appcLabel.set_key(label.name()); appcLabel.set_value(label.value()); appc.mutable_labels()->add_labels()->CopyFrom(appcLabel); } dependencies.emplace_back(appc); } if (dependencies.size() == 0) { return vector<string>(); } // Do a depth first search. vector<Future<vector<string>>> futures; futures.reserve(dependencies.size()); foreach (const Image::Appc& appc, dependencies) { futures.emplace_back(fetchImage(appc, cached)); }
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; })); }