blob: 7766fff1995f00bad573d000526beed0061c9e28 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
failure::Error,
fidl::endpoints::ServerEnd,
fidl_fuchsia_io::{self, DirectoryMarker, DirectoryProxy},
fidl_fuchsia_pkg::{NeededBlobsMarker, PackageCacheRequest, PackageCacheRequestStream},
fidl_fuchsia_pkg_ext::{BlobId, BlobInfo},
fuchsia_syslog::{fx_log_err, fx_log_info, fx_log_warn},
fuchsia_zircon::Status,
futures::prelude::*,
};
pub async fn serve(
pkgfs: DirectoryProxy,
mut stream: PackageCacheRequestStream,
) -> Result<(), Error> {
while let Some(event) = await!(stream.try_next())? {
match event {
PackageCacheRequest::Get { meta_far_blob, selectors, needed_blobs, dir, responder } => {
let status =
await!(get(&pkgfs, meta_far_blob.into(), selectors, needed_blobs, dir));
responder.send(Status::from(status).into_raw())?;
}
PackageCacheRequest::Open { meta_far_blob_id, selectors, dir, responder } => {
let status = await!(open(&pkgfs, meta_far_blob_id.into(), selectors, dir));
responder.send(Status::from(status).into_raw())?;
}
}
}
Ok(())
}
/// Fetch a package, and optionally mount it.
///
/// TODO: implement this method. This stub can't simply proxy to amber for now, since it doesn't
/// know the name of the package, and amber needs it to lookup the package in its TUF repo.
async fn get<'a>(
pkgfs: &'a DirectoryProxy,
meta_far_blob: BlobInfo,
selectors: Vec<String>,
_needed_blobs: ServerEnd<NeededBlobsMarker>,
dir_request: Option<ServerEnd<DirectoryMarker>>,
) -> Result<(), Status> {
fx_log_info!("fetching {:?} with the selectors {:?}", meta_far_blob, selectors);
if let Some(dir_request) = dir_request {
await!(open(pkgfs, meta_far_blob.blob_id, selectors.clone(), dir_request))?;
Ok(())
} else {
Err(Status::NOT_SUPPORTED)
}
}
/// Open a package directory.
async fn open<'a>(
pkgfs: &'a DirectoryProxy,
meta_far_blob_id: BlobId,
selectors: Vec<String>,
dir_request: ServerEnd<DirectoryMarker>,
) -> Result<(), Status> {
// FIXME: need to implement selectors.
if !selectors.is_empty() {
fx_log_warn!("resolve does not support selectors yet");
}
// FIXME: this is a bit of a hack but there isn't a formal way to convert a Directory request
// into a Node request.
let node_request = ServerEnd::new(dir_request.into_channel());
let flags = fidl_fuchsia_io::OPEN_RIGHT_READABLE | fidl_fuchsia_io::OPEN_FLAG_DIRECTORY;
pkgfs.open(flags, 0, &meta_far_blob_id.to_string(), node_request).map_err(|err| {
fx_log_err!("error opening {}: {:?}", meta_far_blob_id, err);
Status::INTERNAL
})?;
Ok(())
}