Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple connection files per logical interface #114

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

koendelaat
Copy link

Fix: #113

This PR addresses the fact that some interface types generate multiple connection files per logical interface.

Disclaimer: I'm newby with respect to rust, and I struggled with some of the concepts. Please make suggestions on how to improve certain coding aspects.

I've added an openvswitch example that would fail without this fix.

There is a change to the host_config.yaml file, but I tried to make it backwards compatible. For each interface there is an additional field that specifies the connection ids belonging to this logical interface.

An example host_config.yaml:

- hostname: node1
  interfaces:
    - logical_name: br1
      connection_ids:
        - br1-br
      interface_type: ovs-bridge
    - logical_name: bridge0
      connection_ids:
        - bridge0
      mac_address: FE:C4:05:42:8B:AA
      interface_type: linux-bridge
    - logical_name: ovs0
      connection_ids:
        - ovs0-port
        - ovs0-if
      interface_type: ovs-interface
    - logical_name: eth0
      connection_ids:
        - eth0
      mac_address: 0E:4D:C6:B8:C4:72
      interface_type: ethernet
    - logical_name: eth1
      connection_ids:
        - eth1-port
        - eth1
      mac_address: 5c:c7:c9:5e:fb:ec
      interface_type: ethernet

@koendelaat
Copy link
Author

koendelaat commented Oct 11, 2024

@atanasdinov Can you give your first thoughts on this change.

Also, please indicate coding errors or weird constructs. As mentioned, I'm a new to rust.

@atanasdinov
Copy link
Collaborator

Thanks for this contribution! In fact, I was already looking at the culprit behind this and was going to push a fix.

I'll take a look early next week but can you also fix the linter issues so the CI is happy? :)

@koendelaat
Copy link
Author

Thanks for this contribution! In fact, I was already looking at the culprit behind this and was going to push a fix.

I'll take a look early next week but can you also fix the linter issues so the CI is happy? :)

Addressing the clippy issues now

@koendelaat koendelaat marked this pull request as ready for review October 14, 2024 12:58
@atanasdinov atanasdinov self-requested a review October 15, 2024 07:56
Copy link
Collaborator

@atanasdinov atanasdinov left a comment

Choose a reason for hiding this comment

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

Thanks a lot for this contribution! The implementation idea is great - I left some comments about my concerns and some improvements that we can make before merging.

Please let me know what you think, thanks!

@@ -0,0 +1 @@
target/
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can probably get rid of this file as we never build nmc in a container.

Copy link
Author

Choose a reason for hiding this comment

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

Sure, I added it because the CI builds a container, and when I tried locally this was a speedup

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is interesting, I wasn't aware it could be a speedup locally.

Copy link
Author

Choose a reason for hiding this comment

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

When built locally, a lot of files are created in the target/ directory. When trying to build the dockerimage, all the files in the target/ directory are copied over to the docker build context. This takes "long" for > 1GB of data...

So this was just a quick fix to remediate this issue. I'm also fine by removing it as we don't need the docker image in the end.

