#!/usr/bin/env python
# Copyright 2012 Citrix Systems, Inc. Licensed under the
# Apache License, Version 2.0 (the "License"); you may not use this
# file except in compliance with the License.  Citrix Systems, Inc.
# reserves all rights not expressly granted by the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 
# Automatically generated by addcopyright.py at 04/03/2012



 

# -*- coding: utf-8 -*-
"""CloudStack 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
try: E_USAGE = os.EX_USAGE
except AttributeError: E_USAGE = 64

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

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

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"):
    version = file("/etc/redhat-release").readline()
    if version.find("Red Hat Enterprise Linux Server release 6") != -1:
        distro = RHEL6
    elif version.find("CentOS release") != -1:
        distro = CentOS
    else:
        distro = CentOS
elif os.path.exists("/etc/legal") and "Ubuntu" in file("/etc/legal").read(-1): distro = Ubuntu
else: distro = Unknown
logFileName=None
# ==================  LIBRARY UTILITY CODE=============
def setLogFile(logFile):
	global logFileName
	logFileName=logFile
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 logFileName != None:
		sys.stderr = open(logFileName, 'a+')
	if args: sys.stderr.write(msgfmt%args)
	else: sys.stderr.write(msgfmt)

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,RHEL6):
		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,RHEL6]: 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() ] ):
			config_enforcing = True
		else:
			config_enforcing = False
	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. There are two options:
1> Set it permissive in /etc/selinux/config, then reboot the machine.
2> Type 'setenforce Permissive' in commandline, after which you can run this program again.

We strongly suggest you doing the option 1 that makes sure SELinux goes into permissive after system reboot.\n''')

	if config_enforcing:
		print "WARNING: We detected that your SELinux is not configured in permissive. to make sure cloudstack won't block by \
SELinux after system reboot, we strongly suggest you setting it in permissive in /etc/selinux/config, then reboot the machine."


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"
	autoMode=False
	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)
	def setAutoMode(self, autoMode):
		self.autoMode = autoMode
	def  isAutoMode(self):
		return self.autoMode


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

class SetupNetworking(ConfigTask):
	name = "network setup"
	def __init__(self,brname, pubNic, prvNic):
		ConfigTask.__init__(self)
		self.brname = brname
  	        self.pubNic = pubNic
		self.prvNic = prvNic
		self.runtime_state_changed = False
		self.was_nm_service_running = None
		self.was_net_service_running = None
		if distro in (Fedora, CentOS, RHEL6):
			self.nmservice = 'NetworkManager'
			self.netservice = 'network'
		else:
			self.nmservice = 'network-manager'
			self.netservice = 'networking'
		
		
	def done(self):
		try:
			alreadysetup = False
			if distro in (Fedora,CentOS, RHEL6):
				if self.pubNic != None:
					alreadysetup = alreadysetup or augtool._print("/files/etc/sysconfig/network-scripts/ifcfg-%s"%self.pubNic).stdout.strip()
				if self.prvNic != None:
					alreadysetup = alreadysetup or augtool._print("/files/etc/sysconfig/network-scripts/ifcfg-%s"%self.prvNic).stdout.strip()
				if not alreadysetup:
					alreadysetup = augtool._print("/files/etc/sysconfig/network-scripts/ifcfg-%s"%self.brname).stdout.strip()
				
			else:
				if self.pubNic != None:
					alreadysetup = alreadysetup or augtool._print("/files/etc/network/interfaces/iface",self.pubNic).stdout.strip()
				if self.prvNic != None:
					alreadysetup = alreadysetup or augtool._print("/files/etc/network/interfaces/iface",self.prvNic).stdout.strip()
				if not alreadysetup:
					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, RHEL6):
			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, RHEL6):
			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, RHEL6):
			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, RHEL6):
			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, RHEL6): 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, RHEL6):
			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."
		if self.isAutoMode(): pass
        	else:
		    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, RHEL6): 	 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, RHEL6): 	 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, RHEL6):	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 in (Fedora, RHEL6):
			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, RHEL6):	svc = "libvirtd"
		else:						svc = "libvirt-bin"
		stop_service(svc)
		enable_service(svc)


class SetupRequiredServices(ConfigTask):
	name = "required services setup"
	
	def done(self):
		if distro in (Fedora, RHEL6):  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 in (Fedora, RHEL6):  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,RHEL6):
			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, RHEL6):
			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, RHEL6):
			if not os.path.exists("/etc/sysconfig/iptables"): return True
			if ":on" not in chkconfig("--list","iptables").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
			return False
		
	def execute(self):
		
		yield "Permitting traffic in the bridge interface, migration port and for VNC ports"
		
		if distro in (Fedora , CentOS, RHEL6):
			
			for rule in (
				"-I INPUT 1 -p tcp --dport 5900:6100 -j ACCEPT",
				"-I INPUT 1 -p tcp --dport 49152:49216 -j ACCEPT",
				):
				args = rule.split()
				o = iptables(*args)
			service.iptables.save(stdout=None,stderr=None)
			
		else:
			
			ufw.allow.proto.tcp("from","any","to","any","port","5900:6100")
			ufw.allow.proto.tcp("from","any","to","any","port","49152:49216")

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


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

def config_tasks(brname, pubNic, prvNic):
	if distro is CentOS:
		config_tasks = (
			SetupNetworking(brname, pubNic, prvNic),
			SetupLibvirt(),
			SetupRequiredServices(),
			SetupFirewall(),
			SetupFirewall2(brname),
		)
	elif distro in (Ubuntu,Fedora, RHEL6):
		config_tasks = (
			SetupNetworking(brname, pubNic, prvNic),
			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] )

def list_zonespods(host):
	text = urllib2.urlopen('http://%s:8096/client/api?command=listPods'%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" ]
		]
	return x
	
def prompt_for_hostpods(zonespods):
	"""Ask user to select one from those zonespods
	Returns (zone,pod) or None if the user made the default selection."""
	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(zonespods):
			print "%3d) %s, %s"%(n,z,p)
		print "================"
		print "> ",
		zoneandpod = raw_input().strip()
		
		if not zoneandpod:
			# we go with default, do not touch anything, just break
			return None
		
		try:
			# if parsing fails as an int, just vomit and retry
			zoneandpod = int(zoneandpod)
			if zoneandpod >= len(zonespods) 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
		return zonespods[zoneandpod]
	
# this configures the agent

def device_exist(devName):
	try:
		alreadysetup = False
		if distro in (Fedora,CentOS, RHEL6):
			alreadysetup = augtool._print("/files/etc/sysconfig/network-scripts/ifcfg-%s"%devName).stdout.strip()
		else:
			alreadysetup = augtool.match("/files/etc/network/interfaces/iface",devName).stdout.strip()
		return alreadysetup
	except OSError,e:
		return False		
	
def setup_agent_config(configfile, host, zone, pod, cluster, guid, pubNic, prvNic):
	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 guid != None:
		confopts['guid'] = guid
	else:
		if not "guid" in confopts:
			stderr("Generating GUID for this Agent")
			confopts['guid'] = uuidgen().stdout.strip()
	
	if host == None:
		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)
		print "> ",
		newhost = raw_input().strip()
		if newhost: host = newhost

	confopts["host"] = host
	
	if pubNic != None and device_exist(pubNic):
		confopts["public.network.device"] = pubNic	
		if prvNic == None or not device_exist(prvNic):
			confopts["private.network.device"] = pubNic	
		
	if prvNic != None and device_exist(prvNic):
		confopts["private.network.device"] = prvNic	
		if pubNic == None or not device_exist(pubNic):
			confopts["public.network.device"] = prvNic	

	stderr("Querying %s for zones and pods",host)
	
	try:
	    if zone == None or pod == None:
			x = list_zonespods(confopts['host'])
			zoneandpod = prompt_for_hostpods(x)
			if zoneandpod:
				confopts["zone"],confopts["pod"] = zoneandpod
				stderr("You selected zone %s pod %s",confopts["zone"],confopts["pod"])
			else:
				stderr("Skipped -- using the previous zone %s pod %s",confopts["zone"],confopts["pod"])
	    else:
			confopts["zone"] = zone
			confopts["pod"] = pod
			confopts["cluster"] = cluster
	except (urllib2.URLError,urllib2.HTTPError),e:
		stderr("Query failed: %s.  Defaulting to zone %s pod %s",str(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)

def setup_consoleproxy_config(configfile, host, zone, pod):
	stderr("Examining Console Proxy 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 Console Proxy")
		confopts['guid'] = uuidgen().stdout.strip()

        if host == None:
		try: host = confopts["host"]
		except KeyError: host = "localhost"
		stderr("Please enter the host name of the management server that this console-proxy will connect to: (just hit ENTER to go with %s)",host)
		print "> ",
		newhost = raw_input().strip()
		if newhost: host = newhost
	confopts["host"] = host

	stderr("Querying %s for zones and pods",host)
	
	try:
                if zone == None or pod == None:
			x = list_zonespods(confopts['host'])
			zoneandpod = prompt_for_hostpods(x)
			if zoneandpod:
				confopts["zone"],confopts["pod"] = zoneandpod
				stderr("You selected zone %s pod %s",confopts["zone"],confopts["pod"])
			else:
				stderr("Skipped -- using the previous zone %s pod %s",confopts["zone"],confopts["pod"])
		else:
			confopts["zone"] = zone
			confopts["pod"] = pod
	except (urllib2.URLError,urllib2.HTTPError),e:
		stderr("Query failed: %s.  Defaulting to zone %s pod %s",str(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.


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


