Skip to content

Commit

Permalink
[doc] Document the new Agama architecture (#1033)
Browse files Browse the repository at this point in the history
Add a document explaining the proposal for the new Agama architecture.
Let's consider the document as a starting point for further discussion.

You can see the [rendered
version](https://github.com/openSUSE/agama/blob/new-architecture/doc/new_architecture.md)
if you prefer.

PS: please, forgive me for those diagrams 😅
  • Loading branch information
imobachgs authored Feb 12, 2024
1 parent fad784f commit d3ce7b6
Showing 1 changed file with 173 additions and 0 deletions.
173 changes: 173 additions & 0 deletions doc/new_architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Agama's 2024 architecture

This document describes the proposal for the new Agama architecture. The reasons for introducing
these changes are recorded in [a discussion in Agama's repository][drop-cockpit].

[drop-cockpit]: https://github.com/openSUSE/agama/discussions/1000

But before describing how the architecture should look, let's quickly look at the current status.

## The current architecture

At this point, Agama is composed of four high-level components:

* **Agama service**: implements the logic to perform the installation. It is the core component of
Agama and it offers a D-Bus interface. Actually, it is composed of two services: `rubygem-agama` and
`agama-dbus-server`.

* **Web user interface (`cockpit-agama`)**: a web-based interface that plays the role of a GUI when
using Agama live.

* **Command Line Interface (`agama-cli`)**: it allows to interact with Agama core and drives the
auto-installation process.

* **Auto-installation (`autoinstallation`)**: it is composed by a Systemd service (`agama-auto`) and
a script that relies on `agama-cli`.

In addition to those components, we need to consider Cockpit, which plays a vital role:

* It makes communication between the web UI and the D-Bus services possible.
* It makes the web UI code available to the browser.
* It takes care of authenticating the user when connecting remotely. Again, it is only relative to
the web UI.

```mermaid
flowchart LR
subgraph Clients
Browser
CLI
auto
end
subgraph Cockpit
UI["Web UI"]
end
subgraph Agama Service
Rust[Agama Rust]
Ruby[Agama Ruby]
end
Browser <---> UI
UI <--D-Bus--> Rust
UI <--D-Bus--> Ruby
CLI <--D-Bus--> Rust
CLI <--D-Bus--> Ruby
Rust <--D-Bus---> Ruby
auto --> CLI
```

## The new architecture

The proposed architecture is not that different from the current one, but it tries to meet these
goals:

* Drop our dependency on Cockpit.
* Implement a higher-level API to be consumed by the clients, replacing D-Bus for client-server
communication. Agama will still use D-Bus for IPC between the Rust and Ruby components.

### Components

With those goals in mind, we are considering the following components:

* **Agama core (old `agama-dbus-server`)**: implements the installation logic. It relies heavily on
the Agama YaST service.

* **Agama YaST service (old `rubygem-agama`)**: it is written in Ruby and has direct access to YaST
libraries. Complex parts, like storage and software handling, are implemented in this component.

* **HTTP and WebSocket API**: implements the API the clients should use to communicate with Agama.
Under the hood, it still uses D-Bus for communication between Agama core and Agama YaST.

* **Web user interface (old `cockpit-agama`)**: Agama's graphical user interface. The web server
makes this React application available to the browsers.

* **Command Line Interface (`agama-cli`)**: it allows interaction with Agama and drives the
auto-installation process. With the new architecture, connecting through the network might be
possible without SSH.

* **Auto-installation (`autoinstallation`)**: as in the current architecture, it is composed by
a Systemd service (`agama-auto`) and a script that relies on `agama-cli`.

The following diagram could be better, but it represents the main components and their interactions.

```mermaid
flowchart LR
subgraph Clients
Browser
CLI
auto
end
subgraph Agama Core
subgraph Web["Web Server"]
direction TB
UI["Web UI"]
API["HTTP/WS API"]
WS["WebSocket"]
end
Web <--"Channel" --> Rust
end
Rust <-- "D-Bus" --> YaST["Agama YaST"]
Browser --> UI
Browser --> API
Browser <---> WS
CLI --> API
CLI <---> WS
auto --> CLI
```

### The web-based API

The new web-based API is divided into two different parts:

* **HTTP/JSON API**: allows clients to execute actions or query Agama. For instance, it could get
the list of available products, request a new storage proposal or start the installation. About the
approach, something REST-like is the most suitable. Switching to GraphQL or gRPC do not seem to be
needed in our case (todo: write why).

* **WebSocket**: Agama will use WebSockets to notify clients about any relevant event: progress,
configuration changes, etc. The event's format is not defined yet, but a JSON event containing the
`type` and the `payload/details` should be enough[^topics].

[^topics]: Ideally, the clients should be able to subscribe to the topics they are interested in.
But that feature can wait.

### Encryption

In the case of a remote installation, the communication between the clients and the server must be
encrypted. Connecting to port 80 (HTTP) should redirect the client to port 443 (HTTPS).

About the certificate, Agama will use a self-signed certificate unless the user injects its own
certificate (through a kernel command line option).

NOTE: under discussion.

### Authentication

The HTTP interface should allow authentication specifying a user and password that will be checked
against PAM. It is not clear yet, but we might need to check whether the logged user has permissions
(making sure it is `root` or through Polkit).

On successful authentication, the server generates a [JSON Web Token][jwt] that the client will
include in the subsequent requests. The web client stores the token in an HTTP-only
cookie[^http-only] and the CLI uses a file with restricted permissions.

[^http-only] HTTP-only cookies cannot be accessed byt client-side JavaScript.

#### Skipping the authentication

When using Agama locally in the installation media, it would be unpleasant to ask for a
user/password. For that reason, there must be a mechanism to skip the authentication step. Agama
Live could run a special service that generates a valid token and injects such a token into the
server, the CLI and the web browser.

## Links

* https://bugzilla.suse.com/show_bug.cgi?id=1219688
* https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html

[http-auth]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication
[jwt]: https://jwt.io

0 comments on commit d3ce7b6

Please sign in to comment.