Skip to content

Add a Network service#571

Merged
imobachgs merged 99 commits intomasterfrom
network-service-2
Jun 1, 2023
Merged

Add a Network service#571
imobachgs merged 99 commits intomasterfrom
network-service-2

Conversation

@imobachgs
Copy link
Copy Markdown
Contributor

@imobachgs imobachgs commented May 10, 2023

Problem

Agama does not offer a service to set up the network. The web UI talks directly to NetworkManager and the CLI/autoinstallation does not support configuring the network.

Solution

Trello card: https://trello.com/c/1kiDu6yN/ and https://trello.com/c/TCJqEQ2z/

This PR introduces a new service that allows configuring the network. The code is organized into these modules:

  • model contains the types that represent the network concepts. They are supposed to be agnostic from the actual network service (e.g., NetworkManager).
  • adapter offers an abstraction to support other backends in the future (if needed).
  • dbus includes the D-Bus service implementation.
  • nm implements support for interacting with NetworkManager.
Example of a network D-Bus tree
$ sudo busctl --address unix:path=/run/agama/bus tree org.opensuse.Agama.Network1
└─/org
  └─/org/opensuse
    └─/org/opensuse/Agama
      └─/org/opensuse/Agama/Network1
        ├─/org/opensuse/Agama/Network1/connections
        │ ├─/org/opensuse/Agama/Network1/connections/0
        │ ├─/org/opensuse/Agama/Network1/connections/1
        │ ├─/org/opensuse/Agama/Network1/connections/10
        │ ├─/org/opensuse/Agama/Network1/connections/2
        │ ├─/org/opensuse/Agama/Network1/connections/3
        │ ├─/org/opensuse/Agama/Network1/connections/4
        │ ├─/org/opensuse/Agama/Network1/connections/5
        │ ├─/org/opensuse/Agama/Network1/connections/6
        │ ├─/org/opensuse/Agama/Network1/connections/7
        │ ├─/org/opensuse/Agama/Network1/connections/8
        │ └─/org/opensuse/Agama/Network1/connections/9
        └─/org/opensuse/Agama/Network1/devices
          ├─/org/opensuse/Agama/Network1/devices/0
          ├─/org/opensuse/Agama/Network1/devices/1
          ├─/org/opensuse/Agama/Network1/devices/2
          ├─/org/opensuse/Agama/Network1/devices/3
          ├─/org/opensuse/Agama/Network1/devices/4
          └─/org/opensuse/Agama/Network1/devices/5
Exposing a wireless network
$ sudo busctl --address unix:path=/run/agama/bus introspect org.opensuse.Agama.Network1 /org/opensuse/Agama/Network1/connections/4
NAME                                            TYPE      SIGNATURE RESULT/VALUE                                                   FLAGS
org.freedesktop.DBus.Introspectable             interface -         -                                                              -
.Introspect                                     method    -         s                                                              -
org.freedesktop.DBus.Peer                       interface -         -                                                              -
.GetMachineId                                   method    -         s                                                              -
.Ping                                           method    -         -                                                              -
org.freedesktop.DBus.Properties                 interface -         -                                                              -
.Get                                            method    ss        v                                                              -
.GetAll                                         method    s         a{sv}                                                          -
.Set                                            method    ssv       -                                                              -
.PropertiesChanged                              signal    sa{sv}as  -                                                              -
org.opensuse.Agama.Network1.Connection          interface -         -                                                              -
.Id                                             property  s         "Vodafone_4960_7DRS"                                           emits-change
.UUID                                           property  s         "889e7b38-82ed-42d4-bee2-5d10ba9c706b"                         emits-change
org.opensuse.Agama.Network1.Connection.IPv4     interface -         -                                                              -
.Addresses                                      property  a(su)     1 "192.168.0.99" 24                                            emits-change writable
.Gateway                                        property  s         "192.168.0.1"                                                  emits-change writable
.Method                                         property  y         1                                                              emits-change writable
.Nameservers                                    property  as        2 "6.6.6.6" "8.8.8.8"                                          emits-change writable
org.opensuse.Agama.Network1.Connection.Wireless interface -         -                                                              -
.Mode                                           property  y         0                                                              emits-change writable
.Password                                       property  s         ""                                                             emits-change writable
.SSID                                           property  ay        18 86 111 100 97 102 111 110 101 95 52 57 54 48 95 55 68 82 83 emits-change writable
.Security                                       property  y         3                                                              emits-change

Documentation

