blob: fc65e9c48c4c34b9410177595812e6b0ad96dc2c [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.
library fuchsia.pkg;
using fuchsia.io;
using zx;
/// This manages the system package cache.
///
/// This is intended to be implemented by the package manager component and used by
/// package resolver components.
[Discoverable]
protocol PackageCache {
/// Gets the package directory if it is present on the local system. If it is not, the
/// `missing_blobs` iterator will provide all the blobs in the package that are missing from
/// the system, and the ability to write those blobs to blobfs. If all the missing blobs are
/// downloaded and written to by the client, the `dir` directory will be resolved. This method
/// will return successfully when the package has been fully resolved, or return an error if
/// the client closes `needed_blobs` or `dir` handle before the package has been resolved.
///
/// This method does not guarantee the missing blobs have been persisted. In order to guarantee
/// missing blobs are persisted, clients should call ['Sync'].
///
/// + request `meta_far_blob` the blob info for the package's meta.far.
/// + request `selectors` the package selectors (TODO: link to docs).
/// + request `needed_blobs` an iterator over all the blobs in the package that
/// are not present on the system.
/// + request `dir` an optional request for a directory that will be resolved when the package
/// has been successfully cached.
/// * error a zx_status value indicating failure. One of the following:
/// * `ZX_ERR_UNAVAILABLE` if the client closed `needed_blobs` or `dir` handles before
/// all the missing blobs were downloaded to the system.
Get(
BlobInfo meta_far_blob,
vector<string> selectors,
request<NeededBlobs> needed_blobs,
request<fuchsia.io.Directory>? dir
) -> () error zx.status;
/// Opens the package, or errors out if it is not present on the local system.
///
/// + request `meta_far_blob_id` the blob id for the package's meta.far.
/// + request `selectors` the package selectors (TODO: link to docs).
/// + request `dir` a request for a directory that will be resolved when the package has been
/// successfully cached.
/// * error a zx_status value indicating failure. One of the following:
/// * `ZX_ERR_NOT_FOUND` if the package does not exist.
Open(
BlobId meta_far_blob_id,
vector<string> selectors,
request<fuchsia.io.Directory> dir
) -> () error zx.status;
/// Retrieves a chunk iterator to the base package index.
///
/// + request `iterator` a request for the `PackageIndexIterator` that will return sets of
/// `PackageIndexEntry` objects until all packages in the base index have been iterated.
BasePackageIndex(request<PackageIndexIterator> iterator);
/// Synchronizes updates to the cached packages to the underlying persistent storage.
///
/// * error a zx_status value indicating failure. One of the following:
/// * `ZX_ERR_INTERNAL` if the sync fails.
Sync() -> () error zx.status;
};
/// Error type for [`NeededBlobs.OpenMetaBlob`] and [`NeededBlobs.OpenBlob`].
enum OpenBlobError {
/// There is insufficient storage space available to persist this blob.
OUT_OF_SPACE = 1;
/// This blob is already open for write by another cache operation.
CONCURRENT_WRITE = 2;
/// An unspecified error occured during underlying I/O.
UNSPECIFIED_IO = 3;
/// An unspecified error occured.
INTERNAL = 4;
};
/// Represents the transaction for caching a particular package.
///
/// Clients should start by requesting to `OpenMetaBlob()`, and fetch and write
/// the metadata blob if needed. Once written, `GetMissingBlobs()` should be
/// used to determine which content blobs need fetched and written using
/// `OpenBlob()`. Violating the expected protocol state will result in the
/// channel being closed by the package cache with a `ZX_ERR_BAD_STATE` epitaph
/// and aborting the package cache operation.
///
/// Once all needed blobs are written by the client, the package cache will
/// complete the pending [`PackageCache.Get`] request and close this channel
/// with a `ZX_OK` epitaph.
protocol NeededBlobs {
/// Opens the package's metadata blob for writing. `GetMissingBlobs()`
/// should not be called until writing the meta blob or this request
/// responds with `false`.
///
/// + request `file` resolves to an opened writable file which must be
/// truncated to the correct size by the caller and then written from
/// start to finish (seeks are not supported). A corrupt blob is indicated
/// by a `Write()` (usually the final write) failing with
/// `ZX_ERR_IO_DATA_INTEGRITY`. On error or a response of `false`, `file`
/// will be closed by the server.
/// - response `needed` `true` if the blob is still needed and should be
/// written by the client. On `false`, the blob now exists, does not
/// need to be written by the client, and `file` will be closed.
/// * error an OpenBlobError indicating failure. Clients may retry this
/// request, though the server end may abort this cache operation on
/// errors it considers to be fatal.
OpenMetaBlob(request<fuchsia.io.File> file) -> (bool needed) error OpenBlobError;
/// Returns an iterator of blobs that are not present on the system that
/// must be written using the `OpenBlob` request before the package will be
/// fully cached.
///
/// A client should make this request no more than once per `NeededBlobs`
/// connection. Once all blobs yielded by this iterator are written, the
/// package open request will complete.
///
/// + request `iterator` a request for an iterator of [`BlobInfo`] of blobs
/// that the client should try to write.
GetMissingBlobs(request<BlobInfoIterator> iterator);
/// Opens a content blob for writing.
///
/// + request `blob_id` the blob id describing this blob.
/// + request `file` resolves to an opened writable file which must be
/// truncated to the correct size by the caller and then written from
/// start to finish (seeks are not supported). A corrupt blob is indicated
/// by a `Write()` (usually the final write) failing with
/// `ZX_ERR_IO_DATA_INTEGRITY`. On error or a response of `false`, `file`
/// will be closed by the server.
/// - response `needed` `true` if the blob is still needed and should be
/// written by the client. On `false`, the blob now exists, does not
/// need to be written by the client, and `file` will be closed.
/// * error an OpenBlobError indicating failure. Clients may retry this
/// request, though the server end may abort this cache operation on
/// errors it considers to be fatal.
OpenBlob(
BlobId blob_id,
request<fuchsia.io.File> file
) -> (bool needed) error OpenBlobError;
/// Aborts this caching operation for the package.
///
/// Any open blobs and any missing blobs iterator will be closed. Any `dir`
/// provided to the associated [`PackageCache.Get`] request will also be
/// closed. Once this request is acknowledged, this channel will be closed.
///
/// Note, dropping this NeededBlobs channel without writing all needed blobs
/// will also abort the package cache operation. However, this API provides
/// the ability to wait for the operation to be torn down.
Abort() -> ();
};
/// A chunked iterator of [`BlobInfo`], allowing transfer of more [`BlobInfo`]s
/// that can fit in a single FIDL message.
protocol BlobInfoIterator {
/// Responds with the next chunk of [`BlobInfo`]s. When the iterator is
/// exhausted, responds with an empty vector and closes the connection.
///
/// - response `blobs` the next chunk of [`BlobInfo`]s.
Next() -> (vector<BlobInfo>:MAX blobs);
};
/// A chunk iterator for the package index. This is required because it is possible for the
/// package index to be too large to send over in a single request (over 64KiB).
protocol PackageIndexIterator {
/// Returns the next chunk of package index entries. When the iterator is exhausted,
/// this returns an empty vector.
///
/// - response `entries` the next chunk of entries in the package index.
Next() -> (vector<PackageIndexEntry>:MAX entries);
};
/// Manages the set of retained packages.
///
/// Retained packages will not be removed from the package cache, even if they
/// aren't fully present. There is only a single set active at once, and the
/// provided APIs for configuring the set atomically replace that set. On boot,
/// the retained package set is always initialized to the empty set.
[Discoverable]
protocol RetainedPackages {
/// Atomically clear the retained package set, releasing any previously
/// retained packages.
Clear() -> ();
/// Atomically replace the retained package set with the package blob IDs
/// provided by the given iterator.
///
/// + request `iterator` an iterator of package blob IDs that should be
/// retained.
Replace(BlobIdIterator iterator) -> ();
};
/// A chunked iterator of blob IDs, allowing transfer of more blob IDs that can
/// fit in a single FIDL message.
protocol BlobIdIterator {
/// Responds with the next chunk of blob IDs. When the iterator is
/// exhausted, responds with an empty vector and closes the connection.
///
/// - response `blobs` the next chunk of blob IDs.
Next() -> (vector<BlobId>:MAX blobs);
};