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

feat: fetch dhcp leases from network-manager via dbus #427

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

Conversation

bhoopesh369
Copy link
Contributor

@bhoopesh369 bhoopesh369 commented Jun 27, 2024

I am not sure how to test this out since, currently, we have the lease file not managed by the network manager
so the agent-6 errors out that sztp_url don't exist,
I need to make the DHCP client connect to the DHCP server via network manager
I'm not sure how to do this.

Thoughts?

closes #418

@bhoopesh369 bhoopesh369 requested a review from a team as a code owner June 27, 2024 22:25
docker-compose.yml Outdated Show resolved Hide resolved
@glimchb
Copy link
Member

glimchb commented Jun 30, 2024

sztp-agent/Dockerfile Outdated Show resolved Hide resolved
@bhoopesh369
Copy link
Contributor Author

so the bootstrapURL in agent will now be a array of strings right?

type Agent struct {
	BootstrapURL  []string
        ...
}

@glimchb
Copy link
Member

glimchb commented Jul 2, 2024

so the bootstrapURL in agent will now be a array of strings right?

type Agent struct {
	BootstrapURL  []string
        ...
}

yep, and then run/daemon will loop of this array

sztp-agent/Dockerfile Outdated Show resolved Hide resolved
scripts/run_agent.sh Outdated Show resolved Hide resolved
sztp-agent/Dockerfile Outdated Show resolved Hide resolved
sztp-agent/cmd/daemon.go Outdated Show resolved Hide resolved
@glimchb
Copy link
Member

glimchb commented Jul 3, 2024

I ran this and this is what I get

root@bf2:~/sztp# docker run --rm -it --privileged --network=host --mount type=bind,source=/var/run/dbus,target=/var/run/dbus,readonly  --mount type=bind,source=/mnt,target=/mnt --mount type=bind,source=/etc/ssh,target=/etc/ssh,readonly  --mount type=bind,source=/etc/os-release,target=/etc/os-release dbus /opi-sztp-agent daemon --bootstrap-trust-anchor-cert /mnt/opi.pem --device-end-entity-cert /mnt/nvidia_my_cert.pem --device-private-key /mnt/nvidia_private_key.pem --serial-number nvidia-serial-number
both '--bootstrap-url' and '--dhcp-lease-file' were not provided, trying to get the bootstrap URL via NetworkManager
2024/07/03 19:10:21 [INFO] Using user provides serial number: nvidia-serial-number
2024/07/03 19:10:21 lmao
2024/07/03 19:10:21 [INFO] Get the Bootstrap URL from DHCP client
2024/07/03 19:10:21 [Error] File  does not exist
2024/07/03 19:10:21 [INFO] Trying to get the URL from NetworkManager
2024/07/03 19:10:21 [INFO] sztp_redirect_url found:  []
2024/07/03 19:10:21 [INFO] failed to get Options property in DHCP4Config  / :  Object does not exist at path “/”
2024/07/03 19:10:21 [INFO] failed to get Options property in DHCP4Config  / :  Object does not exist at path “/”
2024/07/03 19:10:21 [ERROR]  sztp_redirect_urls not found in any active connection
2024/07/03 19:10:21 [ERROR]  sztp_redirect_urls not found in any active connection
2024/07/03 19:10:21 [INFO] Retrying in 5 seconds
  1. as I said before this log is confusing, because of the logic to try leases files first, I think is wrong
2024/07/03 19:10:21 [INFO] Get the Bootstrap URL from DHCP client
2024/07/03 19:10:21 [Error] File  does not exist

especially that previous line says:

both '--bootstrap-url' and '--dhcp-lease-file' were not provided, trying to get the bootstrap URL via NetworkManager
  1. not working
2024/07/03 19:10:21 [INFO] failed to get Options property in DHCP4Config  / :  Object does not exist at path “/”

while this dbus.go example works:

package main

import (
    "fmt"
    "github.com/godbus/dbus/v5"
)

