#!/usr/bin/python2.7
import json
import os
import sys
import logging
import argparse
import fcntl
from contextlib import contextmanager
from dockerup import conf, DockerUp

"""
Service for synchronizing locally running Docker containers with an external
configuration file. If available, EC2 user-data is used as the configuration file,
otherwise dockerup looks in /etc/dockerup/dockerup.json by default (override with --config).

This script can be run on-demand or via a cron job.

Sample config file is shown below:

{
	"containers": [
		{
			"type": "docker",
			"name": "historical-app",
			"image": "barchart/historical-app-alpha",
			"portMappings": [ 
				{
					"containerPort": "8080",
					"hostPort": "8080"
				}
			]
		},
		{
			"type": "docker",
			"name": "logstash-forwarder",
			"image": "barchart/logstash-forwarder",
			"volumes": [
				{
					"containerPath": "/var/log/containers",
					"hostPath": "/var/log/ext",
					"mode": "ro"
				}
			]
		}
	]
}
"""

DEFAULT_CONFIG = '/etc/dockerup/dockerup.conf'
DEFAULT_CACHE = '/var/cache/dockerup'
LOG_FORMAT='%(asctime)s %(levelname)s %(name)s:%(lineno)d %(message)s'

@contextmanager
def lock(lock_file):

	if os.path.exists(lock_file):

		print 'Lock could not be acquired: %s' % lock_file
		sys.exit(-1)

	else:
		open(lock_file, 'w').write("1")
		try:
			yield
		finally:
			os.remove(lock_file)


if __name__ == '__main__':

	# Command line args
	parser = argparse.ArgumentParser()
	parser.add_argument('--config', default=DEFAULT_CONFIG, help='Configuration file')
	parser.add_argument('--cache', default=DEFAULT_CACHE, help='Configuration cache')
	parser.add_argument('--aws', action='store_true', help='Fetch EC2 user-data for configuration')
	parser.add_argument('--confdir', help='Scan directory for configuration files')
	parser.add_argument('-v', '--verbose', action='store_true', help='Verbose logging for debugging')
	args = parser.parse_args()

	# Logging configuration
	level = logging.DEBUG if args.verbose else logging.INFO
	logging.basicConfig(level=level, format=LOG_FORMAT)
	log = logging.getLogger(__name__)

	# Initialize cache
	if not os.path.exists(args.cache):
		try:
			os.makedirs(args.cache)
		except Exception as e:
			print 'Could not create cache directory: %s' % e
			sys.exit(1)

	with lock('%s/run.lock' % args.cache):

		settings = conf.settings(args)
		config = conf.Config()

		if 'confdir' in settings:
			config.merge(conf.FilesConfig(settings['confdir']))

		if 'aws' in settings and settings['aws']:
			config.merge(conf.AWSConfig())

		if not len(config.config):
			print 'No configuration provided'
			sys.exit(1)

		DockerUp(config.config, args.cache).start()