This PR updates the network_support_design.md document, as we decided not to rely on third-party tools (that's the reason the branch is called network-service-2 😅).

In addition to that, we tried to document the code to make it easier to contribute.

Library documentation

Captura desde 2023-05-24 10-27-19

Testing

As with most of our Rust code, it contains a few unit tests. I will try to add more before merging.

Why is it still in draft mode?

  • Reload after saving (to get the correct UUIDs and clean-up removed devices)
  • Extend the documentation
  • Adapt to agama-dbus-server package (see Rust locale #533).
  • (optional) Report which connections failed to add/update/remove (some Report struct).
  • (optional) Better error handling (using anyhow).

What's next?

@coveralls
Copy link
Copy Markdown

coveralls commented May 10, 2023

Coverage Status

Changes unknown
when pulling 0787522 on network-service-2
into ** on master**.

Copy link
Copy Markdown
Contributor

@mvidner mvidner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm being extra pedantic about API naming consistency here...

The aspects to observe are

  • pluralization
  • capitalization

For pluralization, it makes sense to use the plural name whenever there is a collection: /.../things and /.../things/1, /.../things/33 (as opposed to the singular /.../thing/33)

For capitalization,

  • the Naming Conventions want to use CamelCase even for objects
  • here we are following the systemd convention of naming the objects in lowercase
  • other parts of Agama use CamelCase for object names

IMHO we should use CamelCase
(but before reaching this conclusion I have adjusted the docs to document the code reality)

.connections_paths()
.iter()
.filter_map(|c| ObjectPath::try_from(c.clone()).ok())
.collect()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NP: I've found that the resulting array is not sorted, at least not by ObjectPath

/// Adds a new network connection.
///
/// * `name`: connection name.
/// * `ty`: connection type (see [crate::model::DeviceType]).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, the argument name is exposed in D-Feet and my first thought was: "Ty... pe? Why the truncation?"

Using type_ is slightly awkward, but https://docs.rs/zbus/3.12.0/zbus/attr.dbus_interface.html doesn't let us name parameters freely so it is IMHO the best option.

/// Adds a new network connection.
///
/// * `name`: connection name.
/// * `ty`: connection type (see [crate::model::DeviceType]).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About the value of the type argument:

It should be documented where the D-Bus API user can easily reference it.

So I'm going to add /doc/dbus/*Network1*.doc.xml files and document it there.

Copy link
Copy Markdown
Contributor

@mvidner mvidner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strings vs ObjectPaths:

objects
.devices_paths()
.iter()
.filter_map(|c| ObjectPath::try_from(c.clone()).ok())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a strongly typed language I would expect the object paths to be always valid, unless coming as user input or as arguments to a constructor, which is not the case here.

}

/// Returns all devices paths.
pub fn devices_paths(&self) -> Vec<String> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be using specialized strings that are guaranteed to be valid object paths.
The zbus_names crate exists exactly for this purpose and... it does not include object paths... because they appear on the wire so the type lives in zvariant.

So,

use zvariant::ObjectPath;
    pub fn devices_paths(&self) -> Vec<OwnedObjectPath> {
or
    pub fn devices_paths(&self) -> Vec<ObjectPath> {

here and in many other places.
With respect to the D-Bus API it is an implementation detail, so we can leave it for later.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.

@mvidner
Copy link
Copy Markdown
Contributor

mvidner commented May 29, 2023

For pluralization, it makes sense to use the plural name whenever there is a collection: /.../things and /.../things/1, /.../things/33 (as opposed to the singular /.../thing/33)

BTW I don't have a source for this, it is "original research" 😄 and the reasoning is that the tree is more compact when we use the same word forms for both the "manager" and the "items"

Copy link
Copy Markdown
Contributor

@jreidinger jreidinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so now after updates only important stuff for me is DBus naming ( consistency and that ty as property ). And in general I would like to see type_ instead of ty as mvidner agrees with me :) Others can wait for next PR

@imobachgs
Copy link
Copy Markdown
Contributor Author

IMHO we should use CamelCase (but before reaching this conclusion I have adjusted the docs to document the code reality)

I would say we are using systemd capitalization style in new code (basically in storage). We could re-evaluate that decision but, at least, we should document why we went that road (and plan for adopting it in the rest of the APIs).

@imobachgs
Copy link
Copy Markdown
Contributor Author

OK, so now after updates only important stuff for me is DBus naming ( consistency and that ty as property ). And in general I would like to see type_ instead of ty as mvidner agrees with me :) Others can wait for next PR

OK, I still do not like type_. To be clear, the property is exposed as Type over D-Bus, so it remains as an internal detail.

I have found more usages of ty in the Rust world:

However, I can understand that it looks weird, so I have renamed it by now to unblock this PR.

Copy link
Copy Markdown
Contributor

@mvidner mvidner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Just a .changes entry is missing I think

@imobachgs
Copy link
Copy Markdown
Contributor Author

Thank you!

Just a .changes entry is missing I think

Oops, good point. I will add it.

Copy link
Copy Markdown
Contributor

@mvidner mvidner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay!

@imobachgs imobachgs merged commit 2c34acd into master Jun 1, 2023
@imobachgs imobachgs deleted the network-service-2 branch June 1, 2023 09:27
@imobachgs imobachgs mentioned this pull request Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants