blob: 9296e723fc6c06e68c7ace951d4e4ecfb0359db5 [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"
/// }
/// ```
type LiteralRule = struct {
/// The exact hostname to match.
host_match string;
/// The new hostname to replace the matched `host_match` with.
host_replacement string;
/// 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.
path_prefix_match string;
/// 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.
path_prefix_replacement string;
};
/// A rewrite rule, represented as an xunion for future compatibility.
type Rule = flexible union {
1: literal LiteralRule;
};
/// This 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 is intended to be implemented by package resolver components,
/// and used by repository administration tools.
@discoverable
closed protocol Engine {
/// Begins a rule edit transaction.
///
/// + request `transaction` a request for an [`EditTransaction`].
strict StartEditTransaction(resource struct {
transaction server_end:EditTransaction;
});
/// Returns an iterator over all rewrite rules.
///
/// + request `iterator` a request for an iterator.
strict List(resource struct {
iterator server_end:RuleIterator;
});
/// Returns 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` a request for an iterator.
strict ListStatic(resource struct {
iterator server_end:RuleIterator;
});
/// Rewrites 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 a zx_status value indicating failure. One of the following:
/// * `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
strict TestApply(struct {
url string;
}) -> (struct {
rewritten string;
}) error zx.Status;
};
/// A unit of editing for rewrite rules.
closed protocol EditTransaction {
/// Returns 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` a request for an iterator.
strict ListDynamic(resource struct {
iterator server_end:RuleIterator;
});
/// Removes all dynamically configured rewrite rules, leaving only any
/// statically configured rules.
strict ResetAll();
/// Adds 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.
/// * error a zx_status value indicating failure. One of the following:
/// * `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
strict Add(struct {
rule Rule;
}) -> () error zx.Status;
/// Commits this transaction, or detect another transaction that committed
/// before this one.
///
/// * error a zx_status value indicating failure. One of the following:
/// * `ZX_ERR_UNAVAILABLE` if another transaction committed before this one.
/// * `ZX_ERR_ACCESS_DENIED` if editing dynamic rewrite rules is permanently disabled.
strict Commit() -> () error zx.Status;
};
/// The iterator over all the rewrite rules defined in a [`Engine`].
closed protocol RuleIterator {
/// Advances the iterator and returns the next batch of rules.
///
/// - response `rules` a vector of [`Rule`] rules. Will return an empty
/// vector and then close the channel when there are no more rules.
strict Next() -> (struct {
rules vector<Rule>;
});
};