{% set rfcid = “RFC-0220” %} {% include “docs/contribute/governance/rfcs/_common/_rfc_header.md” %}
{# Fuchsia RFCs use templates to display various fields from _rfcs.yaml. View the #} {# fully rendered RFCs at https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs #}
A proposal to simplify the set of product configurations in the open source //products directory.
//products
currently contains ten product definitions. Fuchsia has evolved significantly since those product definitions were created, and the users of those products have become fragmented. Some products have only a couple of users or use cases, or have idiosyncratic features like UI stacks that only exist in that product. Making changes to cross-cutting features like product assembly, the build system, or graphics or networking stacks requires considering each individual product and their differences. This costs developer time and effort, and slows down the platform's evolution.
The //products
directory also has no clear roadmap or statement of purpose. It is unclear from the README
why the products in that directory exist, who they're for, or who maintains them. An ad hoc group of volunteers cares for and feeds the product definitions, with no clear mandate.
Rather than a larger number of products in the platform source tree which have specific use cases, Fuchsia should prefer a smaller number of tightly scoped product definitions that provide reference implementations and examples for how to create a product out of tree (OOT),
It is time to set a roadmap for the //products
directory and significantly reduce the user base fragmentation of Fuchsia's product definitions.
Facilitator: rlb@google.com
Reviewers:
In alphabetical order
aaronwood@google.com
abarth@google.com
amathes@google.com
ddorwin@google.com
dworsham@google.com
fmeawad@google.com
hjfreyer@google.com
jasoncampbell@google.com
neelsa@google.com
nicoh@google.com
Consulted:
List people who should review the RFC, but whose approval is not required.
Socialization:
This RFC was socialized internally in document form with much of the organization, including the teams listed as Consulted and the Fuchsia Engineering Council.
A system is a set of images (ZBI, vbmeta, and optionally an FVM) destined for a single boot slot on a target. This represents a bootable Fuchsia image, though without everything we'd want to flash to a target in production (like recovery images).
See RFC-0115 for more details on boot slots and flashable images.
From our existing documentation: “A product defines the software configuration that a build will produce. Most critically, a product typically defines the kinds of user experiences that are provided for, such as what kind of graphical shell the user might observe, whether or not multimedia support is included, and so on.”
In the output of our product assembly process, a product defines the combination of one or more systems (in slots A, B, and/or R) that are intended for placement on a target. For example, a product image might contain a kernel image, FVM, vbmeta, a recovery image, a recovery vbmeta, and a bootloader image.
From our existing documentation: “A board defines the architecture that the build produces for, and key features of the device upon which the build is intended to run. This configuration affects what drivers are included, and may also influence device-specific kernel parameters.”
Fuchsia build parameters are specified by a (product, board) tuple. This set of parameters completely describes the work the build system must complete to produce a flashable product image.
Minimize the number of product definitions the Fuchsia team has to support over time, to minimize load on both developers and infrastructure
Minimize the amount of migration work for existing users of the current product definitions - moving off core
and terminal
should be as easy as possible for current users of those products
Remove product definitions that no longer represent the intended usage of the Fuchsia platform, or use deprecated configurations
Simplify the product definitions that stay so they are easier to maintain
For product definitions that remain (except bringup
), implement build types so production products can refer to the appropriate build type when implementing their own versions
Define how the new product definitions should be used, when they should be added to, and under what conditions we'd add an entirely new product definition
Don't fundamentally change how products are defined, or how boards are defined, if possible. Keep scope achievable over the medium term
We must support kernel and new board development without the need for custom product definitions
All products must be automatically tested in infrastructure
All products in //products
should be distributed as SDK companion images, and work equally well in and out of tree
Avoid the need for tests to ever add things to the platform to run on products. Tests should be able to bring their dependencies in their own package as subpackages. For example, //bundles/buildbot:foo
should only contain tests, and should not add anything to the product or platform definitions.
Restructure or redefine the interaction of boards, build types, and products. This RFC should focus as much as possible on the contents of //products
and their purposes.
Change development workflows beyond swapping product definitions. This RFC is only concerned with the contents of product definitions.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in IETF RFC 2119.
We have ten product definitions in //products
today. We‘ll remove eight of these product definitions over time, keep two (minimal
, bringup
), and add one more: workbench
. We’ll only create _eng
build types of minimal
and workbench
for now, but may add _user
and _userdebug
build types in future if there is a need.
Many of the current definitions exist to support testing flows, and contain their particular packages and configuration because tests directly rely on services included in the system image, rather than bringing their dependencies with them in their own package.
We intend that most Fuchsia tests should run on minimal_eng
in the medium term, because most Fuchsia tests should be hermetically packaged with all their dependencies.
If a particular test needs to run while relying on services provided directly by the system (not versions running out of its own package), then we should avoid creating a generic in-tree product for testing it. That test should run on the product it's meant to test functionality for, or it should define its own private out-of-tree product definition to run on. We will no longer create and maintain generic “testing products” for tests of all possible functionality. Instead of using products only meant for testing, we should prefer to add testing support to products which are more generally useful for customers or developers.
This means that not all functionality in fuchsia.git will exist in an in-tree product's base configuration by default. We should prefer to create integration and unit tests which can run hermetically on the products we have, rather than add all functionality to a platform-supported product and support that forever.
Used mostly by kernel developers today. bringup
is used to exercise the kernel and core drivers and to do development on new boards.
We intend to leave bringup
as it is in terms of its purpose and contents, but move it to use product assembly. We no longer intend bringup
to be the “base class” for all defined products, as bringup has certain features that are not applicable for all products.
The remaining product definitions in //products
will be co-owned by the Fuchsia Architecture and Software Assembly teams. Day to day maintenance will be done by Software Assembly.
Intended to be “the smallest thing we'd still call Fuchsia.” Definitionally, the smallest thing we'd still call Fuchsia is a system which can:
Note: by “smallest,” we're referring to the smallest amount of functionality the system requires in order to accomplish the above tasks. For instance, none of the above tasks require graphics support, so a system which had graphics would be considered “larger” than minimal
. “Smallest” does not necessarily mean “a system which uses the least memory or CPU.” minimal
might have the lowest resource usage of any product, but that would be by chance rather than design.
The main use of this product for the Fuchsia project will be to run hermetically-packaged tests which contain all their dependencies. It can also serve as a basis for system tests which are not hermetic but only depend on the small set of Fuchsia services it contains.
We will define minimal
as an _eng
build type and for now not create _user
or _userdebug
versions of minimal
. All product definitions in product assembly must be one of _eng
, _userdebug
, or _user
. All references to minimal_eng
and minimal
in the rest of this document are therefore equivalent.
minimal
will include support for:
ffx session launch
on eng
builds.minimal_eng
will be the recommended configuration to run tests against, and will non-exhaustively include by virtue of being an _eng
configuration:
We do not intend to include the following:
Note: even though minimal
won't include support for these features in base, they can still be tested on minimal_eng
builds in hermetically-packaged tests, because all _eng
product builds contain test support. For instance, a graphics test could subpackage the Fuchsia UI subsystem and hardware fakes, as provided by test_ui_stack, and run on minimal_eng
, even though no graphics will be shown on a screen. We will encourage all tests to run on minimal_eng
instead of workbench
if they are able to do so, as minimal_eng
will have lower build time and more debuggability by virtue of being smaller.
minimal
?A platform developer should add a component to an Assembly Input Bundle included in minimal
when it supports the core goal of the minimal
product. For example, a new default filesystem for Fuchsia should get added to minimal
, as a filesystem is required for OTA updates and minimal
should use the default Fuchsia filesystem. A new driver framework should get added to minimal
if it is intended to be in all Fuchsia products. A new graphics driver or control system should not get added to minimal
, as graphics are not required in all Fuchsia systems to boot or update the system.
We have two pressure tests to firmly determine whether a given component should be included in minimal_eng
:
_eng
build type?minimal
unusable without it?If a platform component shouldn't go in minimal, it is likely still a fit for workbench
.
minimal
We should include support for a driver stack in the platform configuration for minimal
if it is critical to support an OTA or running component manager on all boards. This means that even if the board running minimal
provides support for say, Bluetooth, we shouldn't include that driver stack in the resulting configuration because the product does not need it.
This implies a design in which the set of drivers included in the final image is the intersection of features requested by the product and the board's hardware support. This intersection feature is in development with the Software Assembly team.
workbench
will be a product configuration for local development, running larger tests which cannot or should not be packaged hermetically, and exercising larger parts of the Fuchsia platform than minimal
supports. It is intended to be like a literal workbench in that it supports development tools and allows a developer to poke at the system and make changes. It is not intended to be a product that ships to users, or be a basis for those products.
We intend that workbench
will include graphics, audio, and input support (touch, mouse, and keyboard) in addition to the features included by minimal
. This will enable full system validation tests which simulate a graphical product (with the exception of hardware accelerated video decoders and DRM/protected memory).
We will also include WLAN and bluetooth support in workbench
builds if they are supported by the board configured for the build.
This product will serve most uses of the current workstation
and terminal
products, but at a much lower maintenance cost. For instance, many tests that currently run on core
will need to run on workbench
, so workbench
will be able to build with the equivalent of --with //bundles/buildbot:core
to create a package repository of available tests.
workbench
will have a default session adapted from tiles-session
, but will not launch any elements by default. This will enable interactive testing and debugging of different graphical elements, like graphics demos or terminals. Software or tests which need the session to not launch by default will be able to use runtime configuration to disable the launch.
workbench
will not contain any runtimes like Flutter or Chrome as base packages, but they will be able to be loaded on-demand from a package server for development.
workbench
will use the same platform definition for assembly as minimal
, but add to it. It will not inherit the entire product configuration of minimal
.
We will define workbench
as an _eng
build type and for now not create _user
or _userdebug
versions of workbench
. All product definitions in product assembly must be one of _eng
, _userdebug
, or _user
. All references to workbench_eng
and workbench
in the rest of this document are therefore equivalent.
workbench
?We should add components to workbench
when it is expected that the component will be used in all Fuchsia products with graphics and audio support, or that most in-tree Fuchsia developers would benefit from its inclusion in testing flows or day to day development.
For example:
minimal
should also be added to workbench
workbench
, since only a subset of Fuchsia products will have a camera.Some FIDL protocols like fuchsia.web
are defined by the platform, with implementations that are provided from outside the platform. Since those implementations can change and the platform doesn't generally contain a component implementing those protocols, we need to provide a place in the component topology for the product to slot in a component implementing those protocols.
In particular, we should leave a place in the workbench
component topology for an implementation of fuchsia.web
without providing an implementation in the in-tree product definition. Product owners or developers who wish to include an implementation of fuchsia.web
can either use --with-base
during a build, place an implementation in the Fuchsia package server to be loaded at runtime, or we could add support for specifying product-provided implementations directly in the product assembly configuration.
We'll migrate users away from each of these product definitions over time, and then delete the definitions.
As of this RFC, core
and all of its various sub-definitions are deprecated.
Used extensively in Fuchsia‘s infrastructure and by Fuchsia developers at their desks. This is far larger than "the smallest thing we’d call Fuchsia," and includes things like Bluetooth tooling, WLAN tooling, a driver playground, audio, the Starnix manager, a test manager, fuzzing support, virtualization support, SSH support, a utility for managing short-term mutable storage, and many other things that not all products will require.
Our opinion is that core
is a useful product for certain cases, but contains too many opinionated choices about what a product should contain to be the basis of all Fuchsia products.
We plan to shift infrastructure and developers off of core
and to minimal
and workbench
over time, and eventually delete core
. We'll make this possible with technology like subpackages, hermetic integration tests, and making it easy to add software at runtime using Software Delivery tools.
The core.x64
builder runs well over 1000 tests in Fuchsia infrastructure, so deleting this product will be a significant task without technology to ease the transition.
All tests that we currently have should continue to run on either minimal_eng
or workbench_eng
, and we must continue to support the //:tests
idiom in which developers can put their tests in a top-level GN label and they will be sure the tests will run on infrastructure somewhere.
Guidance for where a test should live follows:
minimal_eng
, then we should prefer running it on the minimal_eng
builderworkbench_eng
, which is the closest analogue to today’s core
imageWe can likely use programmatic analysis of the //:tests
target to determine hermeticity and thus which image runs a given test.
Used by infrastructure to perform size checks against platform code. This in turn allows debugging of size creep by core platform components before it rolls into a shipping product, and allows a public view of size check results.
We intend to migrate these checks to minimal_eng
over time, which should have built-in size limits. core_size_limits
exists because there are so many ways to modify the core
image at build time (i.e. with GN arguments) that size limits on the main core image were impractical. Part of the point of minimal
is to be unmodifiable at build time, and to come in only one configuration, so size limits should be an integral part of the minimal
configuration.
Note: We‘d prefer that size checking not rely on a specific product definition. For instance, it would be nice if we could track the size of groups of platform components over time without relying on a particular product configuration. However, this capability does not currently exist, and so we’re proposing doing size checks against minimal_eng
for now. As a result, the reported overall image size will be affected by non-production packages such as developer tools, but sizes of production packages will also be available.
Used as a convenience product for netstack3
developers and for automated testing in infrastructure. We should include netstack2
in workbench
for the purposes of testing while netstack3
is finished, and provide a build-time switch to enable netstack3
either via a new product definition like core_with_netstack3
that modifies workbench
or by an argument to the GN or Bazel build defined in an infrastructure recipe.
As of this RFC, terminal
is deprecated.
Described in the documentation as “a system with a simple graphical user interface with a command-line terminal.” Currently used by a variety of OOT customers to run tests against a product with a graphics system. We intend to migrate these users to the minimal
product (or workbench
if they really cannot shed their system dependencies), and then delete the terminal
product.
The terminal builder in CI runs some benchmarks and several significant tests. These could likely be migrated to a core
builder in the short term, or minimal
in the long term.
More importantly, we'd need to figure out how to stop distributing terminal
images in the SDK. The Chromium and Flutter infrastructures make significant use of the terminal
image as a test host. The implementation section of this RFC describes a plan to migrate the Chromium tests to workbench
.
As of this RFC, workstation is deprecated.
We'd like to replace most uses of workstation with workbench
.
There are several uses of workstation
for which we'll need to find alternatives:
workbench
.minimal
or an OOT product repository.//vendor/google
, though it will still be possible to run starnix programs on workbench
using a package server.See the section on workstation
above. We will delete this configuration.
This was used as a development target for Driver Framework version 2. The Driver Framework team is deleting it as they're nearly done with their migration.
Used as a basis for system validation tests. We'll migrate these tests to workbench
, though none of them are currently running.
Driver developers currently do their work mostly on the core
and bringup
products. Some of them modify the board configuration to include their drivers, some to use --devs_boot_labels
or board_driver_package_labels
as an argument to their fx set
or args.gn
, and some use ephemeral driver loading (which is still experimental).
We are investing in out-of-tree driver development workflows, and the intention is that driver developers will not need to completely reassemble a product to test their driver unless that driver is necessary before networking is available. As of this writing, ephemeral driver loading works for some drivers, though it is not currently possible to use ephemeral loading for drivers which need to run before the device's networking is up.
This RFC does not aim to change driver development workflows, but rather to change the default contents of the product configurations they target. Products generally should not be pulling in drivers as dependencies, but leaving that to board configurations.
There are upcoming changes to product assembly and Fuchsia‘s developer flows which lead to assembly. We’ll leave those flows to subsequent RFCs and documents by saying: we intend to preserve the ability to include drivers in an assembly from the command line or via a file like args.gn
.
minimal
has no legacy assembly bundle (this is not a blocker but will significantly reduce maintenance cost)minimal
runs well on NUC, VIM3, FEMU, and QEMUworkbench
on top of the platform definition for minimal
to ensure the two products don’t diverge.workbench
runs well on NUC, VIM3, Google Compute Engine, and FEMU.tiles-session
at runtime in order to run things like graphical terminals.Many of these migrations will rely on support for subpackages being created out of tree and on our workstreams to support fully hermetic integration tests both in and out of tree. We must implement this feature before migrations will be possible in large numbers.
We must also be able to distribute packages out of tree, which was covered in RFC-0208.
The rest of the workstreams can be run in parallel with each other.
This product definition will likely be the hardest to move users away from, as it has the largest number of users both in and out of tree.
Because of previously lax hermeticity requirements for tests, many tests now take dependencies on certain aspects of the core
product definition. For instance, a test might resolve packages it knows to be in the base set in core
. In doing the migration away from core
as a testing product, we should prevent these instances of Hyrum's law cropping up again. In particular, we should:
All hermetically-packaged tests that are also hermetic with respect to services can be run unmodified against minimal
. We should eagerly move as many in-tree tests as possible to run on minimal
, and establish an allowlist for tests allowed to run in core
to prevent more tests taking dependencies on the configuration of core
.
Once we have an allowlist for the users of core
‘, we’ll engage with the owners of those tests to migrate them to minimal
or workbench
, using the best practices mentioned above.
Out of tree users will be another challenge, since we can‘t as easily enumerate them or their tests. We’ll work with each petal owner individually to determine their usage of core
and whether they can move to minimal
or workbench
. If they can‘t move without changes to those products, we can make them, or create out of tree products specifically for those petal’s tests, following the churn policy.
terminal
may be our most complicated removal because it is the most complicated open source product except for workstation
, and it has many users. This RFC does not claim to have a perfectly complete migration plan for terminal
, but it does commit the Fuchsia organization to support customers as they migrate, either by implementing OOT hermetic testing with subpackages, by adding OOT products for testing, or by adding dependencies to workbench
(roughly in that order of priority).
Here's a sketch of an implementation plan:
terminal
because they require graphics support, so most of them will likely need to migrate to workbench
.workbench
and running tests against it. Run tests in parallel to ensure parity, then turn off the terminal
-based tests once satisfied.Chromium's public CI tests web_engine
using terminal
. Their tests rely on lots of features and services that terminal exposes directly from the base image, such as graphics. In addition, it relies on test/fake components such as fuchsia-pkg://fuchsia.com/flatland-scene-manager-test-ui-stack#meta/test-ui-stack.cm
.
To work unaltered, their tests will need an environment which provides those services and more. We should not block this work on refactoring Chromium tests, so we need to provide such an environment. We can either move the Chromium tests to subpackage their dependencies or provide a package repository to resolve packages at runtime.
workstation
and sub-productsworkstation
is being deleted from Fuchsia's CI in parallel with this writing. However, it is still being shipped in the SDK.
workstation
, determine whether they need to migrate to minimal
, workbench
or an entirely different product definition (potentially out of tree) for their testingworkstation
images in the SDKNo products we're removing are running in production, so no performance impact is expected.
The terminal images are currently used to run performance tests. We don't expect significant performance impacts by moving those tests to workbench
.
We don't intend to change development flows or how products are specified with this RFC. We intend to change the set of available products, which will affect what developers target when they want to run tests in tree or using the SDK. We may also help migrate some tests to a different style (as previously mentioned, hermetically packaged with their dependencies as subpackages) as part of implementation.
Most of these product definition changes are backwards compatible in that we‘re presenting the services that most users need from the new products. For customers of products which are being renamed or changing contents, we’ll provide soft transitions and notification periods. We'll also do much of the migration work ourselves, inline with the Fuchsia Churn Policy.
We don‘t intend or anticipate significant security changes due to this RFC’s implementation. If anything, our security posture should improve due to maintaining fewer product configurations.
None of our new products should be given to users or used in production. These products should implement as secure a configuration of Fuchsia as possible. _eng
variants will naturally allow operations like adding package repositories that current products like core
and terminal
already allow by default.
None of our new products should be given to users or used in production, or for any personal information. We don't believe there are privacy concerns associated with these new products.
Testing the implementation of this RFC is straightforward: all of the tests we currently have both in and out of tree should still pass. Some may need to be migrated to rely on different service implementations, or mocks, or fakes. However, we should achieve the same test coverage we currently have, and we should not disable test suites to achieve the goals of this RFC.
We‘ll update the documentation in the //products
directory which explains the purpose of each product. We’ll add documentation for developers wishing to add test coverage on which product they should target for their tests, and how to use them.
We‘ll remove or modify documentation on fuchsia.dev related to workstation
and the other products we’re removing as we do those removals. Tutorials or codelabs which contain removed or renamed products will be updated as part of our changes.
We will update RFC-0095 to note that this RFC supersedes that one, and we won't be building workstation
or its successor workbench
out of tree at this time.
The transition from terminal
and core
to our new product definitions will mean that we need to have the new product builders running while we transition off the old ones. This will increase infrastructure load until we can delete the builders for the old product definitions. This may create churn on the developer experience as we do the transition.
The main alternative to this RFC is to simply do less. We could remove workstation
and keep core
, minimal
, terminal
, and all their variations unchanged.
This would mean we still need to maintain these product configurations, and work we do on, e.g. rationalizing the core realm, or migrating products to bazel-based assembly will need to be replicated across a larger number of supported products. Having a smaller number of product configurations over time will be dramatically simpler for the teams which maintain the core aspects of product configurations, assembly, and build.
Since many of our current customers for these products have less demand given our reprioritization of workstation, this is an optimal time to simplify our supported configurations.
We could create workbench
in an out-of-tree repository (similar to the proposal in RFC-0095), as many of our tests could be packaged hermetically and run on minimal
. However, lots of tests and use cases rely on graphics or audio, or don‘t want to pull in another OOT dependency, and we need something to run in-tree graphics and audio tests on anyway. We’d end up with a configuration like workbench
checked into the tree somewhere. It's better if we simply maintain it in the //products
directory.
Linked at relevant points in the document.