Created
February 20, 2012 08:09
-
-
Save ecarnevale/1868370 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
#builtin | |
import re, shutil, json, urllib2, os, sys | |
from string import Template | |
from subprocess import call | |
#external | |
import netifaces | |
server_host = '172.26.78.10' | |
class Station: | |
list_tpl = '%(code)s\t%(name)s' | |
kiosk_file = '%(home)s/chrome_god_config.yml' | |
kiosk_content = "url: 'google-chrome --kiosk http://%(server_host)s/stations/%(id)s'\n" | |
def __init__(self, station_id, code, name): | |
self.station_id = station_id | |
self.code = code | |
self.name = name | |
def list_template(self): | |
cls = self.__class__ | |
return cls.list_tpl % \ | |
{ 'code': self.code, 'name': self.name } | |
def save_on_kiosk_file(self): | |
cls = self.__class__ | |
file_name = cls.kiosk_file % \ | |
{ 'home': '/home/traveller' } | |
f = open(file_name, 'w') | |
f.write(cls.kiosk_content % \ | |
{ 'id': self.station_id, 'server_host': server_host }) | |
f.close() | |
os.system( 'chown traveller:traveller %s' % file_name) | |
@classmethod | |
def all(cls): | |
url = 'http://%(host)s/stations.json' % {'host': server_host} | |
try: | |
content = urllib2.urlopen(url).read() | |
jsonized = json.loads(content) | |
stations = [] | |
for obj in jsonized: | |
obj = obj['station'] | |
stations.append(Station(obj['id'], obj['code'], obj['description'])) | |
return stations | |
except urllib2.URLError as err: pass | |
print 'Impossibile ottenere la lista delle stazioni dal server' | |
print 'Sara\' necessario inserire a mano l\'ID numerico' | |
return [] | |
class IFace: | |
raw_iface_re = re.compile('^eth\\d') | |
list_tpl = '%(code)s\t%(mac)s' | |
def __init__(self, code): | |
self.code = code | |
self.mac = netifaces.ifaddresses(code)[netifaces.AF_LINK][0]['addr'] | |
def list_template(self): | |
cls = self.__class__ | |
return cls.list_tpl % \ | |
{ 'code': self.code, 'mac': self.mac } | |
@classmethod | |
def all(cls): | |
raw_ifaces = netifaces.interfaces() | |
eth_ifaces = [] | |
for iface in raw_ifaces: | |
if cls.raw_iface_re.match(iface): | |
eth_ifaces.append(IFace(iface)) | |
return eth_ifaces | |
class NetworkingService: | |
net_template = Template('auto lo\n' + | |
'iface lo inet loopback\n' + | |
'\n' + | |
'auto $iface\n' + | |
'iface $iface inet static\n' + | |
'address $ip\n' + | |
'netmask $netmask\n' + | |
'$network\n' + | |
'$broadcast\n') | |
config_file = '/etc/network/interfaces' | |
daemon = 'networking' | |
@classmethod | |
def backup_conf(cls): | |
backup_file = cls.config_file + '.bak' | |
shutil.move(cls.config_file, backup_file) | |
@classmethod | |
def save_conf(cls, iface, ip, netmask, network = '', broadcast = ''): | |
if len(network) > 0: | |
network = 'network %(ip)s'%{'ip':network} | |
if len(broadcast) > 0: | |
broadcast = 'broadcast %(ip)s'%{'ip':broadcast} | |
content = cls.net_template.substitute( | |
iface = iface, | |
ip = ip, | |
netmask = netmask, | |
network = network, | |
broadcast = broadcast | |
) | |
f = open(cls.config_file, 'w') | |
f.write(content) | |
f.close() | |
@classmethod | |
def restart(cls): | |
call(['/etc/init.d/networking', 'stop']) | |
call(['start', cls.daemon]) | |
@staticmethod | |
def is_connected(): | |
print 'Controllo connessione con %(host)s ...' % { 'host': server_host } | |
try: | |
response=urllib2.urlopen('http://' + server_host) | |
print 'Connessione presente!' | |
return True | |
except urllib2.URLError as err: pass | |
print 'Connessione assente!' | |
return False | |
class StepFirst: | |
ip_re = re.compile('^\d{1,3}(\.\d{1,3}){3}$') | |
@classmethod | |
def run(cls, do_backups = True): | |
print 'STEP 1 - INTERFACCE DI RETE DISPONIBILI' | |
print 'CODICE\tMAC' | |
ifaces = IFace.all() | |
print '\n'.join([iface.list_template() for iface in ifaces]) | |
print 'Annotare il MAC Address per la rete desiderata.' | |
sel_iface = cls.ask_iface(ifaces) | |
print 'CONFIGURAZIONE INTERFACCIA DI RETE %(code)s' % { 'code': sel_iface.code } | |
ip = cls.ask_ip('Indirizzo IP (es. 192.168.0.1)') | |
netmask = cls.ask_ip('Netmask (es. 255.255.255.0)') | |
network = cls.ask_ip('Network (es. 192.168.0.0; lasciare vuoto per usare quello rilevato)', True) | |
broadcast = cls.ask_ip('Broadcast (eg. 192.168.0.254; lasciare vuoto per usare quello rilevato)', True) | |
if do_backups: | |
print 'Rinomino %(config)s -> %(config)s.bak ...' % \ | |
{'config': NetworkingService.config_file} | |
NetworkingService.backup_conf() | |
print 'Salvo nuovo %(config)s ...' % \ | |
{'config': NetworkingService.config_file} | |
NetworkingService.save_conf(iface.code, ip, netmask, network, broadcast) | |
print 'Riavvio %(daemon)s ...' % \ | |
{'daemon': NetworkingService.daemon} | |
NetworkingService.restart() | |
@staticmethod | |
def ask_iface(ifaces): | |
iface = None | |
while iface == None: | |
iface_id = raw_input('Inserire il codice della rete da configurare (es. eth7: ') | |
iface = find(lambda iface: iface.code == iface_id, ifaces) | |
if iface: | |
break | |
print 'Impossibile trovare questo codice nell\'elenco!' | |
return iface | |
@classmethod | |
def ask_ip(cls, msg, optional = False): | |
msg += ': ' | |
ip = None | |
while ip == None: | |
ip = raw_input(msg) | |
if optional and len(ip) == 0: | |
break | |
if not cls.ip_re.match(ip): | |
print 'Indirizzo non corretto!' | |
ip = None | |
return ip | |
class StepSecond: | |
@classmethod | |
def run(cls): | |
print 'STEP 2 - CONFIGURAZIONE STAZIONE' | |
print 'Collegamento al server...' | |
print 'CODICE\tSTAZIONE' | |
stations = Station.all() | |
print '\n'.join([station.list_template() for station in stations]) | |
sel_station = cls.ask_station(stations) | |
print 'Salvo nuova configurazione Kiosk' | |
sel_station.save_on_kiosk_file() | |
print 'Operazione completata!' | |
@staticmethod | |
def ask_station(stations): | |
station = None | |
while station == None: | |
station_id = raw_input('Inserire il codice per la stazione desiderata: ') | |
if not stations: #se il server ha restituito la lista delle stazioni, allora controllo che quella inserita sia valida, altrimenti no | |
return Station(station_id.rstrip(), 'offline', 'stazione inserita a mano') | |
station = find(lambda station: station.code == station_id, stations) | |
if not station: | |
print 'Impossibile trovare il codice nell\'elenco stazioni' | |
return station | |
def find(f, seq): | |
"""Return first item in sequence where f(item) == True.""" | |
for item in seq: | |
if f(item): | |
return item | |
def ask_yn(msg): | |
msg += ': [s/n]' | |
resp = None | |
while resp == None: | |
resp = raw_input(msg).lower() | |
if resp == 's': resp = True | |
elif resp == 'n': resp = False | |
else: resp = None | |
return resp | |
if os.getuid() != 0: | |
print "Devi lanciare lo script con privilegi di amministratore:" | |
print " sudo %s" % os.path.basename(__file__) | |
sys.exit(1) | |
StepFirst.run() | |
while not NetworkingService.is_connected(): | |
print 'Impossibile raggiungere il server con questa configurazione.' | |
response = ask_yn('Premere S per configurare nuovamente la rete, N per proseguire allo step 2') | |
if response: | |
StepFirst.run(False) | |
else: | |
break | |
StepSecond.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment