Skip to content

Commit

Permalink
Check for ovs-vsctl presence when using OVS with clab (fixes #1799) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ipspace authored Jan 15, 2025
1 parent bb3271d commit 2c10748
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
6 changes: 6 additions & 0 deletions netsim/cli/external_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ def add_netlab_path() -> None:

return

"""
has_command: figures out whether a command is available
"""
def has_command(cmd: str) -> bool:
return bool(run_command(['bash','-c',f'command -v {cmd}'],check_result=True,ignore_errors=True))

"""
run_command: Execute an external command specified as a string or a list of CLI parameters
Expand Down
12 changes: 3 additions & 9 deletions netsim/cli/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ def check_crazy_pip3(args: argparse.Namespace) -> None:
os.environ['FLAG_PIP'] = os.environ['FLAG_PIP'] + ' --user'
os.environ['FLAG_USER'] = 'Y'

"""
has_command: figures out whether a command is available
"""
def has_command(cmd: str) -> typing.Union[bool,int,str]:
return external_commands.run_command(['bash','-c',f'command -v {cmd}'],check_result=True,ignore_errors=True)

"""
set_sudo_flag: figures out whether we have 'sudo' installed and whether the user
is a root user if there's no sudo.
Expand All @@ -113,7 +107,7 @@ def set_sudo_flag() -> None:
if os.getuid() == 0:
return

if has_command('sudo'):
if external_commands.has_command('sudo'):
os.environ['SUDO'] = "sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a"
return

Expand All @@ -138,7 +132,7 @@ def check_script(path: str, args: argparse.Namespace) -> None:
cmds = script.read_text()

if ' apt-get ' in cmds:
if not has_command('apt-get'):
if not external_commands.has_command('apt-get'):
log.error(
'This script uses apt-get command that is not available on your system',
more_hints='Most netlab installation scripts work on Ubuntu (and probably on Debian)',
Expand All @@ -148,7 +142,7 @@ def check_script(path: str, args: argparse.Namespace) -> None:
if ' pip3 ' not in cmds:
return

if not has_command('pip3'):
if not external_commands.has_command('pip3'):
log.error(
'This script uses pip3 command that is not available on your system',
more_hints="Install pip3 (for example, with 'sudo apt-get install python-pip3')",
Expand Down
24 changes: 23 additions & 1 deletion netsim/providers/clab.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def list_bridges( topology: Box ) -> typing.Set[str]:
return { l.bridge for l in topology.links if l.bridge and l.node_count > 2 and not 'external_bridge' in l.clab }

def use_ovs_bridge( topology: Box ) -> bool:
return topology.defaults.providers.clab.bridge_type == "ovs-bridge"
return topology.defaults.providers.clab.bridge_type == "ovs-bridge"

def create_linux_bridge( brname: str ) -> bool:
if external_commands.run_command(
Expand Down Expand Up @@ -50,7 +50,26 @@ def destroy_linux_bridge( brname: str ) -> bool:
log.print_verbose( f"Delete Linux bridge '{brname}': {status}" )
return True

_OVS_OK: bool = False
def check_ovs_installation() -> None:
global _OVS_OK
if _OVS_OK:
return

if not external_commands.has_command('ovs-vsctl'):
log.error(
'Open vSwitch package is not installed, you cannot use OVS bridges with containerlab',
more_hints = [
'This error was caused by defaults.providers.clab.bridge_type being set to ovs-bridge',
'Use "sudo apt install openvswitch-switch" on Ubuntu or an equivalent command to install Open vSwitch'],
category=log.FatalError,
module='clab')
log.exit_on_error()

_OVS_OK = True

def create_ovs_bridge( brname: str ) -> bool:
check_ovs_installation()
status = external_commands.run_command(
['sudo','ovs-vsctl','add-br',brname],check_result=True,return_stdout=True)
if status is False:
Expand Down Expand Up @@ -168,6 +187,9 @@ def node_post_transform(self, node: Box, topology: Box) -> None:
self.create_extra_files_mappings(node,topology)

def post_configuration_create(self, topology: Box) -> None:
if use_ovs_bridge(topology):
check_ovs_installation()

for n in topology.nodes.values():
if n.get('clab.binds',None):
self.create_extra_files(n,topology)
Expand Down

0 comments on commit 2c10748

Please sign in to comment.