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'] app = os.environ['LXC_NAME']
pid = os.environ['LXC_PID'] pid = os.environ['LXC_PID']
# Lease the first unused IP to the container # Lease the first unused IP to the container
ip = tools.get_unused_ip() ip = tools.update_hosts_lease(app, True)
tools.update_hosts_lease(ip, app)
tools.set_container_ip(pid, ip) tools.set_container_ip(pid, ip)
def unregister_container(self): def unregister_container(self):
# Extract the variables from values given via lxc.hook.post-stop hook # Extract the variables from values given via lxc.hook.post-stop hook
app = os.environ['LXC_NAME'] app = os.environ['LXC_NAME']
# Release the container IP # Release the container IP
tools.update_hosts_lease(None, app) tools.update_hosts_lease(app, False)
# Remove ephemeral layer data # Remove ephemeral layer data
tools.clean_ephemeral_layer(app) tools.clean_ephemeral_layer(app)

View File

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