diff --git a/local_cname/cli.py b/local_cname/cli.py index 8c4e60b..6094695 100644 --- a/local_cname/cli.py +++ b/local_cname/cli.py @@ -1,10 +1,12 @@ import argparse import socket +import sys import time import os from pathlib import Path -from clickclick import Action, info +from clickclick import Action, info, error +from filelock import FileLock, Timeout def main(): @@ -14,11 +16,30 @@ def main(): args = parser.parse_args() hosts_file = Path('/etc/hosts') + backup_file = hosts_file.with_suffix('.local-cname-backup') + lock_file = hosts_file.with_suffix('.local-cname-lock') + + lock = FileLock(str(lock_file)) + try: + with lock.acquire(timeout=1): + edit_etc_hosts(hosts_file, backup_file, args) + except Timeout: + error('Another instance of local-cname seems to be running.') + info('(if a previous process crashed, remove {} ' + 'and check the contents of {} and {})'.format(lock_file, hosts_file, backup_file)) + sys.exit(1) + +def edit_etc_hosts(hosts_file, backup_file, args): with hosts_file.open() as fd: old_contents = fd.read() - backup_file = hosts_file.with_suffix('.local-cname-backup') + HEADER = '#### Start of entries generated by local-cname' + if HEADER in old_contents: + error('{} seems to have already been modified by local-cname.'.format(hosts_file)) + info('Remove the local-cname header line from this file to proceed.') + sys.exit(1) + with backup_file.open('w') as fd: fd.write(old_contents) @@ -41,7 +62,7 @@ def main(): with Action('Writing {} ..'.format(hosts_file)): with hosts_file.open('w') as fd: fd.write(old_contents) - fd.write('#### Start of entries generated by local-cname\n') + fd.write('{}\n'.format(HEADER)) for hostname, ip in entries: fd.write('{} {}\n'.format(ip, hostname)) diff --git a/setup.py b/setup.py index e39255a..606d7e3 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def readme(): keywords='dns hosts local', license='GNU General Public License v3 (GPLv3)', setup_requires=['flake8'], - install_requires=['clickclick'], + install_requires=['clickclick', 'filelock'], tests_require=[], classifiers=[ 'Programming Language :: Python',