There are different ways for indicating the storage proposal settings: through a D-Bus call, from a JSON config file, through a HTTP call (JSON), and from a YAML product file.
- The
#Calculate
D-Bus method is called with the expected D-Bus data (a{sv}
). - The storage service generates a
ProposalSettings
ruby object from the D-Bus data and calculates the proposal.
client --> storage service
* D-Bus call (a{sv}) * generates proposal settings from D-Bus data
* calculates a proposal
- The JSON file is loaded and a
ProposalSettings
rust struct is generated. - The
ProposalSettings
are converted to the expected D-Bus format and the#Calculate
D-Bus method is called. - The storage service generates a
ProposalSettings
ruby object from the D-Bus data and calculates the proposal.
agama-web-server --> storage service
* loads JSON config * generates proposal settings from D-Bus data
* converts JSON to rust struct * calculates a proposal
* converts struct to D-Bus
* D-Bus call (a{sv})
- A client (e.g., web UI) generates some JSON proposal settings and performs a HTTP post (
/storage/proposal/settings
). - The agama-web-server deserializes the given JSON into a
ProposalSettings
rust struct. - The
ProposalSettings
are converted to the expected D-Bus format and the#Calculate
D-Bus method is called. - The storage service generates a
ProposalSettings
ruby object from the D-Bus data and calculates the proposal.
client --> agama-web-server --> storage service
* HTTP post (JSON) * converts JSON to rust struct * generates proposal settings from D-Bus data
* converts struct to D-Bus * calculates a proposal
* D-Bus call (a{sv})
The product file defines some product properties (e.g., the storage volumes, repositories, etc) and some initial values for the product (e.g., the volumes to use by default for the storage proposal).
For now, let's keep this case aside. Note that the product file is loaded only once by the storage service when a product is selected. It could even make sense to have a special settings format to indicate the default values of the product.
There are at least 3 different sources (ignoring the YAML file) for calculating a storage proposal. Both JSON settings (from config file and from HTTP call) could be probably unified in a single format. But still there would be a JSON format and also a D-Bus format for the storage settings. Moreover, the JSON settings has to be converted to the D-Bus format in order to perform the D-Bus call.
Actually, Agama services like storage sevice are intented to be used by the main service of Agama. That services are not expected to offer a "user friendly" D-Bus interface for third-party tools. The D-Bus API acts as a transport layer. Because of that, the JSON settings could be directly passed to D-Bus without any kind of conversion:
client --> agama-web-server --> storage service
* HTTP post (JSON) * D-Bus call (serialized JSON) * deserializes JSON
* validates with JSON schema
* generates proposal settings from JSON
* calculates a proposal
- JSON settings are received from a HTTP request or loaded from a config file.
- A D-Bus method is called using the serialized JSON settings (a D-Bus string).
- The storage service deserializes the JSON settings, validates it using a schema, generates a proposal settings from the valid JSON data and calculates a proposal.
- If the JSON data is not valid (it does not match the schema), then proper D-Bus errors are emitted.
This idea can go a bit further, having a way of loading a general storage config (not only for the guided proposal). The JSON storage settings is being defined in this document. That storage settings defines how to manipulate storage devices (e.g., format a specific partition), how to calculate a guided proposal, and even how to calculate an AutoYaST based proposal (although this is a temporary feature).
The storage D-Bus interfaces could be reduced and simplified by offering a method to load a JSON config. If the config contains a proposal definition, then the proposal (or AutoYaST proposal) is calculated. For example, the D-Bus interfaces could look like this:
org.opensuse.Agama.Storage1
#Probe (only probes the system, without calculating a proposal)
#SetConfig(config: string)
#GetConfig --> JSON config
#Install
#Finish
org.opensuse.Agama.Storage1.Product
#Transactional
#Volumes --> JSON list
#EncryptionMethods
org.opensuse.Agama.Storage1.Proposal
#UsableDevices
#Calculated
#Result --> {success, computedSizes, defaultBootDevice}
org.opensuse.Agama.Storage1.Devices
System --> list of system devices
Target --> list of target devices
Actions --> list of actions to get the target
Dirty --> whether system has changed
Note that something like #SetConfig
will be needed anyway for auto-installation, so it is not strictly necessary to have separate methods for calculating a proposal.
Clients will always generate storage settings following the JSON schema, and that settings are passed to D-Bus.