src/apply_conf.rs Outdated Show resolved Hide resolved
let connections = &interface
.connection_ids
.clone()
.unwrap_or(vec![interface.logical_name.clone()]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it safer to always include the logical name? Do we anticipate that it will always be present in the connections_id?

Copy link
Author

Choose a reason for hiding this comment

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

I added the logical_name here as a fallback mechanism mainly for backwards compatibility. Although I doubt if we need backwards compatibility (I assume same NMC version is used for generating and applying).

No, the logical name won't be always present in the connection_ids.

See also the example

    - logical_name: ovs0
      connection_ids:
        - ovs0-port
        - ovs0-if
      interface_type: ovs-interface

Copy link
Collaborator

Choose a reason for hiding this comment

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

Isn't there an ovs0.nmconnection file that we don't copy over with the current implementation?

Copy link
Author

Choose a reason for hiding this comment

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

ovs0.nmconnection is not generated by nmstate. When applying this configuration with the current implementation you'll get an error like described in #113 because the file is missing

src/apply_conf.rs Show resolved Hide resolved
src/apply_conf.rs Outdated Show resolved Hide resolved
src/generate_conf.rs Outdated Show resolved Hide resolved
src/generate_conf.rs Outdated Show resolved Hide resolved
src/generate_conf.rs Outdated Show resolved Hide resolved
src/generate_conf.rs Show resolved Hide resolved
Comment on lines 122 to 124
.get(i.name())
.cloned()
.or_else(|| Some(Vec::new())),
Copy link
Collaborator

Choose a reason for hiding this comment

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

This confirms the initial concern about applying the configurations. We should do one of the following:

  1. Always include the logical name in this list since a connection file will be present for it
  2. Never include the logical name in the list and merge it with these connections when applying

Copy link
Author

Choose a reason for hiding this comment

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

  1. is not true, see previous comment

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not saying that either of these is true, but that we should probably do one of those. However, the ovs example you gave can be contradicting if ovs0.nmconnection file is never created.

Copy link
Author

Choose a reason for hiding this comment

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

indeed, ovs0.nmconnection is never created

Signed-off-by: Koen de Laat <[email protected]>
@koendelaat koendelaat force-pushed the fix/multiple_connection_files branch 2 times, most recently from fcaaa98 to 1bda6b4 Compare October 21, 2024 11:24
Signed-off-by: Koen de Laat <[email protected]>
@koendelaat
Copy link
Author

@atanasdinov, can you please have look at the modifications?

Copy link
Collaborator

@atanasdinov atanasdinov left a comment

Choose a reason for hiding this comment

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

Sorry for the late response. Thanks for addressing the initial comments - I left a couple more but this is now very close to being ready, great job!

testdata/apply/node1/eth2.nmconnection Show resolved Hide resolved
src/types.rs Outdated Show resolved Hide resolved
src/generate_conf.rs Outdated Show resolved Hide resolved
src/apply_conf.rs Outdated Show resolved Hide resolved
src/generate_conf.rs Outdated Show resolved Hide resolved
Signed-off-by: Koen de Laat <[email protected]>
src/apply_conf.rs Show resolved Hide resolved
let mut interfaces = extract_interfaces(&net_state);
populate_connection_ids(&mut interfaces, &config_files).expect("populate ids");
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe we're fine to drop this. The test explicitly wants to verify that extract_interfaces works as expected, not necessarily the complete state of the final output.

Copy link
Author

Choose a reason for hiding this comment

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

True, however than in the assert, we've to specify empty vectors in connection_ids. Which is confusing from a developers perspective

) -> anyhow::Result<()> {
config
.iter()
.filter(|(filename, _)| filename != "lo.nmconnection")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would this cause an issue with validate_connection_ids? 👀

Copy link
Author

Choose a reason for hiding this comment

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

No, the current implementation removes the type=loopback interfaces. So this code would fail for lo.nmconnection because it cannot find a matching interface definition.

This is however not perfect I realize now, there could be more loopback connections with each their own connection file.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Precisely because we filter it out, I'd expect the validate_connection_ids to return an error and abort the generation in the cases where there are loopbacks.

Copy link
Author

Choose a reason for hiding this comment

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

I've tried to implement a better filter for loopback connections.

However I'm wondering why we exclude loopback connections at all. Current code will silently remove any loopback configuration during generation and therefor not apply any loopback connection.

src/generate_conf.rs Outdated Show resolved Hide resolved
Signed-off-by: Koen de Laat <[email protected]>
Signed-off-by: Koen de Laat <[email protected]>
@koendelaat
Copy link
Author

@atanasdinov, I've fixed the linter issues. Any other comments?

src/generate_conf.rs Outdated Show resolved Hide resolved
Co-authored-by: Atanas Dinov <[email protected]>
Signed-off-by: Koen de Laat <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

openvswitch not working properly
2 participants