Every repository with this icon (
Every repository with this icon (
Home
Welcome to Metro!
What is Metro?
Metro is a build tool that can build Gentoo Linux OS releases and OpenVZ templates. It’s designed to interface with a package manager such as Portage/emerge so that users can build their own releases of Gentoo or other Linux-based operating systems.
The heart of Metro is its data-oriented recipe language and associated parser, which has been designed to keep operating system builds organized, consistent, maintainable and reliable.
From a Gentoo perspective, you can view Metro as a complete re-thinking and redesign of Gentoo’s Catalyst build tool – building on its strengths and addessing its weaknesses.
QuickStart
To get started right away, use the following links. Otherwise, keep reading Understanding Metro below to understand what Metro is about:
To install Metro for the first time and try it out, see QuickStartGuide.
For the next step, learn how to do custom builds with Metro by reading CustomBuilds.
To learn more about the Metro data model, see MetroDataModel.
To learn more about how Metro gets things done, start reading Using Metro. Developer TODO is viewable at TODO.
Understanding Metro
Probably the easiest way to understand Metro is to compare and contrast it with Gentoo’s Catalyst build tool. Much of Metro’s inspiration came understanding the limitations that existed in Catalyst, and then building a new technology that did not have these limitations. First, let’s contrast the general functionality of both tools. Since Metro is brand new, it is missing some functionality that is in Catalyst:
General Feature Comparison
| General Feature Description | Catalyst | Metro 1.3 |
| Can Build Gentoo Stage 1/2/3 | Yes | Yes |
| Extensible to build new targets | Yes (difficult) | Yes (easy) |
| Out-of-box support for building Custom Gentoo Stages | Yes | Yes |
| ccache (compiler cache) support | Yes | Yes |
| Can Build Unstable Funtoo Stages | No (broken) | Yes |
| Can Build OpenVZ templates | No | Yes |
| Can Build Linux vserver templates | No | Yes |
| Mirror support (easy user-specified paths) | No | Yes |
| HTTP, FTP and rsync proxy support | No (broken) | Yes |
| Gentoo “probes” debugging functionality | No | Yes |
| Documentation | No | Yes |
| Git support | No | Yes |
| Working support for building LiveCDs | Yes | No (planned for 1.x) |
| distcc support | Yes | No |
| icecream support | Yes | No |
| Package cache | Yes | Yes |
| Fine-grained “resume” support | Yes | No |
As you can see, Metro shares some functionality with Catalyst. However, Metro supports Funtoo (unstable) builds, offers support for building OpenVZ templates and supports Git-based Portage repositories. Also, Metro has a very useful feature which we’re calling “Mirror support” that allows the user to easily tell Metro where to look for things it needs and where to put things it creates. This allows you to easily adapt Metro to your specific environment rather than write a script to shuffle things to and fro, which is required with Catalyst and makes it more difficult to use.
You can also see what features Metro does not have when compared to catalyst. Some of these are due to Metro being brand new and will be added soon. Others have not been included in order to keep the code base relatively small, elegant and easy to maintain. In general, I only want to add features to Metro that offer a meaningful benefit without overly complicating the code. Otherwise, the features become a maintenance liability and can end up making the Metro codebase less able to adapt to future needs. The recipe-based design of Metro does offer a big advantage in this regard, however. Because so much of the complexity of Metro has been moved out of Python code and into Metro recipes, the Python code in Metro is an order of magnitude simpler than the catalyst python code base. This makes Metro more able to accept new functionality in the future as needs arise, while still keeping the code base maintainable and elegant.
Recipe Feature Comparison
Both Metro and Catalyst use recipes to describe what should be built. Catalyst’s build recipes are extremely simple, typically only around six lines long. They serve as a means to provide variables to Catalyst’s python code, which does all of the heavy lifting and is quite complex. In contrast, Metro’s recipe engine is much more sophisticated, and all key functionality is performed by the recipes rather than Metro’s python code. This means that Metro’s python code provides a basic framework, while Metro’s recipes explain how things are built. From a developer perspective, this is a major advantage, as you can easily change the build process by changing the recipe. Recipes are typically written in bash but can be written in any scripting language including sh, python, perl, ruby and others.
The recipe-based design of Metro is a key architectural improvement over catalyst, and should allow Metro to age more gracefully and be more easily customizable by developers.
| Recipe Feature Description | Catalyst | Metro 1.1 |
| True recipe-based system | No | Yes |
| Functional data model | No | Yes |
| Keyword references (ie. variable expansion) | No | Yes |
| Multi-line elements | No | Yes |
| Section annotations (groups of data) | No | Yes |
| Conditional blocks (conditionals) | No | Yes |
| Collect annotations (includes) | No | Yes |
| Conditional collect annotations (conditional includes) | No | Yes |
| Core Template engine | No | Yes |
| Embedded Python Template Engine | No | Yes |
| Scripting Language Integration | No | Yes (bash, python, ruby, etc.) |
Collaboration Features
Next, let’s look at features related to collaboration. We want Metro to be a tool that anyone reasonably proficient with Linux can use to build their own OS releases, virtual containers, LiveCDs, etc. To make this happen, we need good documentation for Metro. We also need to keep the source code elegant and easy to understand. Metro’s source code is very elegant with one current exception – modules/flexdata.py – the parser implementation – is a bunch of messy code and will be rewritten from scratch hopefully around version 1.4. I’ve done a lot of experimentation with different approaches to parsing, and grafted in a lot of parser features I was not originally expecting to add. This has caused the parsing code to progressively get uglier and uglier. Right now, I am treating modules/flexdata.py as disposable code – since it will be completely rewritten soon, I have not put much effort into prettying it up. With this one exception, Metro’s code is very elegant and has been drastically simplified when compared to Catalyst. Much of the complexity is now being managed in the recipes themselves rather than relatively fragile and hard-to-extend Python code.
Lastly, Metro’s recipe-based design lends itself to community collaboration. Since Metro users can add new functionality to Metro without touching the Python code, recipes can be easily shared and extended by others. I have made a determined effort to put as much functionality as possible on the recipe side rather than embedding a lot of complex logic in the program itself. This recipe-driven design is a major improvement over catalyst.
| Collaboration Feature Description | Catalyst | Metro 1.1 |
| Documentation | No | Yes (work in progress!) |
| Lines of Python source code | 3000+ | 1500 |
| Easy sharing of recipes | No | Yes |







