blob: 087b22f2cdd48e446c60b4cb81548a9f055ed86c [file] [log] [blame]
// Copyright 2022 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.sys2;
using fuchsia.io;
using fuchsia.component;
using fuchsia.component.decl;
using fuchsia.component.config;
using fuchsia.component.runner;
using fuchsia.url;
/// The maximum length of an instance ID.
/// An instance ID is a 256-bit identifier, which when encoded
/// in hex notation is 64 characters long.
const MAX_INSTANCE_ID_LENGTH uint32 = 64;
/// The maximum length of the human-readable start reason.
/// This accounts for StartReason::AccessCapability which can have a length of
/// MAX_MONIKER_LENGTH + MAX_NAME_LENGTH + 26 (4222 characters).
const MAX_START_REASON uint32 = 5000;
/// Errors that can be returned by the GetInstance call.
type GetInstanceError = flexible enum {
/// Could not find an instance matching the given moniker.
INSTANCE_NOT_FOUND = 1;
/// The given moniker could not be parsed.
BAD_MONIKER = 2;
};
/// Errors that can be returned by the GetManifest call.
type GetDeclarationError = flexible enum {
/// Could not find an instance matching the given moniker.
INSTANCE_NOT_FOUND = 1;
/// The given moniker could not be parsed.
BAD_MONIKER = 2;
/// The component manifest is only available when the instance is resolved.
INSTANCE_NOT_RESOLVED = 3;
/// The component manifest could not be encoded into its persistable format.
ENCODE_FAILED = 4;
/// The specified collection was not found in the specified component.
@available(added=12)
BAD_CHILD_LOCATION = 5;
/// The specified URL could not be parsed.
@available(added=12)
BAD_URL = 6;
};
/// Errors that can be returned by the GetStructuredConfig call.
type GetStructuredConfigError = flexible enum {
/// Could not find an instance matching the given moniker.
INSTANCE_NOT_FOUND = 1;
/// The given moniker could not be parsed.
BAD_MONIKER = 2;
/// The component manifest is only available when the instance is resolved.
INSTANCE_NOT_RESOLVED = 3;
/// There is no structured configuration associated with this instance.
NO_CONFIG = 4;
};
/// Errors that can be returned by the GetAllInstances call.
type GetAllInstancesError = flexible enum {
/// Could not find the scope root instance.
INSTANCE_NOT_FOUND = 1;
};
/// Errors that can be returned by the OpenDirectory call.
type OpenError = flexible enum {
/// Could not find an instance matching the given moniker.
INSTANCE_NOT_FOUND = 1;
/// The given moniker could not be parsed.
BAD_MONIKER = 2;
/// The requested directory is available when the instance is resolved.
INSTANCE_NOT_RESOLVED = 3;
/// The requested directory is available when the instance is running.
///
/// Deprecation: the platform will stop emitting this error from version 19.
/// The component will always be started if not already.
@available(deprecated=19)
INSTANCE_NOT_RUNNING = 4;
/// Component manager's open request on the directory returned a FIDL error.
FIDL_ERROR = 5;
/// The instance does not have a directory of this type.
NO_SUCH_DIR = 6;
/// The given directory type could not be parsed.
BAD_DIR_TYPE = 7;
/// The given path could not be parsed by component manager.
BAD_PATH = 8;
/// Serving the requested directory requires starting the instance, but the
/// instance failed to start.
@available(added=19)
INSTANCE_FAILED_TO_START = 9;
};
/// Errors that can be returned by the ConstructNamespace call.
type ConstructNamespaceError = flexible enum {
/// Could not find an instance matching the given moniker.
INSTANCE_NOT_FOUND = 1;
/// The given moniker could not be parsed.
BAD_MONIKER = 2;
/// Namespace construction requires the instance to be resolved.
INSTANCE_NOT_RESOLVED = 3;
};
/// Errors that can be returned by the ConnectToStorageAdmin call.
type ConnectToStorageAdminError = flexible enum {
/// Could not find an instance matching the given moniker.
INSTANCE_NOT_FOUND = 1;
/// The given moniker could not be parsed.
BAD_MONIKER = 2;
/// The instance does not define a storage capability with the given name.
STORAGE_NOT_FOUND = 3;
/// This operation requires the instance to be resolved.
INSTANCE_NOT_RESOLVED = 4;
/// The given storage capability could not be parsed.
BAD_CAPABILITY = 5;
};
/// Describes a component instance under a realm.
///
/// Note: This structure is expected to fit in a single Zircon channel message.
/// Do not add fields that have the potential to violate that constraint.
/// Prefer to create dedicated methods and iterators instead.
@available(added=11)
type Instance = table {
/// The path to this instance relative to the scope root.
1: moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
/// The URL of the component manifest for this instance.
2: url fuchsia.url.Url;
/// The stable identifier for this instance, if one exists.
3: instance_id string:<MAX_INSTANCE_ID_LENGTH>;
/// Information about the resolved state of a component instance.
/// If the component is not resolved, this field is not set.
4: resolved_info ResolvedInfo;
/// The component's environment name as defined by its parent.
5: environment string:fuchsia.component.MAX_MONIKER_LENGTH;
};
/// Information about the resolved state of a component instance.
@available(added=11)
type ResolvedInfo = table {
/// The resolved URL of this instance.
1: resolved_url fuchsia.url.Url;
/// Information about the execution state of a component instance.
/// If the component is not running, this field is not set.
2: execution_info ExecutionInfo;
};
/// Information about the execution state of a component instance.
@available(added=11)
type ExecutionInfo = table {
/// The human-readable explanation for why this instance was started.
1: start_reason string:MAX_START_REASON;
};
/// The directories of an instance that can be opened by component manager.
@available(added=11)
type OpenDirType = flexible enum {
/// Served by the component's program. Rights unknown.
OUTGOING_DIR = 1;
/// Served by the component's runner. Rights unknown.
RUNTIME_DIR = 2;
/// Served by the component's resolver. Rights unknown.
PACKAGE_DIR = 3;
/// Served by component manager. Directory has RW rights.
EXPOSED_DIR = 4;
/// Served by component manager. Directory has RW rights.
NAMESPACE_DIR = 5;
};
/// Locations from which a child could be resolved under a given parent.
type ChildLocation = flexible union {
1: collection string:fuchsia.component.MAX_NAME_LENGTH;
// TODO(https://fxbug.dev/42077932) support static children
};
/// Offers detailed introspection into component instances under a realm.
@discoverable
closed protocol RealmQuery {
/// Gets an instance identified by its moniker.
@available(added=11)
strict GetInstance(struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
}) -> (struct {
instance Instance;
}) error GetInstanceError;
/// Gets the manifest of an instance identified by its moniker.
///
/// The manifest is encoded in its standalone persistable format per RFC-0120 and
/// is sent across using an iterator. Some manifests are too large to send over a
/// Zircon channel and we can't use a VMO because we need an approach that is
/// compatible with overnet.
@available(added=13)
strict GetResolvedDeclaration(struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
}) -> (resource struct {
iterator client_end:ManifestBytesIterator;
}) error GetDeclarationError;
// TODO(https://fxbug.dev/42077935) delete once no longer required for ffx compat window
/// Prefer `GetResolvedDeclaration` if available for your target API level.
@available(added=11)
strict GetManifest(struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
}) -> (resource struct {
iterator client_end:ManifestBytesIterator;
}) error GetDeclarationError;
/// Gets the manifest of a component URL as if it were a child of the specified parent
/// without actually creating or starting that component.
///
/// The manifest is encoded in its standalone persistable format per RFC-0120 and
/// is sent across using an iterator. Some manifests are too large to send over a
/// Zircon channel and we can't use a VMO because we need an approach that is
/// compatible with overnet.
@available(added=12)
strict ResolveDeclaration(struct {
parent string:fuchsia.component.MAX_MONIKER_LENGTH;
child_location ChildLocation;
url fuchsia.url.Url;
}) -> (resource struct {
iterator client_end:ManifestBytesIterator;
}) error GetDeclarationError;
/// Gets the structured config of an instance identified by its moniker.
@available(added=13)
strict GetStructuredConfig(struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
}) -> (struct {
config fuchsia.component.decl.ResolvedConfig;
}) error GetStructuredConfigError;
// replaced by ABI-compatible version above
@available(added=11, replaced=13)
strict GetStructuredConfig(struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
}) -> (struct {
config fuchsia.component.config.ResolvedConfig;
}) error GetStructuredConfigError;
/// Returns an iterator over all component instances in this realm and instances within resolved
/// children, recursively. Unresolved child components will be included in this list, but
/// children of unresolved children will not be.
@available(added=11)
strict GetAllInstances() -> (resource struct {
iterator client_end:InstanceIterator;
}) error GetAllInstancesError;
/// Constructs the namespace of an instance as determined by its use declarations.
/// This is usually identical to what would be given to the component's runner on
/// component start time, unless extended by
/// `fuchsia.component/StartChildArgs.namespace_entries`.
@available(added=11)
strict ConstructNamespace(struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
}) -> (resource struct {
/// The directory handles + paths that constitute the component's namespace.
namespace vector<fuchsia.component.runner.ComponentNamespaceEntry>:MAX;
}) error ConstructNamespaceError;
/// Makes an fuchsia.io.Directory/Open call on a directory in an instance.
@available(added=11)
strict Open(resource struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
dir_type OpenDirType;
flags fuchsia.io.OpenFlags;
mode fuchsia.io.ModeType;
path string:fuchsia.io.MAX_PATH_LENGTH;
object server_end:fuchsia.io.Node;
}) -> () error OpenError;
/// Connects to the StorageAdmin protocol of a storage declared by an instance.
@available(added=11)
strict ConnectToStorageAdmin(resource struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
storage_name fuchsia.component.decl.name;
server_end server_end:StorageAdmin;
}) -> () error ConnectToStorageAdminError;
/// Gets the detailed information of a particular instance identified by its moniker.
/// This response contains handles to resources of the instance. As a result, component manager
/// pays a non-trivial cost when this method is invoked.
@available(added=11, deprecated=11, removed=12, note="Use GetInstance instead")
strict GetInstanceInfo(struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
}) -> (resource struct {
/// Basic information about the component instance.
info InstanceInfo;
/// Detailed information about the resolved component instance.
/// If this object does not exist, the instance is not resolved.
resolved box<ResolvedState>;
}) error RealmQueryError;
/// Gets all directories relevant to a particular instance identified by its moniker.
/// This response contains directory handles served by component manager. As a result,
/// component manager pays a non-trivial cost when this method is invoked.
@available(added=11, deprecated=11, removed=12, note="Use Open instead")
strict GetInstanceDirectories(struct {
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
}) -> (resource struct {
/// The directories available because the component instance is in resolved state
/// If this object does not exist, the instance is not resolved.
resolved_dirs box<ResolvedDirectories>;
}) error RealmQueryError;
};
/// An iterator over all instances in the realm
@available(added=11)
closed protocol InstanceIterator {
strict Next() -> (struct {
infos vector<Instance>:MAX;
});
};
/// An iterator over the bytes of an instance's manifest
@available(added=11)
closed protocol ManifestBytesIterator {
strict Next() -> (struct {
infos vector<uint8>:MAX;
});
};
// ------------------------------------------------------------
// All types below are marked deprecated and will be removed in
// a newer API version.
// ------------------------------------------------------------
/// Describes the current state of instance
@available(added=11, deprecated=11, removed=12)
type InstanceState = strict enum {
/// The component is created, but has not been resolved by component manager.
/// Most information about this component is unknown.
UNRESOLVED = 0;
/// The component has been resolved by component manager but is not currently running.
RESOLVED = 1;
/// The component has been resolved and started by component manager. It is currently running.
STARTED = 2;
};
/// Basic information about a component instance.
/// This object contains information that is readily available to component manager.
@available(added=11, deprecated=11, removed=12, note="Use Instance instead")
type InstanceInfo = struct {
/// The path to this instance relative to the scope root.
moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
/// The URL of the component manifest for this instance.
url fuchsia.url.Url;
/// The stable identifier for this instance.
instance_id string:<MAX_INSTANCE_ID_LENGTH, optional>;
/// The current state of this instance.
state InstanceState;
};
/// The detailed resolved state of a component instance
@available(added=11, deprecated=11, removed=12, note="Use ResolvedInfo instead")
type ResolvedState = resource struct {
/// All `use` declarations as defined in the component manifest.
uses vector<fuchsia.component.decl.Use>:MAX;
/// All `expose` declarations as defined in the component manifest.
exposes vector<fuchsia.component.decl.Expose>:MAX;
/// The resolved structured configuration of this component instance.
config box<fuchsia.component.config.ResolvedConfig>;
/// The package directory containing the component manifest, if one exists.
/// This directory has the same permissions given by the package resolver
/// (most likely RO permissions).
pkg_dir client_end:<fuchsia.io.Directory, optional>;
/// The information available because the component instance is running.
/// If this object does not exist, the instance is not running.
execution box<ExecutionState>;
/// The directory containing all capabilities exposed by the component.
/// This directory has RW permissions.
exposed_dir client_end:<fuchsia.io.Directory>;
/// The directory representing the component's namespace.
/// This directory has RW permissions.
ns_dir client_end:<fuchsia.io.Directory>;
};
/// The detailed execution state of a component instance
@available(added=11, deprecated=11, removed=12, note="Use ExecutionInfo instead")
type ExecutionState = resource struct {
/// The outgoing directory of this instance, if one exists.
out_dir client_end:<fuchsia.io.Directory, optional>;
/// The debug directory served by the runner of this instance, if one exists.
runtime_dir client_end:<fuchsia.io.Directory, optional>;
/// The human-readable explanation for why this instance was started.
start_reason string:MAX;
};
/// The directories available because the component instance is in resolved state
@available(added=11, deprecated=11, removed=12)
type ResolvedDirectories = resource struct {
/// The package directory containing the component manifest, if one exists.
/// This directory has the same permissions given by the package resolver
/// (most likely RX permissions).
pkg_dir client_end:<fuchsia.io.Directory, optional>;
/// The directory containing all capabilities exposed by the component.
/// This directory has RW permissions.
exposed_dir client_end:<fuchsia.io.Directory>;
/// The directory handles + paths that constitute the component's namespace.
ns_entries vector<fuchsia.component.runner.ComponentNamespaceEntry>:MAX;
/// The directories available because the component instance is running.
/// If this object does not exist, the instance is not running.
execution_dirs box<ExecutionDirectories>;
};
/// The directories available because the component instance is running
@available(added=11, deprecated=11, removed=12)
type ExecutionDirectories = resource struct {
/// The outgoing directory of this instance, if one exists.
out_dir client_end:<fuchsia.io.Directory, optional>;
/// The debug directory served by the runner of this instance, if one exists.
runtime_dir client_end:<fuchsia.io.Directory, optional>;
};
/// An iterator over basic information of all instances in the realm
@available(added=11, deprecated=11, removed=12, note="Use InstanceIterator instead")
closed protocol InstanceInfoIterator {
strict Next() -> (struct {
infos vector<InstanceInfo>:MAX;
});
};
/// Errors that can be returned by the RealmQuery API.
type RealmQueryError = flexible enum {
/// Could not find an instance matching the given moniker.
INSTANCE_NOT_FOUND = 1;
/// The given moniker could not be parsed.
BAD_MONIKER = 2;
};
/// Errors that can be returned by the RealmExplorer API.
@available(added=11, deprecated=11, removed=12)
type RealmExplorerError = flexible enum {
/// Could not find the scope root instance.
// TODO(https://fxbug.dev/42059901): Close the connection when this error occurs.
INSTANCE_NOT_FOUND = 1;
};
/// Offers basic introspection into component instances under a realm.
@discoverable
closed protocol RealmExplorer {
/// Returns an iterator over basic information of each instance scoped to this realm.
/// When the server receives this call, it will take a snapshot of the current component
/// topology and relays that over the iterator. Any changes to the topology *after* this method
/// call is received by the server will not be shown by the iterator.
@available(added=11, deprecated=11, removed=12, note="Use RealmQuery.GetAllInstances instead")
strict GetAllInstanceInfos() -> (resource struct {
iterator client_end:InstanceInfoIterator;
}) error RealmExplorerError;
};