PythonからNetworkManagerを操作し、Linuxのネットワーク設定を行えるようにします。
python-networkmanagerというライブラリを使用します。
このライブラリは特徴は、裏でnmcli等のツールを呼び出してパースしているのではなく、
D-busというものでNetworkManagerと直接やり取りしているところです。
残念ながらドキュメントがしっかりしていないので、自分用の備忘録を兼ねて書いていきます。
なお、こちらではRockyLinux8.5を使用しています。
準備
python-networkmanagerをインストールします。
$ pip3 install python-networkmanager
念のためNetworkManagerが動作しているか確認します。
$ systemctl status NetworkManager
● NetworkManager.service - Network Manager
Loaded: loaded (/usr/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-03-26 22:51:21 JST; 1h 36min ago
~~
ライブラリの動作確認をします。
from dbus.mainloop.glib import DBusGMainLoop
import NetworkManager
DBusGMainLoop(set_as_default=True)
print(NetworkManager.NetworkManager.Version)
実行して1.32.10
などとNetworkManagerのバージョンが表示されていれば成功です。
注意点として必ずNetworkManagerのライブラリを呼び出す前に
DBusGMainLoop(set_as_default=True)
を実行しないとエラーになってしまうようです。
デバイス情報
NetworkManagerからデバイス一覧を取得します。
現在、以下の状態になっています。
$ nmcli dev
DEVICE TYPE STATE CONNECTION
ens18 ethernet 接続済み ens18
ens19 ethernet 接続済み eth1
ens19.20 vlan 接続済み eth1.20
lo loopback 管理無し --
以下のプログラムを実行すると
from dbus.mainloop.glib import DBusGMainLoop
import NetworkManager
DBusGMainLoop(set_as_default=True)
devices = NetworkManager.NetworkManager.GetDevices()
for dev in devices:
print('device :', dev.Interface)
print('state :', NetworkManager.const('device_state', dev.State))
print('type :', NetworkManager.const('device_type', dev.DeviceType))
for addr in dev.Ip4Config.Addresses:
print('addr : {}/{}'.format(addr[0], addr[1]))
print('------------------')
このような結果になります。
$ python3 device.py
device : lo
state : unmanaged
type : generic
addr : 127.0.0.1/8
------------------
device : ens18
state : activated
type : ethernet
addr : 192.168.50.100/24
------------------
device : ens19
state : activated
type : ethernet
addr : 172.16.10.106/24
------------------
device : ens19.20
state : activated
type : vlan
addr : 172.16.20.70/24
------------------
ポイントを解説します。
NetworkManager.NetworkManager.GetDevices()
でデバイスの一覧をList型で取得できます。
オブジェクトのプロパティから各種情報を参照できます。
NetworkManager.const()
で定数値を名前に変換することができます。
参考文献
https://pythonhosted.org/python-networkmanager/
https://github.com/seveas/python-networkmanager