Update hosts file with exclusive lock

This commit is contained in:
Disassembler 2018-11-02 15:25:48 +01:00
parent 1fdf65c850
commit e77ab483df
No known key found for this signature in database
GPG Key ID: 524BD33A0EE29499
2 changed files with 22 additions and 25 deletions

View File

@ -216,15 +216,14 @@ class VMMgr:
app = os.environ['LXC_NAME']
pid = os.environ['LXC_PID']
# Lease the first unused IP to the container
ip = tools.get_unused_ip()
tools.update_hosts_lease(ip, app)
ip = tools.update_hosts_lease(app, True)
tools.set_container_ip(pid, ip)
def unregister_container(self):
# Extract the variables from values given via lxc.hook.post-stop hook
app = os.environ['LXC_NAME']
# Release the container IP
tools.update_hosts_lease(None, app)
tools.update_hosts_lease(app, False)
# Remove ephemeral layer data
tools.clean_ephemeral_layer(app)

View File

@ -3,6 +3,7 @@
import bcrypt
import dns.exception
import dns.resolver
import fcntl
import os
import requests
import shutil
@ -109,30 +110,27 @@ def shutdown_vm():
def reboot_vm():
subprocess.run(['/sbin/reboot'])
def get_unused_ip():
def update_hosts_lease(app, is_request):
# This is a poor man's DHCP server which uses /etc/hosts as lease database
# Leases the first unused IP from range 172.17.0.0/16
leased = []
with open('/etc/hosts', 'r') as f:
for line in f.read().splitlines():
if line.startswith('172.17'):
ip = line.split()[0].split('.')
leased.append(int(ip[2]) * 256 + int(ip[3]))
for i in range(1, 65534):
if i not in leased:
break
return '172.17.{}.{}'. format(i // 256, i % 256)
def update_hosts_lease(ip, app):
hosts = []
with open('/etc/hosts', 'r') as f:
for line in f:
if not line.strip().endswith(' {}'.format(app)):
hosts.append(line)
if ip:
hosts.append('{} {}\n'.format(ip, app))
with open('/etc/hosts', 'w') as f:
f.writelines(hosts)
ip = None
with open('/var/lock/hosts.lock', 'w') as lock:
fcntl.lockf(lock, fcntl.LOCK_EX)
with open('/etc/hosts', 'r') as f:
leases = [l.strip().split(' ', 1) for l in f]
if is_request:
used_ips = [l[0] lor l in leases]
for i in range(2, 65534):
ip = '172.17.{}.{}'. format(i // 256, i % 256)
if ip not in used_ips:
leases.append([ip, app])
break
else:
leases = [l for l in leases if l[1] != app]
with open('/etc/hosts', 'w') as f:
for lease in leases:
f.write('{} {}\n'.format(lease[0], lease[1]))
return ip
def set_container_ip(pid, ip):
# Set IP in container based on PID given via lxc.hook.start-host hook