func main() {
    // Connect to the system bus
    conn, err := dbus.SystemBus()
    if err != nil {
        panic(fmt.Errorf("failed to connect to system bus: %v", err))
    }

    // Get NetworkManager object
    nm := conn.Object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")

    // Get PrimaryConnection property from NetworkManager object
    var primaryConnPath dbus.ObjectPath
    err = nm.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager", "PrimaryConnection").Store(&primaryConnPath)
    if err != nil {
        panic(fmt.Errorf("failed to get PrimaryConnection property: %v", err))
    }

    // Get Active Connection object
    connActive := conn.Object("org.freedesktop.NetworkManager", primaryConnPath)

    // Get Dhcp4Config property from Active Connection object
    var dhcpPath dbus.ObjectPath
    err = connActive.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager.Connection.Active", "Dhcp4Config").Store(&dhcpPath)
    if err != nil {
        panic(fmt.Errorf("failed to get Dhcp4Config property: %v", err))
    }

    // Get Options property from DHCP4Config object
    dhcp := conn.Object("org.freedesktop.NetworkManager", dhcpPath)
    var options map[string]dbus.Variant
    err = dhcp.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager.DHCP4Config", "Options").Store(&options)
    if err != nil {
        panic(fmt.Errorf("failed to get Options property: %v", err))
    }

    // Print sztp_redirect_urls option
    sztpRedirectURLs := options["sztp_redirect_urls"].Value().(string)
    fmt.Println(sztpRedirectURLs)
}

log from real hardware:

$ cd sztp-agent
$ docker run  --rm -it -v `pwd`:/app -w /app golang:alpine go get github.com/godbus/dbus/v5
$ docker run  --rm -it --privileged -v `pwd`:/app -v /var/run/dbus:/var/run/dbus -w /app golang:alpine go run dbus.go
go: downloading github.com/godbus/dbus/v5 v5.1.0
https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data

Copy link
Member

@glimchb glimchb left a comment

Choose a reason for hiding this comment

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

code fails in real life

Copy link

codecov bot commented Jul 20, 2024

Codecov Report

Attention: Patch coverage is 37.64706% with 106 lines in your changes missing coverage. Please review.

Project coverage is 61.93%. Comparing base (42fa12e) to head (69d5484).
Report is 3 commits behind head on main.

Files Patch % Lines
sztp-agent/pkg/dhcp/network_manager.go 0.00% 45 Missing ⚠️
sztp-agent/pkg/secureagent/daemon.go 28.57% 45 Missing ⚠️
sztp-agent/pkg/dhcp/utils.go 65.85% 10 Missing and 4 partials ⚠️
sztp-agent/cmd/daemon.go 0.00% 1 Missing ⚠️
sztp-agent/cmd/run.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #427      +/-   ##
==========================================
- Coverage   66.92%   61.93%   -4.99%     
==========================================
  Files          17       20       +3     
  Lines         780      867      +87     
==========================================
+ Hits          522      537      +15     
- Misses        227      295      +68     
- Partials       31       35       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

break
}
}
return ExtractfromLine(line, `(?m)[^"]*`, 1), nil
Copy link
Member

Choose a reason for hiding this comment

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

see comment above, instead of return let's append to a list and return the list at the end...

<<: *agent
volumes:
- client-certs:/certs
- dhcp-leases-folder:/var/lib/dhclient/
Copy link
Member

Choose a reason for hiding this comment

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

in this agent6 we only test network manager, right ?
then why we map dhcp-leases-folder ? I think should remove it, no ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea will remove it

@@ -0,0 +1,9 @@
[main]
Copy link
Member

Choose a reason for hiding this comment

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

why this config is needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad, not needed
Will remove and push

@bhoopesh369
Copy link
Contributor Author

bhoopesh369 commented Jul 22, 2024

But yea I'm not able to get the bootstrap url via the network manager dbus

@glimchb do you have any idea, am I doing anything wrong?

@glimchb
Copy link
Member

glimchb commented Jul 22, 2024

