blob: cea30ca23bc4a1a2d4d582d246d8929f474d765d [file] [log] [blame]
// Copyright 2019 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.rewrite;
using zx;
/// A literal match and replacement rule.
///
/// # Examples
///
/// Replaces example.com with test.example.com for all packages
/// ```
/// {
/// host_match: "example.com"
/// host_replacement: "test.example.com"
/// path_prefix_match: "/"
/// path_prefix_replacement: "/"
/// }
/// ```
///
/// Replaces example.com with test.example.com for
/// fuchsia-pkg://example.com/rolldice. A package called "rolldice" in another
/// repo would not be rewritten.
/// ```
/// {
/// host_match: "example.com"
/// host_replacement: "test.example.com"
/// path_prefix_match: "/rolldice"
/// path_prefix_replacement: "/rolldice"
/// }
/// ```
///
/// Redirects all packages under "fuchsia-pkg://example.com/examples/" to
/// "fuchsia-pkg://example.com/examples/beta/".
/// ```
/// {
/// host_match: "example.com"
/// host_replacement: "example.com"
/// path_prefix_match: "/examples/"
/// path_prefix_replacement: "/examples/beta/"
/// }
/// ```
struct LiteralRule {
/// The exact hostname to match.
string host_match;
/// The new hostname to replace the matched `host_match` with.
string host_replacement;
/// The absolute path to a package or directory to match against.
///
/// If `path_prefix_match` ends with '/', it will match any packages or
/// subdirectories below the matched path.
/// If `path_prefix_match` does not end with '/', it will be interpreted as
/// as an exact match.
///
/// # Examples
///
/// "/example" only matches a package called "example" at the root of the
/// repo. "/parent/examples" and "/examples" would not match.
///
/// "/example/" would match any package under the "example" path at the root
/// of the repo. For example, "/example/", "/example/package" would both
/// match.
string path_prefix_match;
/// The absolute path to a single package or a directory to replace the
/// matched `path_prefix_match` with.
///
/// `path_prefix_match` and `path_prefix_replacement` must both match
/// directories or both match exact packages. Mixing the two forms is not
/// allowed.
string path_prefix_replacement;
};
/// A rewrite rule, represented as an xunion for future compatibility.
flexible union Rule {
1: LiteralRule literal;
};
/// Manages fuchsia-pkg:// rewrite rules.
///
/// When a package resolver is asked to resolve a fuchsia-pkg URL, it must first
/// iterate through its sequence of rewrite rules (given by [`List`]). The
/// rewrite engine will rewrite the given URL with the first rule that:
/// * matches the given URL
/// * produces a valid URL when applied to the given URL
/// If no rules match, the URL is resolved as-is.
///
/// This interface is intended to be implemented by package resolver components,
/// and used by repository administration tools.
[Discoverable]
protocol Engine {
/// Begins a rule edit transaction.
StartEditTransaction(request<EditTransaction> transaction);
/// Return an iterator over all rewrite rules.
///
/// + request `iterator` is a request for an iterator.
List(request<RuleIterator> iterator);
/// Return an iterator over all static (immutable) rewrite rules. These
/// rules are handled as lower priority than dynamic rules and cannot be
/// modified (although they can be overridden) by [`EditTransaction`]s.
///
/// + request `iterator` is a request for an iterator.
ListStatic(request<RuleIterator> iterator);
/// Rewrite the given `url` with the current rewrite rule set, returning the
/// `rewritten` url. If no rules match or a rule matches but performs an
/// identity transformation, this API returns `url` unchanged.
///
/// This API is intended only for reflecting on rule side effects. Using
/// this API to pre-apply the rules, then passing the result to
/// [`fuchsia.pkg/PackageResolver.Resolve`] would apply the rules twice.
///
/// + request `url` the url to rewrite.
/// - response `rewritten` the rewritten url.
/// * error `ZX_ERR_INVALID_ARGS` If `url` is not a valid `fuchsia-pkg://`
/// URL. See [`fuchsia-pkg URL`].
///
/// [`fuchsia-pkg URL`]:
/// https://fuchsia.dev/fuchsia-src/concepts/storage/package_url
TestApply(string url) -> (string rewritten) error zx.status;
};
protocol EditTransaction {
/// Return an iterator over all dynamic (editable) rewrite rules. The
/// iterator will reflect any changes made to the rewrite rules so far in
/// this transaction.
///
/// + request `iterator` is a request for an iterator.
ListDynamic(request<RuleIterator> iterator);
/// Removes all dynamically configured rewrite rules, leaving only any
/// statically configured rules.
ResetAll();
/// Add a rewrite rule with highest priority. If `rule` already exists, this
/// API will prioritize it over other rules.
///
/// + request `rule` the rewrite rule to persist.
///
/// * status `ZX_OK` if the rule was staged to be added.
/// * status `ZX_ERR_INVALID_ARGS` If `url` is not a valid `fuchsia-pkg://`
/// URL. See [`fuchsia-pkg URL`].
///
/// [`fuchsia-pkg URL`]:
/// https://fuchsia.dev/fuchsia-src/concepts/storage/package_url
Add(Rule rule) -> (zx.status status);
/// Commit this transaction, or detect another transaction that committed
/// before this one.
///
/// * status `ZX_OK` the staged edits were successfully committed.
/// * status `ZX_ERR_UNAVAILABLE` another transaction committed before this one.
/// * status `ZX_ERR_ACCESS_DENIED` editing dynamic rewrite rules is permanently disabled.
Commit() -> (zx.status status);
};
/// The iterator over all the rewrite rules defined in a [`Engine`].
protocol RuleIterator {
/// Advance the iterator and return the next batch of rules.
///
/// - response `rules` a vector of [`Rule`] rules. Will return an empty
/// vector when there are no more rules.
Next() -> (vector<Rule> rules);
};