#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Cloud.com Python utility library"""

import sys, os, subprocess, errno, re, time, glob
import urllib2
import xml.dom.minidom
import logging
import socket

# exit() error constants
E_GENERIC= 1
E_NOKVM = 2
E_NODEFROUTE = 3
E_DHCP = 4
E_NOPERSISTENTNET = 5
E_NETRECONFIGFAILED = 6
E_VIRTRECONFIGFAILED = 7
E_FWRECONFIGFAILED = 8
E_AGENTRECONFIGFAILED = 9
E_AGENTFAILEDTOSTART = 10
E_NOFQDN = 11
E_SELINUXENABLED = 12
E_USAGE = os.EX_USAGE

E_NEEDSMANUALINTERVENTION = 13
E_INTERRUPTED = 14
E_SETUPFAILED = 15
E_UNHANDLEDEXCEPTION = 16
E_MISSINGDEP = 17

Unknown = 0
Fedora = 1
CentOS = 2
Ubuntu = 3

IPV4 = 4
IPV6 = 6

#=================== DISTRIBUTION DETECTION =================

if os.path.exists("/etc/fedora-release"): distro = Fedora
elif os.path.exists("/etc/centos-release"): distro = CentOS
elif os.path.exists("/etc/redhat-release") and not os.path.exists("/etc/fedora-release"): distro = CentOS
elif os.path.exists("/etc/legal") and "Ubuntu" in file("/etc/legal").read(-1): distro = Ubuntu
else: distro = Unknown


# ==================  LIBRARY UTILITY CODE=============

def read_properties(propfile):
	if not hasattr(propfile,"read"): propfile = file(propfile)
	properties = propfile.read().splitlines()
	properties = [ s.strip() for s in properties ]
	properties = [ s for s in properties if
			s and
			not s.startswith("#") and
			not s.startswith(";") ]
	#[ logging.debug("Valid config file line: %s",s) for s in properties ]
	proppairs = [ s.split("=",1) for s in properties ]
	return dict(proppairs)

def stderr(msgfmt,*args):
	"""Print a message to stderr, optionally interpolating the arguments into it"""
	msgfmt += "\n"
	if args: sys.stderr.write(msgfmt%args)
	else: sys.stderr.write(msgfmt)
	sys.stderr.flush()

def exit(errno=E_GENERIC,message=None,*args):
	"""Exit with an error status code, printing a message to stderr if specified"""
	if message: stderr(message,*args)
	sys.exit(errno)

def resolve(host,port):
	return [ (x[4][0],len(x[4])+2) for x in socket.getaddrinfo(host,port,socket.AF_UNSPEC,socket.SOCK_STREAM, 0, socket.AI_PASSIVE) ]
	
def resolves_to_ipv6(host,port):
	return resolve(host,port)[0][1] == IPV6

###add this to Python 2.4, patching the subprocess module at runtime
if hasattr(subprocess,"check_call"):
	from subprocess import CalledProcessError, check_call
else:
	class CalledProcessError(Exception):
		def __init__(self, returncode, cmd):
			self.returncode = returncode ; self.cmd = cmd
		def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
	subprocess.CalledProcessError = CalledProcessError
	
	def check_call(*popenargs, **kwargs):
		retcode = subprocess.call(*popenargs, **kwargs)
		cmd = kwargs.get("args")
		if cmd is None: cmd = popenargs[0]
		if retcode: raise subprocess.CalledProcessError(retcode, cmd)
		return retcode
	subprocess.check_call = check_call

# python 2.4 does not have this
try:
	any = any
	all = all
except NameError:
	def any(sequence):
		for i in sequence:
			if i: return True
		return False
	def all(sequence):
		for i in sequence:
			if not i: return False
		return True

