HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Editing /etc/network/interfaces

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
interfacesnetworkeditingetc

Problem

I am trying to change static to dhcp in the /etc/network/interfaces file and vice versa using Python.

def setMode(mode,port,interfaces):
    #If the port's mode is not configured in the interface file, add a line for it, and return
    if "iface "+port+" inet " not in interfaces:
        newLine="\niface "+port+" inet "+mode
        interfaces="".join([interfaces,newLine])
        return interfaces

    #split the string by port to get to the line containing the port's ip mode
    #then split the third element of the resulting list by newline to isolate the end of that line
    split1=interfaces.partition(port+" inet ")
    split2=split1[2].partition("\n")
    #split the isolated line by space to get each word in it. the last element in the resulting list will be the current ip mode
    line=split2[0].split(" ")
    #if the current mode matches the new mode, return
    if line[len(line)-1] == mode:
        line=" ".join(line)
        split2="".join([line,split2[1],split2[2]])
        interfaces="".join([split1[0],split1[1],split2])
        return interfaces
    #otherwise set the last element to the new mode
    line[len(line)-1]=mode
    #join the line and lines back to recreate the full string
    line=" ".join(line)
    split2="".join([line,split2[1],split2[2]])
    interfaces="".join([split1[0],split1[1],split2])

    return interfaces


This is the code I am taking over with. I am using str.partition() to achieve this. mode == static or dhcp, port = eth8 or eth0, etc, interfaces = copy of interfaces file.

/etc/network/interfaces looks like this:

auto lo
iface lo inet loopback

auto eth8
iface eth8 inet static
address 10.8.100.36
netmask 255.255.0.0
gateway 10.8.1.1

Solution

The splitting / partitioning makes this very complicated and hard to follow. Instead of splitting and then putting the pieces back together, it would be vastly simpler to replace with a regex, for example:

import re

def set_mode(mode, iface, interfaces):
    """
    Set the mode for the specified interface
    :param mode: 'dhcp' or 'static'
    :param iface: name of the interface, for example eth1, eth2, ...
    :param interfaces: content of /etc/network/interfaces
    :return: updated content, to be saved in /etc/network/interfaces
    """
    iface_prefix = 'iface {} inet '.format(iface)
    iface_entry = iface_prefix + mode
    if iface_prefix in interfaces:
        interfaces = re.sub(iface_prefix + r'.*', iface_entry, interfaces)
    else:
        interfaces += '\n' + iface_entry
    return interfaces


For your sample file, the following gives me the same output with the original method and this new one:

with open('./interfaces') as fh:
    content = fh.read()
    print set_mode('static', 'eth8', content)
    print '---'
    print set_mode('dhcp', 'eth8', content)
    print '---'
    print set_mode('dhcp', 'eth1', content)


Coding style

The original code has several issues that violate PEP8, the official coding style guide of Python:

  • Use snake_case for function and variable names (that's why I renamed setMode to set_mode



  • Put spaces around operators: a=something instead of a = something



  • A docstring is strongly recommended for the set_mode function

Code Snippets

import re


def set_mode(mode, iface, interfaces):
    """
    Set the mode for the specified interface
    :param mode: 'dhcp' or 'static'
    :param iface: name of the interface, for example eth1, eth2, ...
    :param interfaces: content of /etc/network/interfaces
    :return: updated content, to be saved in /etc/network/interfaces
    """
    iface_prefix = 'iface {} inet '.format(iface)
    iface_entry = iface_prefix + mode
    if iface_prefix in interfaces:
        interfaces = re.sub(iface_prefix + r'.*', iface_entry, interfaces)
    else:
        interfaces += '\n' + iface_entry
    return interfaces
with open('./interfaces') as fh:
    content = fh.read()
    print set_mode('static', 'eth8', content)
    print '---'
    print set_mode('dhcp', 'eth8', content)
    print '---'
    print set_mode('dhcp', 'eth1', content)

Context

StackExchange Code Review Q#62451, answer score: 5

Revisions (0)

No revisions yet.