This document summarizes the main components of DevStream and how data flows between these components.
The following diagram shows an approximation of how DevStream executes a user command:
There are three major parts:
- CLI: handles user input, commands and parameters
- plugin engine: achieves the core functionalities by calling other modules (config loader, plugins manager, etc.)
- plugins: implements the actual install/uninstall for a certain DevOps tool
Note: for simplicity, the CLI is named dtm
(DevOps Tool Manager) instead of the full name DevStream.
Every time a user runs the dtm
program, the execution transfers immediately into one of the "command" implementations in the devstream
package, in which folder all commands' definitions reside.
Then, each command calls the plugin engine package under internal/pkg
.
The plugin engine calls the config loader first to read the local YAML config file into a struct.
Then it calls the plugin manager to download the required plugins.
After that, the plugin engine calls the state manager and plan manager to create a plan. At last, the plugin engine asks the plan manager to execute the plan and the state manager to update the state. During the execution of the plan, the plugin engine loads each plugin (*.so file) and calls the predefined interface.
The plugin engine has various responsibilities:
- making sure the required plugins (according to the config) are present
- generate a plan according to the state
- execute the plan by loading each plugin and running the desired operation
It achieves the goal by calling the following modules:
Model types in package config
represent the top-level configuration structure.
The plugin manager is in charge of downloading necessary plugins according to the configuration.
If a plugin with the desired version already exists locally, it will not download it again.
The state manager manages the "state", i.e., what has been done successfully and what not.
The plan manager creates a plan according to the state and the config and executes the plan.
A plugin implements the aforementioned predefined interfaces.
It executes operations like install, uninstall, and stores state.
To develop a new plugin, see creating_a_plugin.md.