class Command:
	"""This class simulates a shell command"""
	def __init__(self,name,parent=None):
		self.__name = name
		self.__parent = parent
	def __getattr__(self,name):
		if name == "_print": name = "print"
		return Command(name,self)
	def __call__(self,*args,**kwargs):
		cmd = self.__get_recursive_name() + list(args)
		#print "	",cmd
		kwargs = dict(kwargs)
		if "stdout" not in kwargs: kwargs["stdout"] = subprocess.PIPE
		if "stderr" not in kwargs: kwargs["stderr"] = subprocess.PIPE
		popen = subprocess.Popen(cmd,**kwargs)
		m = popen.communicate()
		ret = popen.wait()
		if ret:
			e = CalledProcessError(ret,cmd)
			e.stdout,e.stderr = m
			raise e
		class CommandOutput:
			def __init__(self,stdout,stderr):
				self.stdout = stdout
				self.stderr = stderr
		return CommandOutput(*m)
	def __lt__(self,other):
		cmd = self.__get_recursive_name()
		#print "	",cmd,"<",other
		popen = subprocess.Popen(cmd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
		m = popen.communicate(other)
		ret = popen.wait()
		if ret:
			e = CalledProcessError(ret,cmd)
			e.stdout,e.stderr = m
			raise e
		class CommandOutput:
			def __init__(self,stdout,stderr):
				self.stdout = stdout
				self.stderr = stderr
		return CommandOutput(*m)
		
	def __get_recursive_name(self,sep=None):
		m = self
		l = []
		while m is not None:
			l.append(m.__name)
			m = m.__parent
		l.reverse()
		if sep: return sep.join(l)
		else: return l
	def __str__(self):
		return '<Command %r>'%self.__get_recursive_name(sep=" ")
		
	def __repr__(self): return self.__str__()

kvmok = Command("kvm-ok")
getenforce = Command("/usr/sbin/getenforce")
ip = Command("ip")
service = Command("service")
chkconfig = Command("chkconfig")
updatercd = Command("update-rc.d")
ufw = Command("ufw")
iptables = Command("iptables")
iptablessave = Command("iptables-save")
augtool = Command("augtool")
ifconfig = Command("ifconfig")
ifdown = Command("ifdown")
ifup = Command("ifup")
brctl = Command("brctl")
uuidgen = Command("uuidgen")


def is_service_running(servicename):
	try:
		o = service(servicename,"status")
		if distro is Ubuntu:
			# status in ubuntu does not signal service status via return code
			if "start/running" in o.stdout: return True
			return False
		else:
			# retcode 0, service running
			return True
	except CalledProcessError,e:
		# retcode nonzero, service not running
		return False


def stop_service(servicename,force=False):
	# This function is idempotent.  N number of calls have the same result as N+1 number of calls.
	if is_service_running(servicename) or force: service(servicename,"stop",stdout=None,stderr=None)


def disable_service(servicename):
	# Stops AND disables the service
	stop_service(servicename)
	if distro is Ubuntu:
		updatercd("-f",servicename,"remove",stdout=None,stderr=None)
	else:
		chkconfig("--del",servicename,stdout=None,stderr=None)


def start_service(servicename,force=False):
	# This function is idempotent unless force is True.  N number of calls have the same result as N+1 number of calls.
	if not is_service_running(servicename) or force: service(servicename,"start",stdout=None,stderr=None)


def enable_service(servicename,forcestart=False):
	# Stops AND disables the service
	if distro is Ubuntu:
		updatercd("-f",servicename,"remove",stdout=None,stderr=None)
		updatercd("-f",servicename,"start","2","3","4","5",".",stdout=None,stderr=None)
	else:
		chkconfig("--add",servicename,stdout=None,stderr=None)
		chkconfig("--level","345",servicename,"on",stdout=None,stderr=None)
	start_service(servicename,force=forcestart)


def replace_line(f,startswith,stanza,always_add=False):
	lines = [ s.strip() for s in file(f).readlines() ]
	newlines = []
	replaced = False
	for line in lines:
		if line.startswith(startswith):
			newlines.append(stanza)
			replaced = True
		else: newlines.append(line)
	if not replaced and always_add: newlines.append(stanza)
	newlines = [ s + '\n' for s in newlines ]
	file(f,"w").writelines(newlines)

def replace_or_add_line(f,startswith,stanza):
	return replace_line(f,startswith,stanza,always_add=True)
	
# ==================================== CHECK FUNCTIONS ==========================

# If they return without exception, it's okay.  If they raise a CheckFailed exception, that means a condition
# (generallly one that needs administrator intervention) was detected.

class CheckFailed(Exception): pass

#check function
def check_hostname():
	"""If the hostname is a non-fqdn, fail with CalledProcessError.  Else return 0."""
	try: check_call(["hostname",'--fqdn'])
	except CalledProcessError:
		raise CheckFailed("This machine does not have an FQDN (fully-qualified domain name) for a hostname")

#check function
def check_kvm():
	if distro in (Fedora,CentOS):
		if os.path.exists("/dev/kvm"): return True
		raise CheckFailed("KVM is not correctly installed on this system, or support for it is not enabled in the BIOS")
	else:
		try:
			kvmok()
			return True
		except CalledProcessError:
			raise CheckFailed("KVM is not correctly installed on this system, or support for it is not enabled in the BIOS")
		except OSError,e:
			if e.errno is errno.ENOENT: raise CheckFailed("KVM is not correctly installed on this system, or support for it is not enabled in the BIOS")
			raise
		return True
	raise AssertionError, "check_kvm() should have never reached this part"

def check_cgroups():
	return glob.glob("/*/cpu.shares")

#check function
def check_selinux():
	if distro not in [Fedora,CentOS]: return # no selinux outside of those
	enforcing = False
	try:
		output = getenforce().stdout.strip()
		if "nforcing" in output:
			enforcing = True
		if any ( [ s.startswith("SELINUX=enforcing") for s in file("/etc/selinux/config").readlines() ] ):
			enforcing = True
	except (IOError,OSError),e:
		if e.errno == 2: pass
		else: raise CheckFailed("An unknown error (%s) took place while checking for SELinux"%str(e))
	if enforcing:
		raise CheckFailed("SELinux is set to enforcing, please set it to permissive in /etc/selinux/config, then reboot the machine or type setenforce Permissive, after which you can run this program again.")


def preflight_checks(do_check_kvm=True):
	if distro is Ubuntu:
		preflight_checks = [
			(check_hostname,"Checking hostname"),
		]
	else:
		preflight_checks = [
			(check_hostname,"Checking hostname"),
			(check_selinux,"Checking if SELinux is disabled"),
		]
	#preflight_checks.append( (check_cgroups,"Checking if the control groups /cgroup filesystem is mounted") )
	if do_check_kvm: preflight_checks.append( (check_kvm,"Checking for KVM") )
	return preflight_checks


# ========================== CONFIGURATION TASKS ================================

# A Task is a function that runs within the context of its run() function that runs the function execute(), which does several things, reporting back to the caller as it goes with the use of yield
# the done() method ought to return true if the task has run in the past
# the execute() method must implement the configuration act itself
# run() wraps the output of execute() within a Starting taskname and a Completed taskname message
# tasks have a name

class TaskFailed(Exception): pass
	#def __init__(self,code,msg):
		#Exception.__init__(self,msg)
		#self.code = code

class ConfigTask:
	name = "generic config task"
	def __init__(self): pass
	def done(self):
		"""Returns true if the config task has already been done in the past, false if it hasn't"""
		return False
	def execute(self):
		"""Executes the configuration task.  Must not be run if test() returned true.
		Must yield strings that describe the steps in the task.
		Raises TaskFailed if the task failed at some step.
		"""
	def run (self):
		stderr("Starting %s"%self.name)
		it = self.execute()
		if not it:
			pass # not a yielding iterable
		else:
			for msg in it: stderr(msg)
		stderr("Completed %s"%self.name)


# ============== these are some configuration tasks ==================

class SetupNetworking(ConfigTask):
	name = "network setup"
	def __init__(self,brname):
		ConfigTask.__init__(self)
		self.brname = brname
		self.runtime_state_changed = False
		self.was_nm_service_running = None
		self.was_net_service_running = None
		if distro in (Fedora, CentOS):
			self.nmservice = 'NetworkManager'
			self.netservice = 'network'
		else:
			self.nmservice = 'network-manager'
			self.netservice = 'networking'
		
		
	def done(self):
		try:
			if distro in (Fedora,CentOS):
				alreadysetup = augtool._print("/files/etc/sysconfig/network-scripts/ifcfg-%s"%self.brname).stdout.strip()
			else:
				alreadysetup = augtool.match("/files/etc/network/interfaces/iface",self.brname).stdout.strip()
			return alreadysetup
		except OSError,e:
			if e.errno is 2: raise TaskFailed("augtool has not been properly installed on this system")
			raise

	def restore_state(self):
		if not self.runtime_state_changed: return
		
		try:
			o = ifconfig(self.brname)
			bridge_exists = True
		except CalledProcessError,e:
			print e.stdout + e.stderr
			bridge_exists = False
			
		if bridge_exists:
			ifconfig(self.brname,"0.0.0.0")
			if hasattr(self,"old_net_device"):
				ifdown(self.old_net_device)
				ifup(self.old_net_device)
			try: ifdown(self.brname)
			except CalledProcessError: pass
			try: ifconfig(self.brname,"down")
			except CalledProcessError: pass
			try: brctl("delbr",self.brname)
			except CalledProcessError: pass
			try: ifdown("--force",self.brname)
			except CalledProcessError: pass
		
		
		if self.was_net_service_running is None:
			# we do nothing
			pass
		elif self.was_net_service_running == False:
			stop_service(self.netservice,force=True)
			time.sleep(1)
		else:
			# we altered service configuration
			stop_service(self.netservice,force=True)
			time.sleep(1)
			try: start_service(self.netservice,force=True)
			except CalledProcessError,e:
				if e.returncode == 1: pass
				else: raise
			time.sleep(1)
		
		if self.was_nm_service_running is None:
			 # we do nothing
			 pass
		elif self.was_nm_service_running == False:
			stop_service(self.nmservice,force=True)
			time.sleep(1)
		else:
			# we altered service configuration
			stop_service(self.nmservice,force=True)
			time.sleep(1)
			start_service(self.nmservice,force=True)
			time.sleep(1)
		
		self.runtime_state_changed = False

	def execute(self):
		yield "Determining default route"
		routes = ip.route().stdout.splitlines()
		defaultroute = [ x for x in routes if x.startswith("default") ]
		if not defaultroute: raise TaskFailed("Your network configuration does not have a default route")
		
		dev = defaultroute[0].split()[4]
		yield "Default route assigned to device %s"%dev
		
		self.old_net_device = dev
		
		if distro in (Fedora, CentOS):
			inconfigfile = "/".join(augtool.match("/files/etc/sysconfig/network-scripts/*/DEVICE",dev).stdout.strip().split("/")[:-1])
			if not inconfigfile: raise TaskFailed("Device %s has not been set up in /etc/sysconfig/network-scripts"%dev)
			pathtoconfigfile = inconfigfile[6:]

		if distro in (Fedora, CentOS):
			automatic = augtool.match("%s/ONBOOT"%inconfigfile,"yes").stdout.strip()
		else:
			automatic = augtool.match("/files/etc/network/interfaces/auto/*/",dev).stdout.strip()
		if not automatic:
			if distro is Fedora: raise TaskFailed("Device %s has not been set up in %s as automatic on boot"%dev,pathtoconfigfile)
			else: raise TaskFailed("Device %s has not been set up in /etc/network/interfaces as automatic on boot"%dev)
			
		if distro not in (Fedora , CentOS):
			inconfigfile = augtool.match("/files/etc/network/interfaces/iface",dev).stdout.strip()
			if not inconfigfile: raise TaskFailed("Device %s has not been set up in /etc/network/interfaces"%dev)

		if distro in (Fedora, CentOS):
			isstatic = augtool.match(inconfigfile + "/BOOTPROTO","none").stdout.strip()
			if not isstatic: isstatic = augtool.match(inconfigfile + "/BOOTPROTO","static").stdout.strip()
		else:
			isstatic = augtool.match(inconfigfile + "/method","static").stdout.strip()
		if not isstatic:
			if distro in (Fedora, CentOS): raise TaskFailed("Device %s has not been set up as a static device in %s"%(dev,pathtoconfigfile))
			else: raise TaskFailed("Device %s has not been set up as a static device in /etc/network/interfaces"%dev)

		if is_service_running(self.nmservice):
			self.was_nm_service_running = True
			yield "Stopping NetworkManager to avoid automatic network reconfiguration"
			disable_service(self.nmservice)
		else:
			self.was_nm_service_running = False
			
		if is_service_running(self.netservice):
			self.was_net_service_running = True
		else:
			self.was_net_service_running = False
			
		yield "Creating Cloud bridging device and making device %s member of this bridge"%dev

		if distro in (Fedora, CentOS):
			ifcfgtext = file(pathtoconfigfile).read()
			newf = "/etc/sysconfig/network-scripts/ifcfg-%s"%self.brname
			#def restore():
				#try: os.unlink(newf)
				#except OSError,e:
					#if errno == 2: pass
					#raise
				#try: file(pathtoconfigfile,"w").write(ifcfgtext)
				#except OSError,e: raise

			f = file(newf,"w") ; f.write(ifcfgtext) ; f.flush() ; f.close()
			innewconfigfile = "/files" + newf

			script = """set %s/DEVICE %s
set %s/NAME %s
set %s/BRIDGE_PORTS %s
set %s/TYPE Bridge
rm %s/HWADDR
rm %s/UUID
rm %s/HWADDR
rm %s/IPADDR
rm %s/DEFROUTE
rm %s/NETMASK
rm %s/GATEWAY
rm %s/BROADCAST
rm %s/NETWORK
set %s/BRIDGE %s
save"""%(innewconfigfile,self.brname,innewconfigfile,self.brname,innewconfigfile,dev,
			innewconfigfile,innewconfigfile,innewconfigfile,innewconfigfile,
			inconfigfile,inconfigfile,inconfigfile,inconfigfile,inconfigfile,inconfigfile,
			inconfigfile,self.brname)
			
			yield "Executing the following reconfiguration script:\n%s"%script
			
			try:
				returned = augtool < script
				if "Saved 2 file" not in returned.stdout:
					print returned.stdout + returned.stderr
					#restore()
					raise TaskFailed("Network reconfiguration failed.")
				else:
					yield "Network reconfiguration complete"
			except CalledProcessError,e:
				#restore()
				print e.stdout + e.stderr
				raise TaskFailed("Network reconfiguration failed")
		else: # Not fedora
			backup = file("/etc/network/interfaces").read(-1)
			#restore = lambda: file("/etc/network/interfaces","w").write(backup)

			script = """set %s %s
set %s %s
set %s/bridge_ports %s
save"""%(automatic,self.brname,inconfigfile,self.brname,inconfigfile,dev)
			
			yield "Executing the following reconfiguration script:\n%s"%script
			
			try:
				returned = augtool < script
				if "Saved 1 file" not in returned.stdout:
					#restore()
					raise TaskFailed("Network reconfiguration failed.")
				else:
					yield "Network reconfiguration complete"
			except CalledProcessError,e:
				#restore()
				print e.stdout + e.stderr
				raise TaskFailed("Network reconfiguration failed")
		
		yield "We are going to restart network services now, to make the network changes take effect.  Hit ENTER when you are ready."
		raw_input()
		
		# if we reach here, then if something goes wrong we should attempt to revert the runinng state
		# if not, then no point
		self.runtime_state_changed = True
		
		yield "Enabling and restarting non-NetworkManager networking"
		if distro is Ubuntu: ifup(self.brname,stdout=None,stderr=None)
		stop_service(self.netservice)
		try: enable_service(self.netservice,forcestart=True)
		except CalledProcessError,e:
			if e.returncode == 1: pass
			else: raise
		
		yield "Verifying that the bridge is up"
		try:
			o = ifconfig(self.brname)
		except CalledProcessError,e:
			print e.stdout + e.stderr
			raise TaskFailed("The bridge could not be set up properly")
		
		yield "Networking restart done"


class SetupCgConfig(ConfigTask):
	name = "control groups configuration"
	
	def done(self):
		
		try:
			return "group virt" in file("/etc/cgconfig.conf","r").read(-1)
		except IOError,e:
			if e.errno is 2: raise TaskFailed("cgconfig has not been properly installed on this system")
			raise
		
	def execute(self):
		cgconfig = file("/etc/cgconfig.conf","r").read(-1)
		cgconfig = cgconfig + """
group virt {
	cpu {
		cpu.shares = 9216;
	}
}
"""
		file("/etc/cgconfig.conf","w").write(cgconfig)
		
		stop_service("cgconfig")
		enable_service("cgconfig",forcestart=True)


class SetupCgRules(ConfigTask):
	name = "control group rules setup"
	cfgline = "root:/usr/sbin/libvirtd	cpu	virt/"
	
	def done(self):
		try:
			return self.cfgline in file("/etc/cgrules.conf","r").read(-1)
		except IOError,e:
			if e.errno is 2: raise TaskFailed("cgrulesd has not been properly installed on this system")
			raise
	
	def execute(self):
		cgrules = file("/etc/cgrules.conf","r").read(-1)
		cgrules = cgrules + "\n" + self.cfgline + "\n"
		file("/etc/cgrules.conf","w").write(cgrules)
		
		stop_service("cgred")
		enable_service("cgred")


class SetupCgroupControllers(ConfigTask):
	name = "qemu cgroup controllers setup"
	cfgline = "cgroup_controllers = [ \"cpu\" ]"
	filename = "/etc/libvirt/qemu.conf"
	
	def done(self):
		try:
			return self.cfgline in file(self.filename,"r").read(-1)
		except IOError,e:
			if e.errno is 2: raise TaskFailed("qemu has not been properly installed on this system")
			raise
	
	def execute(self):
		libvirtqemu = file(self.filename,"r").read(-1)
		libvirtqemu = libvirtqemu + "\n" + self.cfgline + "\n"
		file("/etc/libvirt/qemu.conf","w").write(libvirtqemu)


class SetupSecurityDriver(ConfigTask):
	name = "security driver setup"
	cfgline = "security_driver = \"none\""
	filename = "/etc/libvirt/qemu.conf"
	
	def done(self):
		try:
			return self.cfgline in file(self.filename,"r").read(-1)
		except IOError,e:
			if e.errno is 2: raise TaskFailed("qemu has not been properly installed on this system")
			raise
	
	def execute(self):
		libvirtqemu = file(self.filename,"r").read(-1)
		libvirtqemu = libvirtqemu + "\n" + self.cfgline + "\n"
		file("/etc/libvirt/qemu.conf","w").write(libvirtqemu)


class SetupLibvirt(ConfigTask):
	name = "libvirt setup"
	cfgline = "export CGROUP_DAEMON='cpu:/virt'"
	def done(self):
		try:
			if distro in (Fedora,CentOS): 	 libvirtfile = "/etc/sysconfig/libvirtd"
			elif distro is Ubuntu:	 libvirtfile = "/etc/default/libvirt-bin"
			else: raise AssertionError, "We should not reach this"
			return self.cfgline in file(libvirtfile,"r").read(-1)
		except IOError,e:
			if e.errno is 2: raise TaskFailed("libvirt has not been properly installed on this system")
			raise
	
	def execute(self):
		if distro in (Fedora,CentOS): 	 libvirtfile = "/etc/sysconfig/libvirtd"
		elif distro is Ubuntu:	 libvirtfile = "/etc/default/libvirt-bin"
		else: raise AssertionError, "We should not reach this"
		libvirtbin = file(libvirtfile,"r").read(-1)
		libvirtbin = libvirtbin + "\n" + self.cfgline + "\n"
		file(libvirtfile,"w").write(libvirtbin)
		
		if distro in (CentOS, Fedora):	svc = "libvirtd"
		else:					svc = "libvirt-bin"
		stop_service(svc)
		enable_service(svc)

class SetupLiveMigration(ConfigTask):
	name = "live migration setup"
	stanzas = (
			"listen_tcp=1",
			'tcp_port="16509"',
			'auth_tcp="none"',
			"listen_tls=0",
	)
	
	def done(self):
		try:
			lines = [ s.strip() for s in file("/etc/libvirt/libvirtd.conf").readlines() ]
			if all( [ stanza in lines for stanza in self.stanzas ] ): return True
		except IOError,e:
			if e.errno is 2: raise TaskFailed("libvirt has not been properly installed on this system")
			raise
	
	def execute(self):
		
		for stanza in self.stanzas:
			startswith = stanza.split("=")[0] + '='
			replace_or_add_line("/etc/libvirt/libvirtd.conf",startswith,stanza)

		if distro is Fedora:
			replace_or_add_line("/etc/sysconfig/libvirtd","LIBVIRTD_ARGS=","LIBVIRTD_ARGS=-l")
		
		elif distro is Ubuntu:
			if os.path.exists("/etc/init/libvirt-bin.conf"):
				replace_line("/etc/init/libvirt-bin.conf", "exec /usr/sbin/libvirtd","exec /usr/sbin/libvirtd -d -l")
			else:
				replace_or_add_line("/etc/default/libvirt-bin","libvirtd_opts=","libvirtd_opts='-l -d'")
			
		else:
			raise AssertionError("Unsupported distribution")
		
		if distro in (CentOS, Fedora):	svc = "libvirtd"
		else:						svc = "libvirt-bin"
		stop_service(svc)
		enable_service(svc)


class SetupRequiredServices(ConfigTask):
	name = "required services setup"
	
	def done(self):
		if distro is Fedora:  nfsrelated = "rpcbind nfslock"
		elif distro is CentOS: nfsrelated = "portmap nfslock"
		else: return True
		return all( [ is_service_running(svc) for svc in nfsrelated.split() ] )
		
	def execute(self):

		if distro is Fedora:  nfsrelated = "rpcbind nfslock"
		elif distro is CentOS: nfsrelated = "portmap nfslock"
		else: raise AssertionError("Unsupported distribution")

		for svc in nfsrelated.split(): enable_service(svc)


class SetupFirewall(ConfigTask):
	name = "firewall setup"
	
	def done(self):
		
		if distro in (Fedora, CentOS):
			if not os.path.exists("/etc/sysconfig/iptables"): return True
			if ":on" not in chkconfig("--list","iptables").stdout: return True
		else:
			if "Status: active" not in ufw.status().stdout: return True
			if not os.path.exists("/etc/ufw/before.rules"): return True
		rule = "-p tcp -m tcp --dport 16509 -j ACCEPT"
		if rule in iptablessave().stdout: return True
		return False
	
	def execute(self):
		ports = "22 1798 16509".split()
		if distro in (Fedora , CentOS):
			for p in ports: iptables("-I","INPUT","1","-p","tcp","--dport",p,'-j','ACCEPT')
			o = service.iptables.save() ; print o.stdout + o.stderr
		else:
			for p in ports: ufw.allow(p)


class SetupFirewall2(ConfigTask):
	# this closes bug 4371
	name = "additional firewall setup"
	def __init__(self,brname):
		ConfigTask.__init__(self)
		self.brname = brname
	
	def done(self):
		
		if distro in (Fedora, CentOS):
			if not os.path.exists("/etc/sysconfig/iptables"): return True
			if ":on" not in chkconfig("--list","iptables").stdout: return True
			rule = "FORWARD -i %s -o %s -j ACCEPT"%(self.brname,self.brname)
			if rule in iptablessave().stdout: return True
			return False
		else:
			if "Status: active" not in ufw.status().stdout: return True
			if not os.path.exists("/etc/ufw/before.rules"): return True
			rule = "-A ufw-before-forward -i %s -o %s -j ACCEPT"%(self.brname,self.brname)
			if rule in file("/etc/ufw/before.rules").read(-1): return True
			return False
		
	def execute(self):
		
		yield "Permitting traffic in the bridge interface and for VNC ports"
		
		if distro in (Fedora , CentOS):
			
			for rule in (
				"-I FORWARD -i %s -o %s -j ACCEPT"%(self.brname,self.brname),
				"-I INPUT 1 -p tcp --dport 5900:6100 -j ACCEPT",
				):
				args = rule.split()
				o = iptables(*args)
			service.iptables.save(stdout=None,stderr=None)
			
		else:
			
			rule = "-A ufw-before-forward -i %s -o %s -j ACCEPT"%(self.brname,self.brname)
			text = file("/etc/ufw/before.rules").readlines()
			newtext = []
			for line in text:
				if line.startswith("COMMIT"):
					newtext.append(rule + "\n")
				newtext.append(line)
			file("/etc/ufw/before.rules","w").writelines(newtext)
			ufw.allow.proto.tcp("from","any","to","any","port","5900:6100")

			stop_service("ufw")
			start_service("ufw")


# Tasks according to distribution -- at some point we will split them in separate modules

def config_tasks(brname):
	if distro is CentOS:
		config_tasks = (
			SetupNetworking(brname),
			SetupLibvirt(),
			SetupRequiredServices(),
			SetupFirewall(),
			SetupFirewall2(brname),
		)
	elif distro in (Ubuntu,Fedora):
		config_tasks = (
			SetupNetworking(brname),
			SetupCgConfig(),
			SetupCgRules(),
			SetupCgroupControllers(),
			SetupSecurityDriver(),
			SetupLibvirt(),
			SetupLiveMigration(),
			SetupRequiredServices(),
			SetupFirewall(),
			SetupFirewall2(brname),
		)
	else:
		raise AssertionError("Unknown distribution")
	return config_tasks


def backup_etc(targetdir):
	if not targetdir.endswith("/"): targetdir += "/"
	check_call( ["mkdir","-p",targetdir] )
	rsynccall = ["rsync","-ax","--delete"] + ["/etc/",targetdir]
	check_call( rsynccall )
def restore_etc(targetdir):
	if not targetdir.endswith("/"): targetdir += "/"
	rsynccall = ["rsync","-ax","--delete"] + [targetdir,"/etc/"]
	check_call( rsynccall )
def remove_backup(targetdir):
	check_call( ["rm","-rf",targetdir] )

# this configures the agent

def setup_agent_config(configfile,brname):
	stderr("Examining agent configuration")
	fn = configfile
	text = file(fn).read(-1)
	lines = [ s.strip() for s in text.splitlines() ]
	confopts = dict([ m.split("=",1) for m in lines if "=" in m and not m.startswith("#") ])
	confposes = dict([ (m.split("=",1)[0],n) for n,m in enumerate(lines) if "=" in m and not m.startswith("#") ])
	
	if not "guid" in confopts:
		stderr("Generating GUID for this agent")
		confopts['guid'] = uuidgen().stdout.strip()
	
	try: host = confopts["host"]
	except KeyError: host = "localhost"
	stderr("Please enter the host name of the management server that this agent will connect to: (just hit ENTER to go with %s)",host)
	newhost = raw_input().strip()
	if newhost: host = newhost
	confopts["host"] = host
	
	confopts["private.network.device"] = brname
	confopts["public.network.device"] = brname
	
	stderr("Querying %s for zones and pods",host)
	
	try:

		text = urllib2.urlopen('http://%s:8096/client/api?command=listPods'%confopts["host"]).read(-1)
		dom = xml.dom.minidom.parseString(text) 
		x = [ (zonename,podname)
			for pod in dom.childNodes[0].childNodes  
			for podname in [ x.childNodes[0].wholeText for x in pod.childNodes if x.tagName == "name" ] 
			for zonename in  [ x.childNodes[0].wholeText for x in pod.childNodes if x.tagName == "zonename" ]
			]  
		
		while True:
			
			stderr("Type the number of the zone and pod combination this host belongs to (hit ENTER to skip this step)")
			print "  N) ZONE, POD" 
			print "================"
			for n,(z,p) in enumerate(x):
				print "%3d) %s, %s"%(n,z,p)
			print "================"
			zoneandpod = raw_input().strip()
			
			if not zoneandpod:
				# we go with default, do not touch anything, just break
				break
			
			try:
				# if parsing fails as an int, just vomit and retry
				zoneandpod = int(zoneandpod)
				if zoneandpod >= len(x) or zoneandpod < 0: raise ValueError, "%s out of bounds"%zoneandpod
			except ValueError,e:
				stderr(str(e))
				continue # re-ask
			
			# oh yeah, the int represents an valid zone and pod index in the array
			zone,pod = x[zoneandpod]
			confopts["zone"] = zone
			confopts["pod"] = pod
			break
	
	except (urllib2.URLError,urllib2.HTTPError),e:
		stderr("Query failed: %s.  Defaulting to zone %s pod %s",e,confopts["zone"],confopts["pod"])

	for opt,val in confopts.items():
		line = "=".join([opt,val])
		if opt not in confposes: lines.append(line)
		else: lines[confposes[opt]] = line
	
	text = "\n".join(lines)
	file(fn,"w").write(text)


# =========================== DATABASE MIGRATION SUPPORT CODE ===================

# Migrator, Migratee and Evolvers -- this is the generic infrastructure.
# To actually implement Cloud.com-specific code, search "Cloud.com-specific evolvers and context"


class MigratorException(Exception): pass
class NoMigrationPath(MigratorException): pass
class NoMigrator(MigratorException): pass

INITIAL_LEVEL = '-'

class Migrator:
	"""Migrator class.
	
	The migrator gets a list of Python objects, and discovers MigrationSteps in it. It then sorts the steps into a chain, based on the attributes from_level and to_level in each one of the steps.
	
	When the migrator's run(context) is called, the chain of steps is applied sequentially on the context supplied to run(), in the order of the chain of steps found at discovery time.  See the documentation for the MigrationStep class for information on how that happens.
	"""
	
	def __init__(self,evolver_source):
		self.discover_evolvers(evolver_source)
		self.sort_evolvers()
		
	def discover_evolvers(self,source):
		self.evolvers = []
		for val in source:
			if hasattr(val,"from_level") and hasattr(val,"to_level") and val.to_level:
				self.evolvers.append(val)
	
	def sort_evolvers(self):
		new = []
		while self.evolvers:
			if not new:
				try: idx= [ i for i,s in enumerate(self.evolvers)
					if s.from_level == INITIAL_LEVEL ][0] # initial evolver
				except IndexError,e:
					raise IndexError, "no initial evolver (from_level is None) could be found"
			else:
				try: idx= [ i for i,s in enumerate(self.evolvers)
					if new[-1].to_level == s.from_level ][0]
				except IndexError,e:
					raise IndexError, "no evolver could be found to evolve from level %s"%new[-1].to_level
			new.append(self.evolvers.pop(idx))
		self.evolvers = new
	
	def get_evolver_chain(self):
		return [ (s.from_level, s.to_level, s) for s in self.evolvers ]
		
	def get_evolver_by_starting_level(self,level):
		try: return [ s for s in self.evolvers if s.from_level == level][0]
		except IndexError: raise NoMigrator, "No evolver knows how to evolve the database from schema level %r"%level
	
	def get_evolver_by_ending_level(self,level):
		try: return [ s for s in self.evolvers if s.to_level == level][0]
		except IndexError: raise NoMigrator, "No evolver knows how to evolve the database to schema level %r"%level
	
	def run(self, context, dryrun = False, starting_level = None, ending_level = None):
		"""Runs each one of the steps in sequence, passing the migration context to each. At the end of the process, context.commit() is called to save the changes, or context.rollback() is called if dryrun = True.
		
		If starting_level is not specified, then the context.get_schema_level() is used to find out at what level the context is at.  Then starting_level is set to that.
		
		If ending_level is not specified, then the evolvers will run till the end of the chain."""
		
		assert dryrun is False # NOT IMPLEMENTED, prolly gonna implement by asking the context itself to remember its state
		
		starting_level = starting_level or context.get_schema_level() or self.evolvers[0].from_level
		ending_level = ending_level or self.evolvers[-1].to_level
		
		evolution_path = self.evolvers
		idx = evolution_path.index(self.get_evolver_by_starting_level(starting_level))
		evolution_path = evolution_path[idx:]
		try: idx = evolution_path.index(self.get_evolver_by_ending_level(ending_level))
		except ValueError:
			raise NoEvolutionPath, "No evolution path from schema level %r to schema level %r" % \
				(starting_level,ending_level)
		evolution_path = evolution_path[:idx+1]
		
		logging.info("Starting migration on %s"%context)
		
		for ec in evolution_path:
			assert ec.from_level == context.get_schema_level()
			evolver = ec(context=context)
			logging.info("%s (from level %s to level %s)",
				evolver,
				evolver.from_level,
				evolver.to_level)
			#try:
			evolver.run()
			#except:
				#context.rollback()
				#raise
			context.set_schema_level(evolver.to_level)
			#context.commit()
			logging.info("%s is now at level %s",context,context.get_schema_level())
		
		#if dryrun: # implement me with backup and restore
			#logging.info("Rolling back changes on %s",context)
			#context.rollback()
		#else:
			#logging.info("Committing changes on %s",context)
			#context.commit()
		
		logging.info("Migration finished")
		

class MigrationStep:
	"""Base MigrationStep class, aka evolver.
	
	You develop your own steps, and then pass a list of those steps to the
	Migrator instance that will run them in order.
	
	When the migrator runs, it will take the list of steps you gave him,
	and, for each step:
	
	a) instantiate it, passing the context you gave to the migrator
	   into the step's __init__().
	b) run() the method in the migration step.
	
	As you can see, the default MigrationStep constructor makes the passed
	context available as self.context in the methods of your step.
	
	Each step has two member vars that determine in which order they
	are run, and if they need to run:
	
	- from_level = the schema level that the database should be at,
		       before running the evolver
		       The value None has special meaning here, it
		       means the first evolver that should be run if the
		       database does not have a schema level yet.
	- to_level =   the schema level number that the database will be at
		       after the evolver has run
	"""
	
	# Implement these attributes in your steps
	from_level = None
	to_level = None
	
	def __init__(self,context):
		self.context = context
		
	def run(self):
		raise NotImplementedError


class MigrationContext:
	def __init__(self): pass
	def commit(self):raise NotImplementedError
	def rollback(self):raise NotImplementedError
	def get_schema_level(self):raise NotImplementedError
	def set_schema_level(self,l):raise NotImplementedError


