Skip to content

Instantly share code, notes, and snippets.

@simon-engledew
Created March 27, 2011 09:45
Show Gist options
  • Save simon-engledew/889091 to your computer and use it in GitHub Desktop.
Save simon-engledew/889091 to your computer and use it in GitHub Desktop.
snack based ncurses script for configuring ubuntu networking, first pass
from __future__ import with_statement
import snack, ipaddr, optparse, re, shlex
parser = optparse.OptionParser()
parser.add_option('--no-cancel', action='store_true', dest='no_cancel', help='Do not display a cancel button')
parser.add_option('--title', action='store', dest='title', default='Configure Networking', help='set the form title')
parser.add_option('--interface', action='store', dest='interface', default='eth0', help='interface to edit')
parser.add_option('--interfaces-file', action='store', dest='interfaces_file', default='/etc/network/interfaces', help='target interfaces file to edit')
parser.add_option('--dns-file', action='store', dest='dns_file', default='/etc/resolvconf/resolv.conf.d/base', help='target dns file to edit')
options, args = parser.parse_args()
def bind(object, **kwargs):
for key, value in kwargs.items():
setattr(object, key, value)
return object
VALUES = dict()
ERRORS = dict()
OUTPUT = dict()
screen = snack.SnackScreen()
def LabelledEntry(name, label):
return (
bind(snack.Label(label), name=name, label=label, form=dict(padding=(2, 0, 1, 0), anchorRight=1)),
bind(snack.Entry(width=20), name=name, form=dict(padding=(0, 0, 1, 0)))
)
def to_ip_address(s):
try:
return ipaddr.IPAddress(s)
except ValueError:
return None
def to_ip_network(address, netmask):
try:
return ipaddr.IPNetwork('%s/%s' % (address, netmask))
except ValueError:
return None
try:
screen.pushHelpLine(' <Tab>/<Alt-Tab> between elements | * Optional Address')
while True:
fields = [
LabelledEntry('address', 'IP Address '),
LabelledEntry('netmask', 'Netmask '),
LabelledEntry('gateway', 'Gateway '),
LabelledEntry('dns[0]', 'Primary DNS '),
LabelledEntry('dns[1]', '* Secondary DNS '),
]
form = snack.GridForm(screen, options.title, 1, 2)
grid = snack.Grid(max(len(row) for row in fields), len(fields))
if not options.no_cancel:
button_grid = snack.Grid(2, 1)
button_grid.setField(bind(snack.Button('OK'), name='ok'), 0, 0, padding=(0, 2, 2, 0))
button_grid.setField(bind(snack.Button('Canel'), name='cancel'), 1, 0, padding=(2, 2, 0, 0))
else:
button_grid = snack.Grid(1, 1)
button_grid.setField(bind(snack.Button('OK'), name='ok'), 0, 0, padding=(0, 2, 0, 0))
if len(ERRORS) > 0:
screen.pushHelpLine(' <Tab>/<Alt-Tab> between elements | * Optional Address | ! Invalid Address')
for y, row in enumerate(fields):
for x, field in enumerate(row):
if isinstance(field, snack.Entry):
field.set(VALUES.get(field.name, ''))
elif isinstance(field, snack.Label) and hasattr(field, 'name') and field.name in ERRORS:
field.setText('! ' + field.label)
grid.setField(field, x, y, **field.__dict__.get('form', {}))
form.add(grid, 0, 0)
form.add(button_grid, 0, 1)
result = form.runOnce()
for row in fields:
for field in row:
if isinstance(field, snack.Entry):
VALUES[field.name] = field.value()
if len(ERRORS) > 0:
screen.popHelpLine()
ERRORS = dict()
address = to_ip_address(VALUES['address'])
if not address: ERRORS['address'] = True
else:
OUTPUT['address'] = address
network = to_ip_network(address, VALUES['netmask'])
if not network: ERRORS['netmask'] = True
else: OUTPUT['netmask'] = network.netmask
for key in ['gateway', 'dns[0]']:
address = to_ip_address(VALUES[key])
if not address: ERRORS[key] = True
else: OUTPUT[key] = address
for key in ['dns[1]']:
if len(VALUES[key]) > 0:
address = to_ip_address(VALUES[key])
if not address: ERRORS[key] = True
else: OUTPUT[key] = address
if result.name == 'cancel': break
if len(ERRORS) == 0:
with open(options.interfaces_file, 'r') as f:
tokens = ' '.join(shlex.split(f.read(), comments=True))
tokens = re.compile(' (?=auto|iface)').split(tokens)
# filter out the interface we are working on
tokens = [interface for interface in tokens if not re.search('^(?:auto|iface) %(interface)s' % options.__dict__, interface)]
with open(options.interfaces_file, 'w+') as f:
result = []
result.append('iface %(interface)s inet static' % options.__dict__)
result.append('address %(address)s netmask %(netmask)s gateway %(gateway)s' % OUTPUT)
result.append('dns-nameservers %(dns[0])s' % OUTPUT)
if 'dns[1]' in OUTPUT:
result.append(' %(dns[1])s' % OUTPUT)
tokens.append(' '.join(result))
print >> f, '\n'.join(tokens)
break
finally:
screen.finish()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment