Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package virt-bridge-setup for openSUSE:Factory checked in at 2025-03-18 17:42:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/virt-bridge-setup (Old) and /work/SRC/openSUSE:Factory/.virt-bridge-setup.new.19136 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "virt-bridge-setup" Tue Mar 18 17:42:32 2025 rev:2 rq:1254157 version:0.5 Changes: -------- --- /work/SRC/openSUSE:Factory/virt-bridge-setup/virt-bridge-setup.changes 2025-03-07 16:48:49.314140165 +0100 +++ /work/SRC/openSUSE:Factory/.virt-bridge-setup.new.19136/virt-bridge-setup.changes 2025-03-18 17:44:56.298684041 +0100 @@ -1,0 +2,10 @@ +Tue Mar 18 13:36:19 UTC 2025 - Antoine Ginies <agin...@suse.com> + +- version 0.5: + * better logging + * add debug option + * improve connection modification + * rename some VAR to avoid confusion + * bsc#1239445 + +------------------------------------------------------------------- Old: ---- 0.3.tar.gz _service New: ---- 0.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ virt-bridge-setup.spec ++++++ --- /var/tmp/diff_new_pack.Gj8xXr/_old 2025-03-18 17:44:56.802705220 +0100 +++ /var/tmp/diff_new_pack.Gj8xXr/_new 2025-03-18 17:44:56.806705388 +0100 @@ -16,7 +16,7 @@ # Name: virt-bridge-setup -Version: 0.3 +Version: 0.5 Release: 1%{?dist} Summary: Script to setup virtual bridges License: GPL-2.0-or-later ++++++ 0.3.tar.gz -> 0.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-bridge-setup-0.3/README.md new/virt-bridge-setup-0.5/README.md --- old/virt-bridge-setup-0.3/README.md 2025-03-07 09:16:15.000000000 +0100 +++ new/virt-bridge-setup-0.5/README.md 2025-03-18 14:40:29.000000000 +0100 @@ -1,16 +1,18 @@ -# Network Bridge Creation Script +# Network Bridge Creation Script (virt-bridge-setup) This script allows you to create a network bridge on a specified interface using `nmcli`. It simplifies the process of creating and managing network bridges for virtualization environments. This was originally created to replace the automatic "yast2 virtualization" bridge creation. +Support IPV4 only. ## Features -- Checks if NetworkManager is running. -- Creates a network bridge with the default name `br0`. -- `--force` deletes an existing bridge if used. -- `--interface` options to select the device -- Activates the bridge and configures the connection to automatically connect. +- Checks if NetworkManager is running +- Creates a network bridge with the default name `br0` +- `-f` `--force`: deletes an existing bridge if used +- `-i` `--interface`: options to select the device +- `-d` `--debug`: show debug info +- Activates the bridge and configures the connection to automatically connect ## Prerequisites @@ -20,10 +22,15 @@ ## Installation +Clone the repository: +```bash +git clone https://github.com/aginies/virt-bridge-setup.git +``` + ## Usage ```sh -python virt-bridge-setup.py -i <interface_name> [-f] +python virt-bridge-setup.py -i <interface_name> [-f] [-d] ``` ## Licence diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-bridge-setup-0.3/virt-bridge-setup.py new/virt-bridge-setup-0.5/virt-bridge-setup.py --- old/virt-bridge-setup-0.3/virt-bridge-setup.py 2025-03-07 09:16:15.000000000 +0100 +++ new/virt-bridge-setup-0.5/virt-bridge-setup.py 2025-03-18 14:40:29.000000000 +0100 @@ -4,18 +4,23 @@ """ script to create a bridge on an interface This was previously done by yast2 virtualization +IPV4 only """ import subprocess import argparse import re +import logging +import time # using the default name used previously by yast2 -BRIDGE_NAME = "br0" +BRIDGE_INTERFACE = "br0" +MY_BRIDGE = "my-br0" def run_command(cmd): """ - Launch a system command + Launch a system command and log it if debug is enabled """ + logging.debug(f"Executing command: {cmd}") proc = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, @@ -23,7 +28,7 @@ universal_newlines=True ) try: - out, errs = proc.communicate(timeout=5) + out, errs = proc.communicate(timeout=25) return out.strip(), errs.strip() except subprocess.TimeoutExpired: proc.kill() @@ -48,49 +53,67 @@ stdout, stderr = run_command(cmd) return stdout == "active", stdout + "\n" + stderr -def create_bridge(bridge_name, interface_name): +def create_bridge(bridge_interface, interface, master_name): """ Create a new bridge and on an interface """ _, stderr = run_command( - f"nmcli connection add type bridge ifname {bridge_name} con-name {bridge_name}" - ) + f"nmcli connection add type bridge ifname {bridge_interface} con-name {MY_BRIDGE}" + ) if stderr: - print(f"Error add bridge {bridge_name}: {stderr}") + logging.error(f"Error adding bridge {bridge_interface}: {stderr}") return - _, stderr = run_command(f"nmcli connection modify {interface_name} master {bridge_name}") + _, stderr = run_command(f"nmcli connection modify '{master_name}' master {bridge_interface}") if stderr: - print(f"Error modify master: {stderr}") + logging.error(f"Error modifying master: {stderr}") return if stderr == "": - print(f"Slave interface: {interface_name}, Bridge Interface {bridge_name} created") + logging.info(f"Slave interface: {interface}, Bridge Interface {bridge_interface} created") -def delete_bridge(bridge_name): +def delete_bridge(bridge_interface, bridge_name): """ delete bridge_name need --force """ - print(f"--force option used, deleting current bridge {bridge_name}") + logging.warning(f"--force option used, deleting current bridge {bridge_name}") + _, stderr = run_command(f"nmcli device delete {bridge_interface}") + if stderr: + logging.error(f"Error deleting bridge {bridge_interface}: {stderr}") + return _, stderr = run_command(f"nmcli connection delete {bridge_name}") if stderr: - print(f"Error deleting bridge {bridge_name}: {stderr}") + logging.error(f"Error deleting id {bridge_name}: {stderr}") return -def bring_bridge_up(bridge_name, interface_name): +def bring_bridge_up(bridge_interface, interface): """ Bring the bridge up and set it to autoconnect """ - print(f"Bringing the bridge {bridge_name} up, this can take some times...") - _, stderr = run_command(f"nmcli connection up {bridge_name}") + logging.info(f"Bringing the bridge {bridge_interface} up, this can take some times...") + #_, stderr = run_command(f"nmcli connection modify {MY_BRIDGE} ipv4.method auto") + #if stderr: + # logging.error(f"Error modify {MY_BRIDGE} auto method: {stderr}") + # return + run_command(f"nmcli connection modify {bridge_interface} connection.autoconnect yes") + _, stderr = run_command(f"nmcli device up {bridge_interface}") + if not wait_for_ip(bridge_interface): + logging.error(f"Failed to obtain IP address on {bridge_interface}") if stderr: - print(f"Error bringing up {bridge_name}: {stderr}") + logging.error(f"Error bringing up {bridge_interface}: {stderr}") return - # set interface_name up again to get the bridge up through this interface - _, stderr = run_command(f"nmcli connection up {interface_name}") - if stderr: - print(f"Error bringing up {interface_name}: {stderr}") - return - run_command(f"nmcli connection modify {bridge_name} connection.autoconnect yes") + +def wait_for_ip(interface, timeout=30, interval=5): + """ + Wait for the interface to get an IP address + """ + end_time = time.time() + timeout + while time.time() < end_time: + stdout, _ = run_command(f"ip addr show {interface}") + if re.search(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b', stdout): + logging.info(f"IP address obtained on {interface}: {stdout}") + return True + time.sleep(interval) + return False def get_nmcli_connection_info(): """ @@ -123,15 +146,26 @@ return connections_by_type -def find_connection(connections_by_type, target_types): +def find_device(connections_by_type, target_types): """ - Find connection by type + Find first device by type """ for conn_type, connections in connections_by_type.items(): if conn_type in target_types: + print(connections) return connections[0]['DEVICE'] return None +def find_name(connections_by_type, interface): + """ + find first connection name using interface name + """ + for _, connections in connections_by_type.items(): + for conn in connections: + if conn['DEVICE'] == interface: + return connections[0]['NAME'] + return None + def main(): """ main programm @@ -141,46 +175,55 @@ will pickup the first wireless one.") parser.add_argument('-i', '--interface', type=str, help='Specify the slave interface name') parser.add_argument('-f', '--force', action='store_true', help='Force deleting previous bridge') + parser.add_argument('-d', '--debug', action='store_true', help='Enable debug mode to show all commands executed') args = parser.parse_args() + # Set up logging based on the --debug option + if args.debug: + logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') + else: + logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + status, output = is_networkmanager_running() if status: - print("NetworkManager is running.") + logging.info("NetworkManager is running.") else: - print("NetworkManager is not running. Exiting\nDetails:") - print(output) + logging.error("NetworkManager is not running. Exiting\nDetails:") + logging.error(output) exit(1) connections_by_type = get_nmcli_connection_info() - #for conn_type, connections in connections_by_type.items(): - # print(f" {conn_type}:") - # for conn in connections: - # print(f" UUID: {conn['UUID']}, NAME: {conn['NAME']}, DEVICE: {conn['DEVICE']}") + for conn_type, connections in connections_by_type.items(): + logging.debug(f" {conn_type}:") + for conn in connections: + logging.debug(f" UUID: {conn['UUID']}, NAME: {conn['NAME']}, DEVICE: {conn['DEVICE']}") + + bridge_interface = find_device(connections_by_type, ['bridge']) + bridge_name = find_name(connections_by_type, bridge_interface) + master_interface = args.interface or find_device(connections_by_type, ['ethernet']) or \ + find_device(connections_by_type, ['wireless']) + conn_name = find_name(connections_by_type, master_interface) - bridge_interface = find_connection(connections_by_type, ['bridge']) if bridge_interface: if args.force: - delete_bridge(bridge_interface) + delete_bridge(bridge_interface, bridge_name) else: - print(f"Bridge {bridge_interface} already existing!") - print("You have 2 options:") - print("1) adjust your configuration with nmcli tool command line") - print(f"2) use --force to delete {bridge_interface} and setup another one") + logging.warning(f"Bridge {bridge_interface} already existing!") + logging.info("You have 2 options:") + logging.info("1) adjust your configuration with nmcli tool command line") + logging.info(f"2) use --force to delete {bridge_interface} and setup another one") exit(1) - interface_name = args.interface or find_connection(connections_by_type, ['ethernet']) or \ - find_connection(connections_by_type, ['wireless']) - - if not interface_name: - print("No Ethernet or WiFi connection found. Adjust your network.") + if not master_interface: + logging.error("No Ethernet or WiFi connection found. Adjust your network.") exit(1) if args.interface and not check_interface_exists(args.interface, connections_by_type): - print(f"Interface '{args.interface}' does not exist in the connections.") + logging.error(f"Interface '{args.interface}' does not exist in the connections.") exit(1) - create_bridge(BRIDGE_NAME, interface_name) - bring_bridge_up(BRIDGE_NAME, interface_name) + create_bridge(BRIDGE_INTERFACE, master_interface, conn_name) + bring_bridge_up(BRIDGE_INTERFACE, master_interface) if __name__ == "__main__": main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-bridge-setup-0.3/virt-bridge-setup.spec new/virt-bridge-setup-0.5/virt-bridge-setup.spec --- old/virt-bridge-setup-0.3/virt-bridge-setup.spec 2025-03-07 09:16:15.000000000 +0100 +++ new/virt-bridge-setup-0.5/virt-bridge-setup.spec 2025-03-18 14:40:29.000000000 +0100 @@ -16,13 +16,13 @@ # Name: virt-bridge-setup -Version: 0.3 +Version: 0.5 Release: 1%{?dist} Summary: Script to setup virtual bridges License: GPL-2.0-or-later Group: System/Management URL: https://github.com/aginies/virt-bridge-setup -Source0: %{name}-%{version}.tar.bz2 +Source0: https://github.com/aginies/virt-bridge-setup/archive/refs/tags/%{version}.tar.gz BuildArch: noarch Requires: NetworkManager BuildRequires: make