"Modularisation" is another buzzword which is more popular now than ever. It has its benefits and drawbacks. This blog post intends to discuss the motivation for making Anaconda modular, and to describe the benefits and drawbacks of such an undertaking. For a quick summary of this article skip to the Summary section below.
What does this mean?
Anaconda is written in Python 3 and it is a monolith. This means the entire Anaconda application is one code base and one program. We can abstractly divide the existing Anaconda based on the packages we have. The UI (User Interface) and the backend are all wrapped inside of the abstract Anaconda bubble.
A simplified version would be similar to this image:
It is possible to add features to Anaconda by creating an addon, which contains Python sources at a specific location inside of the installation environment (stage 2). These files will be loaded to the monolith. Addons can access any part of Anaconda, which can be affected by changes to the codebase by the Anaconda developers. The only exceptions to this are the setup() and execute() methods, which are the starting points for addons. In other words, it is not possible to replace existing parts of Anaconda with custom functionality without losing reliability of the code. Therefore, it is only possible to add new features, which should, ideally, not use the internals of Anaconda at all.
Something else to consider is the user interface, both graphical and text. It is the part of Anaconda which may or may not be installed in the installation environment depending on which package is included when creating a bootable iso. This UI code is directly calling the backend. The user interfaces also have logic which is used to ensure successful installation. This is bad in many ways -- for example, the code has to be duplicated, and addons are not able to simply use and enhance it, since it is prone to breaking.
A modular Anaconda will be based on four parts: modules, core, UI and installer.
A module is a logical unit which provides a specific Anaconda functionality. Every module will have kickstart command(s) it works with. The module will be responsible for only its specific functionality, and it will communicate with other modules if it needs information outside of the module’s scope. The modules could be: Time & Date, Users, Storage, Localization, etc. Every module will have documentation and an API. These modules will be isolated units and will communicate with each other by a public message bus, which will likely be DBus. Every new module may connect to this bus and use the API. User addons are similar to modules and have the same capabilities as the main modules. It will also be possible to remove existing modules or replace them entirely.
The core is more backend code for developers. However, it is one of the main components. Every module must use the core. The main responsibility of the core is to register new modules, add them to the message bus, and solve their dependencies. It can also handle runtime validation of module communication and report their state.
The UI will connect in a way similar to the modules. It will connect externally to the modules via the message bus, so everything used for the UI will be the public API, and it could use any addon available. Addons can, of course, add their new functionality to the UI as well. On the other hand, the UI won't be registered on the bus for addons and modules, so they can't call the UI. The UI should contain the least amount of logic possible. The best case scenario is to have the UI logic isolated and everything related to installation should be the modules’ responsibility. In other words, it should be simple to write a user interface.
The installer is the executor. The core will take data from all the modules, create the complete kickstart file, and run the installer with the kickstart file. Installation will be non-interactive, and it should be possible to run the installer on its own. However, all validations and APIs will be lost.
The current Anaconda has one significant problem: all of the code is in one place--the monolith. It is more difficult to trace bugs and to a have a stable API. Implementing new features or modifying existing code in Anaconda is also more challenging. Modularisation should help with these things mainly because of isolation between the modules. It will be much easier to create tests for modules or to add new functionality.
Modularisation also opens up new possibilities to developers. They should be able to create a new user interface easily. Since developers can rely on the existing API documentation, it should not be necessary to browse the source code tree very often. Another benefit is that an addon is like another module, communicating with other modules, so it has the same capabilities. Developers can use the public API to write their addons in their favourite programming language which supports DBus.
Here are some drawbacks of this change:
- It will take a lot of time and work; a big part of the existing codebase needs to be rewritten.
- It is currently unknown whether DBus can handle all of the work. If not, a replacement needs to be found.
Do you have any questions? Please leave a reply; all comments are welcome.
-  Anaconda was migrated to Python 3 in Fedora 23.
-  We are trying to avoid that but then the core Text and Graphical UI are more and more entangled.
-  It is possible that this functionality will be added later if this feature is desired.