But yea I'm not able to get the bootstrap url via the network manager dbus

@glimchb do you have any idea, am I doing anything wrong?

if you take this code dbus.go:

package main

import (
    "fmt"
    "github.com/godbus/dbus/v5"
)

func main() {
    // Connect to the system bus
    conn, err := dbus.SystemBus()
    if err != nil {
        panic(fmt.Errorf("failed to connect to system bus: %v", err))
    }

    // Get NetworkManager object
    nm := conn.Object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")

    // Get PrimaryConnection property from NetworkManager object
    var primaryConnPath dbus.ObjectPath
    err = nm.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager", "PrimaryConnection").Store(&primaryConnPath)
    if err != nil {
        panic(fmt.Errorf("failed to get PrimaryConnection property: %v", err))
    }

    // Get Active Connection object
    connActive := conn.Object("org.freedesktop.NetworkManager", primaryConnPath)

    // Get Dhcp4Config property from Active Connection object
    var dhcpPath dbus.ObjectPath
    err = connActive.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager.Connection.Active", "Dhcp4Config").Store(&dhcpPath)
    if err != nil {
        panic(fmt.Errorf("failed to get Dhcp4Config property: %v", err))
    }

    // Get Options property from DHCP4Config object
    dhcp := conn.Object("org.freedesktop.NetworkManager", dhcpPath)
    var options map[string]dbus.Variant
    err = dhcp.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager.DHCP4Config", "Options").Store(&options)
    if err != nil {
        panic(fmt.Errorf("failed to get Options property: %v", err))
    }

    // Print sztp_redirect_urls option
    sztpRedirectURLs := options["sztp_redirect_urls"].Value().(string)
    fmt.Println(sztpRedirectURLs)
}

and run it like this:

$ cd sztp-agent
$ docker run  --rm -it -v `pwd`:/app -w /app golang:alpine go get github.com/godbus/dbus/v5
$ docker run  --rm -it --privileged -v `pwd`:/app -v /var/run/dbus:/var/run/dbus -w /app golang:alpine go run dbus.go
go: downloading github.com/godbus/dbus/v5 v5.1.0
https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data

it works...

so I suggest to start like this with this simple approach... and then the difference is loop over all active connections... vs single connection... try to see if you can start with working example and add tiny bits and see when it breaks..

don;t work with sztp code base, just create a small standalone dbus.go file and run it individually...

