mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-18 03:23:45 +01:00
217 lines
6.7 KiB
Python
Executable File
217 lines
6.7 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import sys, os, subprocess, errno, re
|
|
|
|
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_CPRECONFIGFAILED = 9
|
|
E_CPFAILEDTOSTART = 10
|
|
E_NOFQDN = 11
|
|
|
|
|
|
def stderr(msgfmt,*args):
|
|
msgfmt += "\n"
|
|
if args: sys.stderr.write(msgfmt%args)
|
|
else: sys.stderr.write(msgfmt)
|
|
sys.stderr.flush()
|
|
|
|
def bail(errno=E_GENERIC,message=None,*args):
|
|
if message: stderr(message,*args)
|
|
stderr("Cloud Console Proxy setup aborted")
|
|
sys.exit(errno)
|
|
|
|
|
|
#---------------- boilerplate for python 2.4 support
|
|
|
|
|
|
# CENTOS does not have this -- we have to put this here
|
|
try:
|
|
from subprocess import check_call
|
|
from subprocess import CalledProcessError
|
|
except ImportError:
|
|
def check_call(*popenargs, **kwargs):
|
|
import subprocess
|
|
retcode = subprocess.call(*popenargs, **kwargs)
|
|
cmd = kwargs.get("args")
|
|
if cmd is None: cmd = popenargs[0]
|
|
if retcode: raise CalledProcessError(retcode, cmd)
|
|
return retcode
|
|
|
|
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)
|
|
|
|
# ------------ end boilerplate -------------------------
|
|
|
|
def check_hostname(): return check_call(["hostname",'--fqdn'])
|
|
|
|
class 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):
|
|
cmd = self.__get_recursive_name() + list(args)
|
|
#print " ",cmd
|
|
popen = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
|
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__()
|
|
|
|
ip = Command("ip")
|
|
service = Command("service")
|
|
chkconfig = Command("chkconfig")
|
|
ufw = Command("ufw")
|
|
iptables = Command("iptables")
|
|
augtool = Command("augtool")
|
|
ifconfig = Command("ifconfig")
|
|
uuidgen = Command("uuidgen")
|
|
|
|
Fedora = os.path.exists("/etc/fedora-release")
|
|
CentOS = os.path.exists("/etc/centos-release") or ( os.path.exists("/etc/redhat-release") and not os.path.exists("/etc/fedora-release") )
|
|
|
|
#--------------- procedure starts here ------------
|
|
|
|
stderr("Welcome to the Cloud Console Proxy setup")
|
|
stderr("")
|
|
|
|
try:
|
|
check_hostname()
|
|
stderr("The hostname of this machine is properly set up")
|
|
except CalledProcessError,e:
|
|
bail(E_NOFQDN,"This machine does not have an FQDN (fully-qualified domain name) for a hostname")
|
|
|
|
try:
|
|
service("@PACKAGE@-console-proxy","status")
|
|
except CalledProcessError,e:
|
|
stderr("Stopping the Cloud Console Proxy")
|
|
m = service("@PACKAGE@-console-proxy","stop")
|
|
print m.stdout + m.stderr
|
|
stderr("Cloud Console Proxy stopped")
|
|
|
|
stderr("Determining default route")
|
|
routes = ip.route().stdout.splitlines()
|
|
defaultroute = [ x for x in routes if x.startswith("default") ]
|
|
if not defaultroute: bail(E_NODEFROUTE,"Your network configuration does not have a default route")
|
|
dev = defaultroute[0].split()[4]
|
|
stderr("Default route assigned to device %s"%dev)
|
|
|
|
ports = "8002".split()
|
|
if Fedora or CentOS:
|
|
try:
|
|
o = chkconfig("--list","iptables")
|
|
if ":on" in o.stdout and os.path.exists("/etc/sysconfig/iptables"):
|
|
stderr("Setting up firewall rules to permit traffic to Cloud services")
|
|
service.iptables.start() ; print o.stdout + o.stderr
|
|
for p in ports: iptables("-I","INPUT","1","-p","tcp","--dport",p,'-j','ACCEPT')
|
|
o = service.iptables.save() ; print o.stdout + o.stderr
|
|
except CalledProcessError,e:
|
|
print e.stdout+e.stderr
|
|
bail(E_FWRECONFIGFAILED,"Firewall rules could not be set")
|
|
else:
|
|
stderr("Setting up firewall rules to permit traffic to Cloud services")
|
|
try:
|
|
for p in ports: ufw.allow(p)
|
|
stderr("Rules set")
|
|
except CalledProcessError,e:
|
|
print e.stdout+e.stderr
|
|
bail(E_FWRECONFIGFAILED,"Firewall rules could not be set")
|
|
|
|
stderr("We are going to enable ufw now. This may disrupt network connectivity and service availability. See the ufw documentation for information on how to manage ufw firewall policies.")
|
|
try:
|
|
o = ufw.enable < "y\n" ; print o.stdout + o.stderr
|
|
except CalledProcessError,e:
|
|
print e.stdout+e.stderr
|
|
bail(E_FWRECONFIGFAILED,"Firewall could not be enabled")
|
|
|
|
stderr("Examining console-proxy configuration")
|
|
fn = "@CPSYSCONFDIR@/agent.properties"
|
|
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()
|
|
|
|
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)
|
|
newhost = raw_input().strip()
|
|
if newhost: host = newhost
|
|
confopts["host"] = host
|
|
|
|
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)
|
|
try: file(fn,"w").write(text)
|
|
except Exception: bail(E_CPRECONFIGFAILED,"Console Proxy configuration failed")
|
|
|
|
stderr("")
|
|
stderr("Cloud Console Proxy setup completed successfully")
|
|
|
|
stderr("Starting the Cloud Console Proxy")
|
|
try:
|
|
m = service("@PACKAGE@-console-proxy","stop")
|
|
print m.stdout + m.stderr
|
|
except CalledProcessError,e:
|
|
print e.stdout + e.stderr
|
|
|
|
try:
|
|
m = service("@PACKAGE@-console-proxy","start")
|
|
print m.stdout + m.stderr
|
|
except CalledProcessError,e:
|
|
print e.stdout + e.stderr
|
|
bail(E_CPFAILEDTOSTART,"@PACKAGE@-console-proxy failed to start")
|
|
# FIXMES: 1) nullify networkmanager on ubuntu (asking the user first) and enable the networking service permanently
|