@@ -0,0 +1,33 @@
/*
SPDX-License-Identifier: Apache-2.0
Copy link
Member

Choose a reason for hiding this comment

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

better file name lease.go

@@ -0,0 +1,73 @@
/*
SPDX-License-Identifier: Apache-2.0
Copy link
Member

Choose a reason for hiding this comment

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

better file name dbus.go

@glimchb
Copy link
Member

glimchb commented Jul 22, 2024

@bhoopesh369 can we split into 2 PRs?

  • one is just refactoring of getBootstrapURLsViaLeaseFile() function into dhcp folder ?
  • second is adding dbus ?

it will be easier for me to review and merge first PR asap... and then we can work on second one together...

)

// DHCPTestContent is a test content for DHCP Lease file
const DHCPTestContent = `lease {
Copy link
Member

Choose a reason for hiding this comment

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

why this is not in the test.go file ?

}

// DeleteTempTestFile deletes a temporary file
func DeleteTempTestFile(file string) {
Copy link
Member

Choose a reason for hiding this comment

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

why this is not in the test.go file ?

}

// CreateTempTestFile creates a temporary file with the given content
func CreateTempTestFile(file string, content string, _ bool) {
Copy link
Member

Choose a reason for hiding this comment

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

why this is not in the test.go file ?

@glimchb
Copy link
Member

glimchb commented Jul 22, 2024

@bhoopesh369 please check #438 .
I added proper logic imho to the discovery function.
I think the confusion before was due to mis-use of user given URL vs internal state of the agent...
Now I added one more string to be separate USER given URL
If missing - use DHCP discovery method...

@bhoopesh369
Copy link
Contributor Author

bhoopesh369 commented Jul 23, 2024

I think when the client container starts, it runs dhclient -d -v, which sends DHCP discover messages over the opi network which is managed by docker.

I think the connection is not managed by the network manager but rather by Docker’s internal networking.

Am I wrong here ? Wdyt
@glimchb

@bhoopesh369
Copy link
Contributor Author

@bhoopesh369 can we split into 2 PRs?

  • one is just refactoring of getBootstrapURLsViaLeaseFile() function into dhcp folder ?
  • second is adding dbus ?

it will be easier for me to review and merge first PR asap... and then we can work on second one together...

Yea works ig

@glimchb
Copy link
Member

glimchb commented Jul 24, 2024

Am I wrong here ? Wdyt @glimchb

you are talking about CI
I'm talking about real hardware I tested this on... unrelated to CI and docker network - we will fix it separately

@bhoopesh369
Copy link
Contributor Author

Yep, I get that

But like I have my environment set up in docker. Is there like a readme file for me to set this up in local?

@glimchb
Copy link
Member

glimchb commented Jul 24, 2024

Yep, I get that

But like I have my environment set up in docker. Is there like a readme file for me to set this up in local?

sure, https://github.com/opiproject/sztp/blob/main/scripts/run_agent.sh

@glimchb
Copy link
Member

glimchb commented Aug 2, 2024

I opened #441 to handle first and then we can rebase this PR on top
Fixed #442

@bhoopesh369
Copy link
Contributor Author

bhoopesh369 commented Aug 15, 2024

@glimchb
I tried setting up the DHCP server and client in local in the host network
but nmcli doesnt show the options eventhough i have set the DHCP config file properly
is there any script or something to run them in local?

The docker run commands I ran were:

docker run -d \
  --name dhcp \
  --env NODE_IP_SUBNET=10.1.58.0 \
  --env NODE_IP_NETMASK=255.255.254.0 \
  --env NODE_IP_RANGE_MIN=10.1.58.100 \
  --env NODE_IP_RANGE_MAX=10.1.59.200 \
  --env NODE_IP_ADDRESS=10.1.58.25 \
  --volume $(pwd)/dhcp:/opt \
  --cap-add=NET_BIND_SERVICE \
  --cap-add=NET_RAW \
  --network host \
  --entrypoint sh \
  docker.io/networkboot/dhcpd:1.3.0 \
  -e -u -x -c 'touch /var/lib/dhcp/dhcpd.leases && eval "echo \"$(cat /opt/dhcpd.conf.template)\"" > /etc/dhcp/dhcpd.conf && dhcpd -d dhcp0'
docker run -d --name dhcp-client \
  --cap-add=NET_RAW \
  --cap-add=NET_ADMIN \
  --volume dhcp-leases-folder:/var/lib/dhclient/ \
  --volume ./dhcp/dhclient.conf:/etc/dhcp/dhclient.conf \
  --network host \
  docker.io/modularitycontainers/dhcp-client:latest \
  dhclient -d -v dhcp0

I created a dummy dhcp0 interface via nmcli.

but the options 143 was not present even though the conf file had them defined.

@bhoopesh369
Copy link
Contributor Author

bhoopesh369 commented Aug 15, 2024

I tried setting up the DHCP server and client in local in the host network but nmcli doesnt show the options eventhough i have set the DHCP config file properly is there any script or something to run them in local? (

@glimchb I had messaged you in slack 2 days before but didn't receive any response

@glimchb
Copy link
Member

glimchb commented Aug 16, 2024

@glimchb I had messaged you in slack 2 days before but didn't receive any response

i'm traveling, will read soon

sztp-agent/Dockerfile Fixed Show fixed Hide fixed
@bhoopesh369 bhoopesh369 force-pushed the nm-dbus branch 2 times, most recently from bdd3fb0 to 3539961 Compare September 19, 2024 07:03
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.

fetch DHCP leases from nmcli over dbus
2 participants