mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
refactore cloud related tools
This commit is contained in:
parent
fd24a1e240
commit
cbf2b03e31
@ -1,148 +1,107 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
import logging
|
||||
import sys
|
||||
import socket
|
||||
from cloud.cloudException import CloudRuntimeException, CloudInternalException
|
||||
from cloud.utilities import initLoging
|
||||
from cloud.configFileOps import configFileOps
|
||||
from cloud.globalEnv import globalEnv
|
||||
from cloud.networkConfig import networkConfig
|
||||
from cloud.syscfg import sysConfigFactory
|
||||
|
||||
import sys, os, subprocess, errno, re, traceback, getopt
|
||||
from optparse import OptionParser
|
||||
|
||||
def getUserInputs():
|
||||
print "Welcome to myCloud Setup:"
|
||||
|
||||
# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
|
||||
# ---- We do this so cloud_utils can be looked up in the following order:
|
||||
# ---- 1) Sources directory
|
||||
# ---- 2) waf configured PYTHONDIR
|
||||
# ---- 3) System Python path
|
||||
for pythonpath in (
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
||||
):
|
||||
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
||||
# ---- End snippet of code ----
|
||||
import cloud_utils
|
||||
from cloud_utils import stderr,CheckFailed,TaskFailed,backup_etc,restore_etc
|
||||
from cloud_utils import setup_agent_config,stop_service,enable_service
|
||||
from cloud_utils import exit as bail
|
||||
from cloud_utils import all, any
|
||||
cfo = configFileOps("/etc/cloud/agent/agent.properties")
|
||||
oldMgt = cfo.getEntry("host")
|
||||
|
||||
mgtSvr = raw_input("Please input the Management Server Name/IP:[%s]"%oldMgt)
|
||||
if mgtSvr == "":
|
||||
mgtSvr = oldMgt
|
||||
try:
|
||||
socket.getaddrinfo(mgtSvr, 443)
|
||||
except:
|
||||
print "Failed to resolve %s. Please input correct server name or IP."%mgtSvr
|
||||
exit(1)
|
||||
|
||||
#--------------- procedure starts here ------------
|
||||
oldToken = cfo.getEntry("zone")
|
||||
zoneToken = raw_input("Please input the Zone Token:[%s]"%oldToken)
|
||||
|
||||
if zoneToken == "":
|
||||
zoneToken = oldToken
|
||||
|
||||
# FÏXME for backup and restore: collect service state for all services so we can restore the system's runtime state back to what it was before
|
||||
# possible exit states:
|
||||
# a. system configuration needs administrator attention
|
||||
# b. automatic reconfiguration failed
|
||||
# c. process interrupted
|
||||
# d. everything was configured properly (exit status 0)
|
||||
try:
|
||||
defaultNic = networkConfig.getDefaultNetwork()
|
||||
except:
|
||||
print "Failed to get default route. Please configure your network to have a default route"
|
||||
exit(1)
|
||||
|
||||
defNic = defaultNic.name
|
||||
network = raw_input("Please choose which network used to create VM:[%s]"%defNic)
|
||||
if network == "":
|
||||
if defNic == "":
|
||||
print "You need to specifiy one of Nic or bridge on your system"
|
||||
exit(1)
|
||||
elif network == "":
|
||||
network = defNic
|
||||
|
||||
brname = "@PACKAGE@br0"
|
||||
servicename = "@PACKAGE@-agent"
|
||||
configfile = "@AGENTSYSCONFDIR@/agent.properties"
|
||||
backupdir = "@SHAREDSTATEDIR@/@AGENTPATH@/etcbackup"
|
||||
return [mgtSvr, zoneToken, network]
|
||||
|
||||
#=================== the magic happens here ====================
|
||||
if __name__ == '__main__':
|
||||
initLoging("/var/log/cloud/setupAgent.log")
|
||||
glbEnv = globalEnv()
|
||||
|
||||
glbEnv.mode = "Agent"
|
||||
glbEnv.agentMode = "Agent"
|
||||
parser = OptionParser()
|
||||
parser.add_option("-a", action="store_true", dest="auto", help="auto mode")
|
||||
parser.add_option("-m", "--host", dest="mgt", help="management server name or IP")
|
||||
parser.add_option("-z", "--zone", dest="zone", help="zone id")
|
||||
parser.add_option("-p", "--pod", dest="pod", help="pod id")
|
||||
parser.add_option("-c", "--cluster", dest="cluster", help="cluster id")
|
||||
parser.add_option("-g", "--guid", dest="guid", help="guid")
|
||||
parser.add_option("--pubNic", dest="pubNic", help="public nic")
|
||||
parser.add_option("--prvNic", dest="prvNic", help="private nic")
|
||||
parser.add_option("--guestNic", dest="guestNic", help="guest nic")
|
||||
|
||||
try:
|
||||
# parse cmd line
|
||||
opts, args = getopt.getopt(sys.argv[1:], "a", ["host=", "zone=", "pod=", "cluster=", "no-kvm", "guid=", "pubNic=", "prvNic="])
|
||||
host=None
|
||||
zone=None
|
||||
pod=None
|
||||
cluster=None
|
||||
guid=None
|
||||
pubNic=None
|
||||
prvNic=None
|
||||
autoMode=False
|
||||
do_check_kvm = True
|
||||
for opt, arg in opts:
|
||||
if opt == "--host":
|
||||
if arg != "":
|
||||
host = arg
|
||||
elif opt == "--zone":
|
||||
if arg != "":
|
||||
zone = arg
|
||||
elif opt == "--pod":
|
||||
if arg != "":
|
||||
pod = arg
|
||||
elif opt == "--cluster":
|
||||
if arg != "":
|
||||
cluster = arg
|
||||
elif opt == "--guid":
|
||||
if arg != "":
|
||||
guid = arg
|
||||
elif opt == "--pubNic":
|
||||
pubNic = arg
|
||||
elif opt == "--prvNic":
|
||||
prvNic = arg
|
||||
elif opt == "--no-kvm":
|
||||
do_check_kvm = False
|
||||
elif opt == "-a":
|
||||
autoMode=True
|
||||
|
||||
if autoMode:
|
||||
cloud_utils.setLogFile("/var/log/cloud/setupAgent.log")
|
||||
|
||||
stderr("Welcome to the Cloud Agent setup")
|
||||
stderr("")
|
||||
# pre-flight checks for things that the administrator must fix
|
||||
try:
|
||||
for f,n in cloud_utils.preflight_checks(
|
||||
do_check_kvm=do_check_kvm
|
||||
):
|
||||
stderr(n)
|
||||
f()
|
||||
except CheckFailed,e:
|
||||
stderr(str(e))
|
||||
bail(cloud_utils.E_NEEDSMANUALINTERVENTION,
|
||||
"Cloud Agent setup cannot continue until these issues have been addressed")
|
||||
|
||||
# system configuration tasks that our Cloud Agent setup performs
|
||||
|
||||
try:
|
||||
tasks = cloud_utils.config_tasks(brname, pubNic, prvNic)
|
||||
for t in tasks:
|
||||
t.setAutoMode(autoMode)
|
||||
if all( [ t.done() for t in tasks ] ):
|
||||
|
||||
stderr("All configuration tasks have been performed already")
|
||||
|
||||
else:
|
||||
|
||||
backup_etc(backupdir)
|
||||
try:
|
||||
# run all tasks that have not been done
|
||||
for t in [ n for n in tasks if not n.done() ]:
|
||||
t.run()
|
||||
except:
|
||||
# oops, something wrong, restore system to earlier state and re-raise
|
||||
stderr("A fatal issue has been detected -- restoring system configuration.\nPlease be patient; *do not* interrupt this process.")
|
||||
restore_etc(backupdir)
|
||||
for t in [ n for n in tasks if hasattr(n,"restore_state") ]:
|
||||
t.restore_state()
|
||||
raise
|
||||
|
||||
except (TaskFailed,CheckFailed),e:
|
||||
# some configuration task or post-flight check failed, we exit right away
|
||||
stderr(str(e))
|
||||
bail(cloud_utils.E_SETUPFAILED,"Cloud Agent setup failed")
|
||||
|
||||
setup_agent_config(configfile, host, zone, pod, cluster, guid, pubNic, prvNic)
|
||||
stderr("Enabling and starting the Cloud Agent")
|
||||
stop_service(servicename)
|
||||
enable_service(servicename)
|
||||
stderr("Cloud Agent restarted")
|
||||
|
||||
except KeyboardInterrupt,e:
|
||||
# user interrupted, we exit right away
|
||||
bail(cloud_utils.E_INTERRUPTED,"Cloud Agent setup interrupted")
|
||||
except SystemExit,e:
|
||||
# process above handled a failure then called bail(), which raises a SystemExit on CentOS
|
||||
sys.exit(e.code)
|
||||
except Exception,e:
|
||||
# at ths point, any exception has been dealt with cleanly by restoring system config from a backup
|
||||
# we just inform the user that there was a problem
|
||||
# and bail prematurely
|
||||
stderr("Cloud Agent setup has experienced an unrecoverable error. Please report the following technical details to Cloud.com.")
|
||||
traceback.print_exc()
|
||||
bail(cloud_utils.E_UNHANDLEDEXCEPTION,"Cloud Agent setup ended prematurely")
|
||||
(options, args) = parser.parse_args()
|
||||
if options.auto is None:
|
||||
userInputs = getUserInputs()
|
||||
glbEnv.mgtSvr = userInputs[0]
|
||||
glbEnv.zone = userInputs[1]
|
||||
glbEnv.defaultNic = userInputs[2]
|
||||
#generate UUID
|
||||
glbEnv.uuid = configFileOps("/etc/cloud/agent/agent.properties").getEntry("guid")
|
||||
if glbEnv.uuid == "":
|
||||
glbEnv.uuid = bash("uuidgen").getStdout()
|
||||
else:
|
||||
for para, value in options.__dict__.items():
|
||||
if value is None:
|
||||
print "Missing operand:%s"%para
|
||||
print "Try %s --help for more information"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
stderr("")
|
||||
stderr("Cloud Agent setup completed successfully")
|
||||
|
||||
# ========================= end program ========================
|
||||
glbEnv.uuid = options.guid
|
||||
glbEnv.mgtSvr = options.mgt
|
||||
glbEnv.zone = options.zone
|
||||
glbEnv.pod = options.pod
|
||||
glbEnv.cluster = options.cluster
|
||||
glbEnv.nics.append(options.prvNic)
|
||||
glbEnv.nics.append(options.pubNic)
|
||||
glbEnv.nics.append(options.guestNic)
|
||||
|
||||
print "Starting to configure your system:"
|
||||
syscfg = sysConfigFactory.getSysConfigFactory(glbEnv)
|
||||
try:
|
||||
syscfg.config()
|
||||
print "Cloud Agent setup is Done!"
|
||||
except (CloudRuntimeException,CloudInternalException), e:
|
||||
print e
|
||||
print "Try to restore your system:"
|
||||
try:
|
||||
syscfg.restore()
|
||||
except:
|
||||
pass
|
||||
|
||||
@ -1,263 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, subprocess, errno, re
|
||||
|
||||
# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
|
||||
# ---- We do this so cloud_utils can be looked up in the following order:
|
||||
# ---- 1) Sources directory
|
||||
# ---- 2) waf configured PYTHONDIR
|
||||
# ---- 3) System Python path
|
||||
for pythonpath in (
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
||||
):
|
||||
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
||||
# ---- End snippet of code ----
|
||||
from cloud_utils import check_selinux, CheckFailed
|
||||
|
||||
E_GENERIC= 1
|
||||
E_NOKVM = 2
|
||||
E_NODEFROUTE = 3
|
||||
E_DHCP = 4
|
||||
E_NOPERSISTENTNET = 5
|
||||
E_VIRTRECONFIGFAILED = 7
|
||||
E_FWRECONFIGFAILED = 8
|
||||
E_AGENTRECONFIGFAILED = 9
|
||||
E_AGENTFAILEDTOSTART = 10
|
||||
E_NOFQDN = 11
|
||||
E_OSUNSUPP = 11
|
||||
E_SUDORECONFIGFAILED = 6
|
||||
E_SELINUXENABLED=12
|
||||
|
||||
|
||||
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("CloudStack Management Server 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_kvm(): return check_call(["kvm-ok"])
|
||||
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__()
|
||||
|
||||
def checkselinux():
|
||||
try:
|
||||
check_selinux()
|
||||
except CheckFailed,e:
|
||||
bail(E_SELINUXENABLED,"SELINUX is set to enforcing. Please set it to permissive in /etc/selinux/config. Then reboot or run setenforce permissive. Then run this program again.")
|
||||
|
||||
|
||||
ip = Command("ip")
|
||||
service = Command("/sbin/service")
|
||||
chkconfig = Command("/sbin/chkconfig")
|
||||
updatercd = Command("update-rc.d")
|
||||
ufw = Command("ufw")
|
||||
iptables = Command("/sbin/iptables")
|
||||
iptables_save = Command("/sbin/iptables-save")
|
||||
kvmok = Command("kvm-ok")
|
||||
ifconfig = Command("/sbin/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 CloudStack Management 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")
|
||||
|
||||
if Fedora or CentOS:
|
||||
checkselinux()
|
||||
|
||||
try:
|
||||
service("@PACKAGE@-management","status")
|
||||
stderr("Stopping the CloudStack Management Server")
|
||||
m = service("@PACKAGE@-management","stop")
|
||||
print m.stdout + m.stderr
|
||||
stderr("CloudStack Management Server stopped")
|
||||
except CalledProcessError,e:
|
||||
pass
|
||||
|
||||
sudoerstext = file("/etc/sudoers").readlines()
|
||||
def restore():
|
||||
try: file("/etc/sudoers","w").write(''.join(sudoerstext))
|
||||
except OSError,e: raise
|
||||
|
||||
try:
|
||||
stderr("Configure /etc/sudoers")
|
||||
newtext = []
|
||||
clouder = "cloud ALL = NOPASSWD : ALL"
|
||||
hasClouder = False
|
||||
for line in sudoerstext:
|
||||
if "Defaults" in line and "requiretty" in line:
|
||||
continue
|
||||
if clouder in line:
|
||||
hasClouder = True
|
||||
newtext.append(line)
|
||||
if not hasClouder:
|
||||
newtext.append(clouder+'\n')
|
||||
file("/etc/sudoers", "w").write(''.join(newtext))
|
||||
except:
|
||||
restore()
|
||||
bail(E_SUDORECONFIGFAILED,"sudoers reconfiguration failed")
|
||||
|
||||
ports = "80 8080 8096 8250 9090".split()
|
||||
if Fedora or CentOS:
|
||||
try:
|
||||
o = chkconfig("--list","iptables")
|
||||
iptableschkconfig = True
|
||||
except CalledProcessError,e:
|
||||
stderr("No need to set up iptables as the service is not registered in the SysV init system")
|
||||
iptableschkconfig = False
|
||||
if iptableschkconfig is True:
|
||||
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 CloudStack services")
|
||||
service.iptables.start() ; print o.stdout + o.stderr
|
||||
o = iptables_save()
|
||||
for p in ports:
|
||||
r = "INPUT -p tcp -m tcp --dport %s -j ACCEPT" % p
|
||||
if r in o.stdout:
|
||||
continue
|
||||
iptables("-I","INPUT","1","-p","tcp","--dport",p,"-j","ACCEPT")
|
||||
|
||||
o = service.iptables.save() ; print o.stdout + o.stderr
|
||||
else:
|
||||
stderr("No need to set up iptables as the service is unconfigured or not set to start up at boot")
|
||||
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 CloudStack 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("")
|
||||
stderr("CloudStack Management Server setup completed successfully")
|
||||
|
||||
try:
|
||||
if Fedora or CentOS: chkconfig("tomcat6","off")
|
||||
else: updatercd("tomcat6","disable")
|
||||
service("tomcat6","status")
|
||||
stderr("Stopping Tomcat")
|
||||
m = service("tomcat6","stop")
|
||||
print m.stdout + m.stderr
|
||||
stderr("Tomcat stopped")
|
||||
except CalledProcessError,e:
|
||||
pass
|
||||
|
||||
try:
|
||||
if Fedora or CentOS:
|
||||
chkconfig("--level","35","network","on")
|
||||
except CalledProcessError,e:
|
||||
pass
|
||||
|
||||
stderr("Starting the CloudStack Management Server")
|
||||
try:
|
||||
m = service("@PACKAGE@-management","start")
|
||||
print m.stdout + m.stderr
|
||||
except CalledProcessError,e:
|
||||
print e.stdout + e.stderr
|
||||
bail(E_AGENTFAILEDTOSTART,"@PACKAGE@-management failed to start")
|
||||
|
||||
|
||||
# FIXMES: 1) nullify networkmanager on ubuntu (asking the user first) and enable the networking service permanently
|
||||
from cloud.syscfg import sysConfigFactory
|
||||
from cloud.utilities import initLoging
|
||||
from cloud.cloudException import CloudRuntimeException, CloudInternalException
|
||||
from cloud.globalEnv import globalEnv
|
||||
if __name__ == '__main__':
|
||||
initLoging("/var/log/cloud/setupManagement.log")
|
||||
glbEnv = globalEnv()
|
||||
|
||||
glbEnv.mode = "Server"
|
||||
|
||||
print "Starting to configure CloudStack Management Server:"
|
||||
syscfg = sysConfigFactory.getSysConfigFactory(glbEnv)
|
||||
try:
|
||||
syscfg.config()
|
||||
print "CloudStack Management Server setup is Done!"
|
||||
except (CloudRuntimeException, CloudInternalException), e:
|
||||
print e
|
||||
print "Try to restore your system:"
|
||||
try:
|
||||
syscfg.restore()
|
||||
except:
|
||||
pass
|
||||
|
||||
0
python/lib/cloudutils/__init__.py
Normal file
0
python/lib/cloudutils/__init__.py
Normal file
29
python/lib/cloudutils/cloudException.py
Normal file
29
python/lib/cloudutils/cloudException.py
Normal file
@ -0,0 +1,29 @@
|
||||
import sys
|
||||
import traceback
|
||||
class CloudRuntimeException(Exception):
|
||||
def __init__(self, errMsg):
|
||||
self.errMsg = errMsg
|
||||
|
||||
value = sys.exc_info()[1]
|
||||
if value is not None:
|
||||
self.errMsg += ", due to:" + str(value)
|
||||
|
||||
self.details = formatExceptionInfo()
|
||||
def __str__(self):
|
||||
return self.errMsg
|
||||
def getDetails(self):
|
||||
return self.details
|
||||
|
||||
class CloudInternalException(Exception):
|
||||
def __init__(self, errMsg):
|
||||
self.errMsg = errMsg
|
||||
def __str__(self):
|
||||
return self.errMsg
|
||||
|
||||
def formatExceptionInfo(maxTBlevel=5):
|
||||
cla, exc, trbk = sys.exc_info()
|
||||
excTb = traceback.format_tb(trbk, maxTBlevel)
|
||||
msg = str(exc) + "\n"
|
||||
for tb in excTb:
|
||||
msg += tb
|
||||
return msg
|
||||
148
python/lib/cloudutils/configFileOps.py
Normal file
148
python/lib/cloudutils/configFileOps.py
Normal file
@ -0,0 +1,148 @@
|
||||
import re
|
||||
import tempfile
|
||||
import shutil
|
||||
from utilities import bash
|
||||
class configFileOps:
|
||||
class entry:
|
||||
def __init__(self, name, value, op, separator):
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.state = "new"
|
||||
self.op = op
|
||||
self.separator = separator
|
||||
def setState(self, state):
|
||||
self.state = state
|
||||
def getState(self):
|
||||
return self.state
|
||||
|
||||
def __init__(self, fileName, cfg=None):
|
||||
self.fileName = fileName
|
||||
self.entries = []
|
||||
self.backups = []
|
||||
|
||||
if cfg is not None:
|
||||
cfg.cfoHandlers.append(self)
|
||||
|
||||
def addEntry(self, name, value, separator="="):
|
||||
e = self.entry(name, value, "add", separator)
|
||||
self.entries.append(e)
|
||||
|
||||
def rmEntry(self, name, value, separator="="):
|
||||
entry = self.entry(name, value, "rm", separator)
|
||||
self.entries.append(entry)
|
||||
|
||||
def getEntry(self, name, separator="="):
|
||||
try:
|
||||
ctx = file(self.fileName).read(-1)
|
||||
match = re.search("^" + name + ".*", ctx, re.MULTILINE)
|
||||
if match is None:
|
||||
return ""
|
||||
line = match.group(0).split(separator, 1)
|
||||
return line[1]
|
||||
except:
|
||||
return ""
|
||||
|
||||
def save(self):
|
||||
fp = open(self.fileName, "r")
|
||||
newLines = []
|
||||
for line in fp.readlines():
|
||||
matched = False
|
||||
for entry in self.entries:
|
||||
if entry.op == "add":
|
||||
if entry.separator == "=":
|
||||
matchString = "^\ *" + entry.name + ".*"
|
||||
elif entry.separator == " ":
|
||||
matchString = "^\ *" + entry.name + "\ *" + entry.value
|
||||
else:
|
||||
if entry.separator == "=":
|
||||
matchString = "^\ *" + entry.name + "\ *=\ *" + entry.value
|
||||
else:
|
||||
matchString = "^\ *" + entry.name + "\ *" + entry.value
|
||||
|
||||
match = re.match(matchString, line)
|
||||
if match is not None:
|
||||
if entry.op == "add" and entry.separator == "=":
|
||||
newline = entry.name + "=" + entry.value + "\n"
|
||||
entry.setState("set")
|
||||
newLines.append(newline)
|
||||
self.backups.append([line, newline])
|
||||
matched = True
|
||||
break
|
||||
elif entry.op == "rm":
|
||||
entry.setState("set")
|
||||
self.backups.append([line, None])
|
||||
matched = True
|
||||
break
|
||||
|
||||
if not matched:
|
||||
newLines.append(line)
|
||||
|
||||
for entry in self.entries:
|
||||
if entry.getState() != "set":
|
||||
if entry.op == "add":
|
||||
newline = entry.name + entry.separator + entry.value + "\n"
|
||||
newLines.append(newline)
|
||||
self.backups.append([None, newline])
|
||||
entry.setState("set")
|
||||
|
||||
fp.close()
|
||||
|
||||
file(self.fileName, "w").writelines(newLines)
|
||||
|
||||
def replace_line(self, startswith,stanza,always_add=False):
|
||||
lines = [ s.strip() for s in file(self.fileName).readlines() ]
|
||||
newlines = []
|
||||
replaced = False
|
||||
for line in lines:
|
||||
if re.search(startswith, line):
|
||||
if stanza is not None:
|
||||
newlines.append(stanza)
|
||||
self.backups.append([line, stanza])
|
||||
replaced = True
|
||||
else: newlines.append(line)
|
||||
if not replaced and always_add:
|
||||
newlines.append(stanza)
|
||||
self.backups.append([None, stanza])
|
||||
newlines = [ s + '\n' for s in newlines ]
|
||||
file(self.fileName,"w").writelines(newlines)
|
||||
|
||||
def replace_or_add_line(self, startswith,stanza):
|
||||
return self.replace_line(startswith,stanza,always_add=True)
|
||||
|
||||
def add_lines(self, lines, addToBackup=True):
|
||||
fp = file(self.fileName).read(-1)
|
||||
sh = re.escape(lines)
|
||||
match = re.search(sh, fp, re.MULTILINE)
|
||||
if match is not None:
|
||||
return
|
||||
|
||||
fp += lines
|
||||
file(self.fileName, "w").write(fp)
|
||||
self.backups.append([None, lines])
|
||||
|
||||
def replace_lines(self, src, dst, addToBackup=True):
|
||||
fp = file(self.fileName).read(-1)
|
||||
sh = re.escape(src)
|
||||
if dst is None:
|
||||
dst = ""
|
||||
repl,nums = re.subn(sh, dst, fp)
|
||||
if nums <=0:
|
||||
return
|
||||
file(self.fileName, "w").write(repl)
|
||||
if addToBackup:
|
||||
self.backups.append([src, dst])
|
||||
|
||||
def backup(self):
|
||||
for oldLine, newLine in self.backups:
|
||||
if newLine is None:
|
||||
self.add_lines(oldLine, False)
|
||||
else:
|
||||
self.replace_lines(newLine, oldLine, False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
cfo = configFileOps("./sudoers")
|
||||
#cloud ALL = NOPASSWD : ALL
|
||||
cfo.addEntry("cloud ALL ", "NOPASSWD : ALL")
|
||||
cfo.rmEntry("Defaults", "requiretty", " ")
|
||||
#cfo.addEntry("zone", "test", " ")
|
||||
cfo.save()
|
||||
66
python/lib/cloudutils/db.py
Normal file
66
python/lib/cloudutils/db.py
Normal file
@ -0,0 +1,66 @@
|
||||
import MySQLdb
|
||||
import os
|
||||
from utilities import bash
|
||||
from cloudException import CloudRuntimeException
|
||||
import sys
|
||||
class Database:
|
||||
"""Database connection"""
|
||||
def __init__(self, username, password=None, host='localhost', port='3306', db="cloud"):
|
||||
self.host = host
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.port = port
|
||||
self.db = db
|
||||
|
||||
def execute(self, statement):
|
||||
txn = None
|
||||
try:
|
||||
if self.password is not None:
|
||||
txn = MySQLdb.Connect(host=self.host, user=self.username,
|
||||
passwd=self.password, db=self.db)
|
||||
else:
|
||||
txn = MySQLdb.Connect(host=self.host, user=self.username,
|
||||
db=self.db)
|
||||
cursor = txn.cursor()
|
||||
cursor.execute(statement)
|
||||
cursor.close()
|
||||
txn.commit()
|
||||
if txn is not None:
|
||||
try:
|
||||
txn.close()
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
if txn is not None:
|
||||
try:
|
||||
txn.close()
|
||||
except:
|
||||
pass
|
||||
raise CloudRuntimeException("Failed to execute:%s"%statement)
|
||||
|
||||
def testConnection(self):
|
||||
try:
|
||||
if self.password is not None:
|
||||
db = MySQLdb.Connect(host=self.host, user=self.username,
|
||||
passwd=self.password, db=self.db)
|
||||
else:
|
||||
db = MySQLdb.Connect(host=self.host, user=self.username,
|
||||
db=self.db)
|
||||
return True
|
||||
except:
|
||||
raise CloudRuntimeException("Failed to Connect to DB")
|
||||
|
||||
def executeFromFile(self, file):
|
||||
if not os.path.exists(file):
|
||||
return False
|
||||
|
||||
cmdLine = "mysql --host=" + self.host + " --port=" + str(self.port) + " --user=" + self.username
|
||||
if self.password is not None:
|
||||
cmdLine += " --password=" + self.password
|
||||
|
||||
cmdLine += " < " + file
|
||||
|
||||
try:
|
||||
bash(cmdLine)
|
||||
except:
|
||||
raise CloudRuntimeException("Failed to execute " + cmdLine)
|
||||
24
python/lib/cloudutils/globalEnv.py
Normal file
24
python/lib/cloudutils/globalEnv.py
Normal file
@ -0,0 +1,24 @@
|
||||
class globalEnv:
|
||||
def __init__(self):
|
||||
#Agent/Server/Db
|
||||
self.mode = None
|
||||
#server mode: normal/mycloud
|
||||
self.svrMode = None
|
||||
#myCloud/Agent/Console
|
||||
self.agentMode = None
|
||||
#debug
|
||||
self.debug = False
|
||||
#management server IP
|
||||
self.mgtSvr = None
|
||||
#zone id or zone name
|
||||
self.zone = None
|
||||
#pod id or pod name
|
||||
self.pod = None
|
||||
#cluster id or cluster name
|
||||
self.cluster = None
|
||||
#nics: 0: private nic, 1: guest nic, 2: public nic used by agent
|
||||
self.nics = []
|
||||
#uuid
|
||||
self.uuid = None
|
||||
#default private network
|
||||
self.privateNet = "cloudbr0"
|
||||
135
python/lib/cloudutils/networkConfig.py
Normal file
135
python/lib/cloudutils/networkConfig.py
Normal file
@ -0,0 +1,135 @@
|
||||
from utilities import bash
|
||||
from cloudException import CloudRuntimeException, CloudInternalException
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
||||
class networkConfig:
|
||||
class devInfo:
|
||||
def __init__(self, macAddr, ipAddr, netmask, gateway, type, name):
|
||||
self.name = name
|
||||
self.macAdrr = macAddr
|
||||
self.ipAddr = ipAddr
|
||||
self.netmask = netmask
|
||||
self.gateway = gateway
|
||||
self.type = type
|
||||
self.name = name
|
||||
#dhcp or static
|
||||
self.method = None
|
||||
|
||||
@staticmethod
|
||||
def getDefaultNetwork():
|
||||
cmd = bash("route -n|awk \'/^0.0.0.0/ {print $2,$8}\'")
|
||||
if not cmd.isSuccess():
|
||||
logging.debug("Failed to get default route")
|
||||
raise CloudRuntimeException("Failed to get default route")
|
||||
|
||||
result = cmd.getStdout().split(" ")
|
||||
gateway = result[0]
|
||||
dev = result[1]
|
||||
|
||||
pdi = networkConfig.getDevInfo(dev)
|
||||
logging.debug("Found default network device:%s"%pdi.name)
|
||||
pdi.gateway = gateway
|
||||
return pdi
|
||||
|
||||
@staticmethod
|
||||
def createBridge(dev, brName):
|
||||
if not networkConfig.isBridgeSupported():
|
||||
logging.debug("bridge is not supported")
|
||||
return False
|
||||
if networkConfig.isBridgeEnslavedWithDevices(brName):
|
||||
logging.debug("bridge: %s has devices enslaved"%brName)
|
||||
return False
|
||||
|
||||
cmds = ""
|
||||
if not networkConfig.isBridge(brName):
|
||||
cmds = "brctl addbr %s ;"%brName
|
||||
|
||||
cmds += "ifconfig %s up;"%brName
|
||||
cmds += "brctl addif %s %s"%(brName, dev)
|
||||
return bash(cmds).isSuccess()
|
||||
|
||||
@staticmethod
|
||||
def isBridgeEnslavedWithDevices(brName):
|
||||
if not networkConfig.isBridge(brName):
|
||||
return False
|
||||
|
||||
if not os.listdir("/sys/class/net/%s/brif"%brName):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def isBridgeSupported():
|
||||
if os.path.exists("/proc/sys/net/bridge"):
|
||||
return True
|
||||
|
||||
return bash("modprobe bridge").isSucess()
|
||||
|
||||
@staticmethod
|
||||
def isNetworkDev(devName):
|
||||
return os.path.exists("/sys/class/net/%s"%devName)
|
||||
|
||||
@staticmethod
|
||||
def isBridgePort(devName):
|
||||
return os.path.exists("/sys/class/net/%s/brport"%devName)
|
||||
|
||||
@staticmethod
|
||||
def isBridge(devName):
|
||||
return os.path.exists("/sys/class/net/%s/bridge"%devName)
|
||||
|
||||
@staticmethod
|
||||
def getBridge(devName):
|
||||
bridgeName = None
|
||||
if os.path.exists("/sys/class/net/%s/brport/bridge"%devName):
|
||||
realPath = os.path.realpath("/sys/class/net/%s/brport/bridge"%devName)
|
||||
bridgeName = realPath.split("/")[-1]
|
||||
return bridgeName
|
||||
|
||||
@staticmethod
|
||||
def getEnslavedDev(br, brPort):
|
||||
if not networkConfig.isBridgeEnslavedWithDevices(br):
|
||||
return None
|
||||
|
||||
for dev in os.listdir("/sys/class/net/%s/brif"%br):
|
||||
br_port = int(file("/sys/class/net/%s/brif/%s/port_no"%(br,dev)).readline().strip("\n"), 16)
|
||||
if br_port == brPort:
|
||||
return dev
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def getDevInfo(dev):
|
||||
if not networkConfig.isNetworkDev(dev):
|
||||
logging.debug("dev: " + dev + " is not a network device")
|
||||
raise CloudInternalException("dev: " + dev + " is not a network device")
|
||||
|
||||
netmask = None
|
||||
ipAddr = None
|
||||
macAddr = None
|
||||
|
||||
cmd = bash("ifconfig " + dev)
|
||||
if not cmd.isSuccess():
|
||||
logging.debug("Failed to get address from ifconfig")
|
||||
raise CloudInternalException("Failed to get network info by ifconfig %s"%dev)
|
||||
|
||||
for line in cmd.getLines():
|
||||
if line.find("HWaddr") != -1:
|
||||
macAddr = line.split("HWaddr ")[1].strip(" ")
|
||||
elif line.find("inet ") != -1:
|
||||
m = re.search("addr:(.*)\ *Bcast:(.*)\ *Mask:(.*)", line)
|
||||
if m is not None:
|
||||
ipAddr = m.group(1).rstrip(" ")
|
||||
netmask = m.group(3).rstrip(" ")
|
||||
|
||||
if networkConfig.isBridgePort(dev):
|
||||
type = "brport"
|
||||
elif networkConfig.isBridge(dev):
|
||||
type = "bridge"
|
||||
else:
|
||||
type = "dev"
|
||||
|
||||
return networkConfig.devInfo(macAddr, ipAddr, netmask, None, type, dev)
|
||||
|
||||
|
||||
627
python/lib/cloudutils/serviceConfig.py
Normal file
627
python/lib/cloudutils/serviceConfig.py
Normal file
@ -0,0 +1,627 @@
|
||||
from utilities import writeProgressBar, bash
|
||||
from cloudException import CloudRuntimeException, CloudInternalException, formatExceptionInfo
|
||||
import logging
|
||||
from networkConfig import networkConfig
|
||||
import re
|
||||
from configFileOps import configFileOps
|
||||
import os
|
||||
import shutil
|
||||
|
||||
class serviceCfgBase(object):
|
||||
def __init__(self, syscfg):
|
||||
self.status = None
|
||||
self.serviceName = ""
|
||||
self.cfoHandlers = []
|
||||
self.syscfg = syscfg
|
||||
self.netMgrRunning = False
|
||||
|
||||
def configration(self):
|
||||
writeProgressBar("Configure " + self.serviceName + " ...", None)
|
||||
result = False
|
||||
try:
|
||||
result = self.config()
|
||||
self.status = result
|
||||
writeProgressBar(None, result)
|
||||
return result
|
||||
except CloudRuntimeException, e:
|
||||
self.status = result
|
||||
writeProgressBar(None, result)
|
||||
logging.debug(e.getDetails())
|
||||
raise e
|
||||
except CloudInternalException, e:
|
||||
self.status = result
|
||||
writeProgressBar(None, result)
|
||||
raise e
|
||||
except:
|
||||
logging.debug(formatExceptionInfo())
|
||||
if self.syscfg.env.mode == "Server":
|
||||
raise CloudRuntimeException("Configure %s failed, Please check the /var/log/cloud/setupManagement.log for detail"%self.serviceName)
|
||||
else:
|
||||
raise CloudRuntimeException("Configure %s failed, Please check the /var/log/cloud/setupAgent.log for detail"%self.serviceName)
|
||||
|
||||
def backup(self):
|
||||
if self.status is None:
|
||||
return True
|
||||
|
||||
writeProgressBar("Restore " + self.serviceName + " ...", None)
|
||||
result = False
|
||||
try:
|
||||
for cfo in self.cfoHandlers:
|
||||
cfo.backup()
|
||||
|
||||
result = self.restore()
|
||||
except (CloudRuntimeException, CloudInternalException), e:
|
||||
logging.debug(e)
|
||||
|
||||
writeProgressBar(None, result)
|
||||
|
||||
def config(self):
|
||||
return True
|
||||
|
||||
def restore(self):
|
||||
return True
|
||||
|
||||
class networkConfigBase:
|
||||
def __init__(self, syscfg):
|
||||
self.netcfg = networkConfig()
|
||||
self.serviceName = "Network"
|
||||
self.brName = None
|
||||
self.dev = None
|
||||
self.syscfg = syscfg
|
||||
|
||||
def isPreConfiged(self):
|
||||
preCfged = False
|
||||
for br in self.syscfg.env.nics:
|
||||
if not self.netcfg.isNetworkDev(br):
|
||||
raise CloudInternalException("%s is not a network device, is it down?"%br)
|
||||
if not self.netcfg.isBridge(br):
|
||||
raise CloudInternalException("%s is not a bridge"%br)
|
||||
preCfged = True
|
||||
|
||||
return preCfged
|
||||
|
||||
def cfgNetwork(self, dev=None, brName=None):
|
||||
if dev is None:
|
||||
device = self.netcfg.getDefaultNetwork()
|
||||
else:
|
||||
device = self.netcfg.getDevInfo(dev)
|
||||
|
||||
if device.type == "dev":
|
||||
if brName is None:
|
||||
brName = "cloudbr0"
|
||||
|
||||
self.writeToCfgFile(brName, device)
|
||||
elif device.type == "brport":
|
||||
brName = self.netcfg.getBridge(dev)
|
||||
brDevice = self.netcfg.getDevInfo(brName)
|
||||
self.writeToCfgFile(brDevice.name, device)
|
||||
elif device.type == "bridge":
|
||||
#Fixme, assuming the outgoing physcial device is on port 1
|
||||
enslavedDev = self.netcfg.getEnslavedDev(device.name, 1)
|
||||
if enslavedDev is None:
|
||||
raise CloudInternalException("Failed to get enslaved devices on bridge:%s"%device.name)
|
||||
|
||||
brDevice = device
|
||||
device = self.netcfg.getDevInfo(enslavedDev)
|
||||
brName = brDevice.name
|
||||
self.writeToCfgFile(brName, device)
|
||||
|
||||
self.brName = brName
|
||||
self.dev = device.name
|
||||
|
||||
def writeToCfgFile(self):
|
||||
pass
|
||||
|
||||
class networkConfigUbuntu(serviceCfgBase, networkConfigBase):
|
||||
def __init__(self, syscfg):
|
||||
super(networkConfigUbuntu, self).__init__(syscfg)
|
||||
networkConfigBase.__init__(self, syscfg)
|
||||
self.netCfgFile = "/etc/network/interfaces"
|
||||
|
||||
def getNetworkMethod(self, line):
|
||||
if line.find("static") != -1:
|
||||
return "static"
|
||||
elif line.find("dhcp") != -1:
|
||||
return "dhcp"
|
||||
else:
|
||||
logging.debug("Failed to find the network method from:%s"%line)
|
||||
raise CloudInternalException("Failed to find the network method from /etc/network/interfaces")
|
||||
|
||||
def addBridge(self, br, dev):
|
||||
bash("ifdown %s"%dev.name)
|
||||
for line in file(self.netCfgFile).readlines():
|
||||
match = re.match("^ *iface %s.*"%dev.name, line)
|
||||
if match is not None:
|
||||
dev.method = self.getNetworkMethod(match.group(0))
|
||||
bridgeCfg = "\niface %s inet manual\n \
|
||||
auto %s\n \
|
||||
iface %s inet %s\n \
|
||||
bridge_ports %s\n"%(dev.name, br, br, dev.method, dev.name)
|
||||
cfo = configFileOps(self.netCfgFile, self)
|
||||
cfo.replace_line("^ *iface %s.*"%dev.name, bridgeCfg)
|
||||
|
||||
def addDev(self, br, dev):
|
||||
logging.debug("Haven't implement yet")
|
||||
|
||||
def addBridgeAndDev(self, br, dev):
|
||||
logging.debug("Haven't implement yet")
|
||||
|
||||
def writeToCfgFile(self, br, dev):
|
||||
cfg = file(self.netCfgFile).read()
|
||||
ifaceDev = re.search("^ *iface %s.*"%dev.name, cfg, re.MULTILINE)
|
||||
ifaceBr = re.search("^ *iface %s.*"%br, cfg, re.MULTILINE)
|
||||
if ifaceDev is not None and ifaceBr is not None:
|
||||
logging.debug("%s:%s already configured"%(br, dev.name))
|
||||
return True
|
||||
elif ifaceDev is not None and ifaceBr is None:
|
||||
#reconfig bridge
|
||||
self.addBridge(br, dev)
|
||||
elif ifaceDev is None and ifaceBr is not None:
|
||||
#reconfig dev
|
||||
raise CloudInternalException("Missing device configuration, Need to add your network configuration into /etc/network/interfaces at first")
|
||||
else:
|
||||
raise CloudInternalException("Missing bridge/device network configuration, need to add your network configuration into /etc/network/interfaces at first")
|
||||
|
||||
def config(self):
|
||||
try:
|
||||
if super(networkConfigUbuntu, self).isPreConfiged():
|
||||
return True
|
||||
|
||||
self.netMgrRunning = self.syscfg.svo.isServiceRunning("network-manager")
|
||||
super(networkConfigUbuntu, self).cfgNetwork()
|
||||
if self.netMgrRunning:
|
||||
self.syscfg.svo.stopService("network-manager")
|
||||
self.syscfg.svo.disableService("network-manager")
|
||||
|
||||
if not bash("ifup %s"%self.brName).isSuccess():
|
||||
raise CloudInternalException("Can't start network:%s"%self.brName, bash.getErrMsg(self))
|
||||
|
||||
self.syscfg.env.nics.append(self.brName)
|
||||
self.syscfg.env.nics.append(self.brName)
|
||||
self.syscfg.env.nics.append(self.brName)
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def restore(self):
|
||||
try:
|
||||
if self.netMgrRunning:
|
||||
self.syscfg.svo.enableService("network-manager")
|
||||
self.syscfg.svo.startService("network-manager")
|
||||
|
||||
bash("/etc/init.d/networking stop")
|
||||
bash("/etc/init.d/networking start")
|
||||
return True
|
||||
except:
|
||||
logging.debug(formatExceptionInfo())
|
||||
return False
|
||||
|
||||
class networkConfigRedhat(serviceCfgBase, networkConfigBase):
|
||||
def __init__(self, syscfg):
|
||||
super(networkConfigRedhat, self).__init__(syscfg)
|
||||
networkConfigBase.__init__(self, syscfg)
|
||||
|
||||
def writeToCfgFile(self, brName, dev):
|
||||
self.devCfgFile = "/etc/sysconfig/network-scripts/ifcfg-%s"%dev.name
|
||||
self.brCfgFile = "/etc/sysconfig/network-scripts/ifcfg-%s"%brName
|
||||
|
||||
isDevExist = os.path.exists(self.devCfgFile)
|
||||
isBrExist = os.path.exists(self.brCfgFile)
|
||||
if isDevExist and isBrExist:
|
||||
logging.debug("%s:%s already configured"%(brName, dev.name))
|
||||
return True
|
||||
elif isDevExist and not isBrExist:
|
||||
#reconfig bridge
|
||||
self.addBridge(brName, dev)
|
||||
elif not isDevExist and isBrExist:
|
||||
#reconfig dev
|
||||
raise CloudInternalException("Missing device configuration, Need to add your network configuration into /etc/sysconfig/network-scripts at first")
|
||||
else:
|
||||
raise CloudInternalException("Missing bridge/device network configuration, need to add your network configuration into /etc/sysconfig/network-scripts at first")
|
||||
|
||||
|
||||
def addBridge(self, brName, dev):
|
||||
bash("ifdown %s"%dev.name)
|
||||
|
||||
if not os.path.exists(self.brCfgFile):
|
||||
shutil.copy(self.devCfgFile, self.brCfgFile)
|
||||
|
||||
#config device file at first: disable nm, set onboot=yes if not
|
||||
cfo = configFileOps(self.devCfgFile, self)
|
||||
cfo.addEntry("NM_CONTROLLED", "no")
|
||||
cfo.addEntry("ONBOOT", "yes")
|
||||
cfo.addEntry("BRIDGE", brName)
|
||||
cfo.save()
|
||||
|
||||
cfo = configFileOps(self.brCfgFile, self)
|
||||
cfo.addEntry("NM_CONTROLLED", "no")
|
||||
cfo.addEntry("ONBOOT", "yes")
|
||||
cfo.addEntry("DEVICE", brName)
|
||||
cfo.addEntry("TYPE", "Bridge")
|
||||
cfo.save()
|
||||
|
||||
def config(self):
|
||||
try:
|
||||
if super(networkConfigRedhat, self).isPreConfiged():
|
||||
return True
|
||||
|
||||
super(networkConfigRedhat, self).cfgNetwork()
|
||||
|
||||
self.netMgrRunning = self.syscfg.svo.isServiceRunning("NetworkManager")
|
||||
if self.netMgrRunning:
|
||||
self.syscfg.svo.stopService("NetworkManager")
|
||||
self.syscfg.svo.disableService("NetworkManager")
|
||||
|
||||
|
||||
if not bash("service network restart").success():
|
||||
raise CloudInternalException("Can't restart network")
|
||||
|
||||
self.syscfg.env.nics.append(self.brName)
|
||||
self.syscfg.env.nics.append(self.brName)
|
||||
self.syscfg.env.nics.append(self.brName)
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def restore(self):
|
||||
try:
|
||||
if self.netMgrRunning:
|
||||
self.syscfg.svo.enableService("NetworkManager")
|
||||
self.syscfg.svo.startService("NetworkManager")
|
||||
bash("service network restart")
|
||||
return True
|
||||
except:
|
||||
logging.debug(formatExceptionInfo())
|
||||
return False
|
||||
|
||||
class cgroupConfig(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(cgroupConfig, self).__init__(syscfg)
|
||||
self.serviceName = "Cgroup"
|
||||
|
||||
def config(self):
|
||||
try:
|
||||
cfo = configFileOps("/etc/cgconfig.conf", self)
|
||||
addConfig = "group virt {\n \
|
||||
cpu {\n \
|
||||
cpu.shares = 9216;\n \
|
||||
}\n \
|
||||
}\n"
|
||||
cfo.add_lines(addConfig)
|
||||
|
||||
self.syscfg.svo.stopService("cgconfig")
|
||||
self.syscfg.svo.enableService("cgconfig",forcestart=True)
|
||||
|
||||
cfo = configFileOps("/etc/cgrules.conf", self)
|
||||
cfgline = "root:/usr/sbin/libvirtd cpu virt/\n"
|
||||
cfo.add_lines(cfgline)
|
||||
|
||||
self.syscfg.svo.stopService("cgred")
|
||||
if not self.syscfg.svo.enableService("cgred"):
|
||||
return False
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def restore(self):
|
||||
try:
|
||||
self.syscfg.svo.stopService("cgconfig")
|
||||
self.syscfg.svo.enableService("cgconfig",forcestart=True)
|
||||
self.syscfg.svo.stopService("cgred")
|
||||
self.syscfg.svo.enableService("cgred")
|
||||
return True
|
||||
except:
|
||||
logging.debug(formatExceptionInfo())
|
||||
return False
|
||||
|
||||
class securityPolicyConfigUbuntu(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(securityPolicyConfigUbuntu, self).__init__(syscfg)
|
||||
self.serviceName = "Apparmor"
|
||||
|
||||
def config(self):
|
||||
try:
|
||||
if bash("service apparmor status").getStdout() == "":
|
||||
self.spRunning = False
|
||||
return True
|
||||
|
||||
bash("service apparmor stop")
|
||||
|
||||
bash("update-rc.d -f apparmor remove")
|
||||
return True
|
||||
except:
|
||||
raise CloudRuntimeException("Failed to configure apparmor, please see the /var/log/cloud/setupAgent.log for detail, \
|
||||
or you can manually disable it before starting myCloud")
|
||||
|
||||
def restore(self):
|
||||
try:
|
||||
self.syscfg.svo.enableService("apparmor")
|
||||
self.syscfg.svo.startService("apparmor")
|
||||
return True
|
||||
except:
|
||||
logging.debug(formatExceptionInfo())
|
||||
return False
|
||||
|
||||
class securityPolicyConfigRedhat(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(securityPolicyConfigRedhat, self).__init__(syscfg)
|
||||
self.serviceName = "SElinux"
|
||||
|
||||
def config(self):
|
||||
selinuxEnabled = True
|
||||
|
||||
if not bash("selinuxenabled").isSuccess():
|
||||
selinuxEnabled = False
|
||||
|
||||
if selinuxEnabled:
|
||||
try:
|
||||
bash("setenforce 0")
|
||||
cfo = configFileOps("/etc/selinux/config", self)
|
||||
cfo.replace_line("SELINUX=", "SELINUX=permissive")
|
||||
return True
|
||||
except:
|
||||
raise CloudRuntimeException("Failed to configure selinux, please see the /var/log/cloud/setupAgent.log for detail, \
|
||||
or you can manually disable it before starting myCloud")
|
||||
|
||||
def restore(self):
|
||||
try:
|
||||
bash("setenforce 1")
|
||||
return True
|
||||
except:
|
||||
logging.debug(formatExceptionInfo())
|
||||
return False
|
||||
|
||||
class libvirtConfigRedhat(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(libvirtConfigRedhat, self).__init__(syscfg)
|
||||
self.serviceName = "Libvirt"
|
||||
|
||||
def config(self):
|
||||
try:
|
||||
cfo = configFileOps("/etc/libvirt/libvirtd.conf", self)
|
||||
cfo.addEntry("listen_tcp", "1")
|
||||
cfo.addEntry("tcp_port", "\"16509\"")
|
||||
cfo.addEntry("auth_tcp", "\"none\"")
|
||||
cfo.addEntry("listen_tls", "0")
|
||||
cfo.save()
|
||||
|
||||
cfo = configFileOps("/etc/sysconfig/libvirtd", self)
|
||||
cfo.addEntry("export CGROUP_DAEMON", "'cpu:/virt'")
|
||||
cfo.addEntry("LIBVIRTD_ARGS", "-l")
|
||||
cfo.save()
|
||||
|
||||
cfgline = "cgroup_controllers = [ \"cpu\" ]\n" \
|
||||
"security_driver = \"none\"\n"
|
||||
filename = "/etc/libvirt/qemu.conf"
|
||||
|
||||
cfo = configFileOps(filename, self)
|
||||
cfo.add_lines(cfgline)
|
||||
|
||||
self.syscfg.svo.stopService("libvirtd")
|
||||
if not self.syscfg.svo.startService("libvirtd"):
|
||||
return False
|
||||
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def restore(self):
|
||||
pass
|
||||
|
||||
class libvirtConfigUbuntu(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(libvirtConfigUbuntu, self).__init__(syscfg)
|
||||
self.serviceName = "Libvirt"
|
||||
|
||||
def setupLiveMigration(self):
|
||||
cfo = configFileOps("/etc/libvirt/libvirtd.conf", self)
|
||||
cfo.addEntry("listen_tcp", "1")
|
||||
cfo.addEntry("tcp_port", "16509")
|
||||
cfo.addEntry("auth_tcp", "none")
|
||||
cfo.addEntry("listen_tls", "0")
|
||||
cfo.save()
|
||||
|
||||
if os.path.exists("/etc/init/libvirt-bin.conf"):
|
||||
cfo = configFileOps("/etc/init/libvirt-bin.conf", self)
|
||||
cfo.replace_line("exec /usr/sbin/libvirtd","exec /usr/sbin/libvirtd -d -l")
|
||||
else:
|
||||
cfo = configFileOps("/etc/default/libvirt-bin", self)
|
||||
cfo.replace_or_add_line("libvirtd_opts=","libvirtd_opts='-l -d'")
|
||||
|
||||
def config(self):
|
||||
try:
|
||||
cfgline = "export CGROUP_DAEMON='cpu:/virt'"
|
||||
libvirtfile = "/etc/default/libvirt-bin"
|
||||
cfo = configFileOps(libvirtfile, self)
|
||||
cfo.add_lines(cfgline)
|
||||
|
||||
self.setupLiveMigration()
|
||||
|
||||
cfgline = "cgroup_controllers = [ \"cpu\" ]\n" \
|
||||
"security_driver = \"none\"\n"
|
||||
filename = "/etc/libvirt/qemu.conf"
|
||||
|
||||
cfo = configFileOps(filename, self)
|
||||
cfo.add_lines(cfgline)
|
||||
|
||||
self.syscfg.svo.stopService("libvirt-bin")
|
||||
self.syscfg.svo.enableService("libvirt-bin")
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def restore(self):
|
||||
try:
|
||||
self.syscfg.svo.stopService("libvirt-bin")
|
||||
self.syscfg.svo.startService("libvirt-bin")
|
||||
return True
|
||||
except:
|
||||
logging.debug(formatExceptionInfo())
|
||||
return False
|
||||
|
||||
class firewallConfigUbuntu(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(firewallConfigUbuntu, self).__init__(syscfg)
|
||||
self.serviceName = "Firewall"
|
||||
|
||||
def config(self):
|
||||
try:
|
||||
ports = "22 1798 16509".split()
|
||||
for p in ports:
|
||||
bash("ufw allow %s"%p)
|
||||
bash("ufw allow proto tcp from any to any port 5900:6100")
|
||||
bash("ufw allow proto tcp from any to any port 49152:49216")
|
||||
self.syscfg.svo.stopService("ufw")
|
||||
self.syscfg.svo.startService("ufw")
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def restore(self):
|
||||
return True
|
||||
|
||||
class firewallConfigBase(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(firewallConfigBase, self).__init__(syscfg)
|
||||
self.serviceName = "Firewall"
|
||||
|
||||
def allowPort(self, port):
|
||||
status = False
|
||||
try:
|
||||
status = bash("iptables-save|grep INPUT|grep -w %s"%port).isSuccess()
|
||||
except:
|
||||
pass
|
||||
|
||||
if not status:
|
||||
bash("iptables -I INPUT -p tcp -m tcp --dport %s -j ACCEPT"%port)
|
||||
|
||||
def config(self):
|
||||
try:
|
||||
for port in self.ports:
|
||||
self.allowPort(port)
|
||||
|
||||
bash("iptables-save > /etc/sysconfig/iptables")
|
||||
self.syscfg.svo.stopService("iptables")
|
||||
self.syscfg.svo.startService("iptables")
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def restore(self):
|
||||
return True
|
||||
|
||||
class firewallConfigAgent(firewallConfigBase):
|
||||
def __init__(self, syscfg):
|
||||
super(firewallConfigAgent, self).__init__(syscfg)
|
||||
self.ports = "22 16509 5900:6100 49152:49216".split()
|
||||
|
||||
|
||||
|
||||
class cloudAgentConfig(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(cloudAgentConfig, self).__init__(syscfg)
|
||||
if syscfg.env.agentMode == "Agent":
|
||||
self.serviceName = "cloudAgent"
|
||||
elif syscfg.env.agentMode == "myCloud":
|
||||
self.serviceName = "myCloud"
|
||||
elif syscfg.env.agentMode == "Console":
|
||||
self.serviceName = "Console Proxy"
|
||||
|
||||
def configMyCloud(self):
|
||||
try:
|
||||
cfo = configFileOps("/etc/cloud/agent/agent.properties", self)
|
||||
cfo.addEntry("host", self.syscfg.env.mgtSvr)
|
||||
cfo.addEntry("zone", self.syscfg.env.zone)
|
||||
cfo.addEntry("port", "443")
|
||||
cfo.addEntry("private.network.device", self.syscfg.env.nics[0])
|
||||
cfo.addEntry("public.network.device", self.syscfg.env.nics[1])
|
||||
cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])
|
||||
cfo.addEntry("guid", str(self.syscfg.env.uuid))
|
||||
cfo.addEntry("mount.path", "/mnt")
|
||||
cfo.addEntry("resource", "com.cloud.storage.resource.LocalSecondaryStorageResource|com.cloud.agent.resource.computing.CloudZonesComputingResource")
|
||||
cfo.save()
|
||||
|
||||
self.syscfg.svo.stopService("cloud-agent")
|
||||
self.syscfg.svo.startService("cloud-agent")
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def configAgent(self):
|
||||
try:
|
||||
cfo = configFileOps("/etc/cloud/agent/agent.properties", self)
|
||||
cfo.addEntry("host", self.syscfg.env.mgtSvr)
|
||||
cfo.addEntry("zone", self.syscfg.env.zone)
|
||||
cfo.addEntry("pod", self.syscfg.env.pod)
|
||||
cfo.addEntry("cluster", self.syscfg.env.cluster)
|
||||
cfo.addEntry("port", "8250")
|
||||
cfo.addEntry("private.network.device", self.syscfg.env.nics[0])
|
||||
cfo.addEntry("public.network.device", self.syscfg.env.nics[1])
|
||||
cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])
|
||||
cfo.addEntry("guid", str(self.syscfg.env.uuid))
|
||||
cfo.addEntry("resource", "com.cloud.agent.resource.computing.LibvirtComputingResource")
|
||||
cfo.save()
|
||||
|
||||
self.syscfg.svo.stopService("cloud-agent")
|
||||
self.syscfg.svo.startService("cloud-agent")
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def configConsole(self):
|
||||
try:
|
||||
cfo = configFileOps("/etc/cloud/agent/agent.properties", self)
|
||||
cfo.addEntry("host", self.syscfg.env.mgtSvr)
|
||||
cfo.addEntry("zone", self.syscfg.env.zone)
|
||||
cfo.addEntry("pod", self.syscfg.env.pod)
|
||||
cfo.addEntry("cluster", self.syscfg.env.cluster)
|
||||
cfo.addEntry("port", "8250")
|
||||
cfo.addEntry("private.network.device", self.syscfg.env.nics[0])
|
||||
cfo.addEntry("public.network.device", self.syscfg.env.nics[1])
|
||||
cfo.addEntry("guest.network.device", self.syscfg.env.nics[2])
|
||||
cfo.addEntry("guid", str(self.syscfg.env.uuid))
|
||||
cfo.addEntry("resource", "com.cloud.agent.resource.computing.consoleProxyResource")
|
||||
cfo.save()
|
||||
|
||||
self.syscfg.svo.stopService("cloud-agent")
|
||||
self.syscfg.svo.startService("cloud-agent")
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def config(self):
|
||||
if self.syscfg.env.agentMode == "Agent":
|
||||
return self.configAgent()
|
||||
elif self.syscfg.env.agentMode == "myCloud":
|
||||
return self.configMyCloud()
|
||||
elif self.syscfg.env.agentMode == "console":
|
||||
return self.configConsole()
|
||||
|
||||
def restore(self):
|
||||
return True
|
||||
|
||||
|
||||
class sudoersConfig(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(sudoersConfig, self).__init__(syscfg)
|
||||
self.serviceName = "sudoers"
|
||||
def config(self):
|
||||
try:
|
||||
cfo = configFileOps("/etc/sudoers", self)
|
||||
cfo.addEntry("cloud ALL ", "NOPASSWD : ALL")
|
||||
cfo.rmEntry("Defaults", "requiretty", " ")
|
||||
cfo.save()
|
||||
return True
|
||||
except:
|
||||
raise
|
||||
|
||||
def restore(self):
|
||||
return True
|
||||
|
||||
class firewallConfigServer(firewallConfigBase):
|
||||
def __init__(self, syscfg):
|
||||
super(firewallConfigServer, self).__init__(syscfg)
|
||||
if self.syscfg.env.svrMode == "myCloud":
|
||||
self.ports = "443 8080 8096 8250 8443".split()
|
||||
else:
|
||||
self.ports = "8080 8096 8250".split()
|
||||
74
python/lib/cloudutils/serviceConfigServer.py
Normal file
74
python/lib/cloudutils/serviceConfigServer.py
Normal file
@ -0,0 +1,74 @@
|
||||
from db import Database
|
||||
from configFileOps import configFileOps
|
||||
from serviceConfig import serviceCfgBase
|
||||
from cloudException import CloudRuntimeException, CloudInternalException
|
||||
from utilities import bash
|
||||
import os
|
||||
|
||||
class cloudManagementConfig(serviceCfgBase):
|
||||
def __init__(self, syscfg):
|
||||
super(cloudManagementConfig, self).__init__(syscfg)
|
||||
self.serviceName = "CloudStack Management Server"
|
||||
|
||||
def config(self):
|
||||
if self.syscfg.env.svrMode == "mycloud":
|
||||
cfo = configFileOps("/usr/share/cloud/management/conf/environment.properties", self)
|
||||
cfo.addEntry("cloud-stack-components-specification", "components-cloudzones.xml")
|
||||
cfo.save()
|
||||
|
||||
cfo = configFileOps("/usr/share/cloud/management/conf/db.properties", self)
|
||||
dbHost = cfo.getEntry("db.cloud.host")
|
||||
dbPort = cfo.getEntry("db.cloud.port")
|
||||
dbUser = cfo.getEntry("db.cloud.username")
|
||||
dbPass = cfo.getEntry("db.cloud.password")
|
||||
if dbPass.strip() == "":
|
||||
dbPass = None
|
||||
dbName = cfo.getEntry("db.cloud.name")
|
||||
db = Database(dbUser, dbPass, dbHost, dbPort, dbName)
|
||||
|
||||
try:
|
||||
db.testConnection()
|
||||
except CloudRuntimeException, e:
|
||||
raise e
|
||||
except:
|
||||
raise CloudInternalException("Failed to connect to Mysql server")
|
||||
|
||||
try:
|
||||
statement = """ UPDATE configuration SET value='%s' WHERE name='%s'"""
|
||||
|
||||
db.execute(statement%('true','use.local.storage'))
|
||||
db.execute(statement%('20','max.template.iso.size'))
|
||||
|
||||
statement = """ UPDATE vm_template SET url='%s',checksum='%s' WHERE id='%s' """
|
||||
db.execute(statement%('https://rightscale-cloudstack.s3.amazonaws.com/kvm/RightImage_CentOS_5.4_x64_v5.6.28.qcow2.bz2', '90fcd2fa4d3177e31ff296cecb9933b7', '4'))
|
||||
|
||||
statement="""UPDATE disk_offering set use_local_storage=1"""
|
||||
db.execute(statement)
|
||||
except:
|
||||
raise e
|
||||
|
||||
#add DNAT 443 to 8250
|
||||
if not bash("iptables-save |grep PREROUTING | grep 8250").isSuccess():
|
||||
bash("iptables -A PREROUTING -t nat -p tcp --dport 443 -j REDIRECT --to-port 8250 ")
|
||||
|
||||
#generate keystore
|
||||
keyPath = "/var/lib/cloud/management/web.keystore"
|
||||
if not os.path.exists(keyPath):
|
||||
cmd = bash("keytool -genkey -keystore %s -storepass \"cloud.com\" -keypass \"cloud.com\" -validity 3650 -dname cn=\"Cloudstack User\",ou=\"mycloud.cloud.com\",o=\"mycloud.cloud.com\",c=\"Unknown\""%keyPath)
|
||||
|
||||
if not cmd.isSuccess():
|
||||
raise CloudInternalException(cmd.getErrMsg())
|
||||
|
||||
cfo = configFileOps("/etc/cloud/management/tomcat6.conf", self)
|
||||
cfo.add_lines("JAVA_OPTS+=\" -Djavax.net.ssl.trustStore=%s \""%keyPath)
|
||||
|
||||
try:
|
||||
self.syscfg.svo.disableService("tomcat6")
|
||||
except:
|
||||
pass
|
||||
|
||||
if self.syscfg.svo.enableService("cloud-management"):
|
||||
return True
|
||||
else:
|
||||
raise CloudRuntimeException("Failed to configure %s, please see the /var/log/cloud/setupManagement.log for detail"%self.serviceName)
|
||||
|
||||
141
python/lib/cloudutils/syscfg.py
Normal file
141
python/lib/cloudutils/syscfg.py
Normal file
@ -0,0 +1,141 @@
|
||||
from utilities import DistributionDetector, serviceOpsRedhat,serviceOpsUbuntu
|
||||
from serviceConfig import *
|
||||
class sysConfigFactory:
|
||||
@staticmethod
|
||||
def getSysConfigFactory(glbEnv):
|
||||
if glbEnv.mode == "Agent":
|
||||
return sysConfigAgentFactory.getAgent(glbEnv)
|
||||
elif glbEnv.mode == "Server":
|
||||
return sysConfigServerFactory.getServer(glbEnv)
|
||||
elif glbEnv.mode == "Db":
|
||||
return sysConfigDbFactory.getDb(glbEnv)
|
||||
else:
|
||||
raise CloudInternalException("Need to specify which mode are u running: Agent/Server/Db")
|
||||
|
||||
class sysConfigAgentFactory:
|
||||
@staticmethod
|
||||
def getAgent(glbEnv):
|
||||
distribution = DistributionDetector().getVersion()
|
||||
if distribution == "Ubuntu":
|
||||
return sysConfigAgentUbuntu(glbEnv)
|
||||
elif distribution == "Fedora":
|
||||
return sysConfigRedhat6(glbEnv)
|
||||
elif distribution == "CentOS" or distribution == "RHEL5":
|
||||
return sysConfigRedhat5(glbEnv)
|
||||
else:
|
||||
print "Can't find the distribution version"
|
||||
return sysConfig()
|
||||
|
||||
class sysConfigServerFactory:
|
||||
@staticmethod
|
||||
def getServer(glbEnv):
|
||||
distribution = DistributionDetector().getVersion()
|
||||
if distribution == "Ubuntu":
|
||||
return sysConfigServerUbuntu(glbEnv)
|
||||
elif distribution != "Unknown":
|
||||
return sysConfigServerRedhat(glbEnv)
|
||||
else:
|
||||
print "Can't find the distribution version"
|
||||
return sysConfig()
|
||||
|
||||
class sysConfigDbFactory:
|
||||
@staticmethod
|
||||
def getDb(glbEnv):
|
||||
pass
|
||||
|
||||
class sysConfig(object):
|
||||
def __init__(self, env):
|
||||
self.env = env
|
||||
self.services = []
|
||||
|
||||
def registerService(self, service):
|
||||
self.services.append(service)
|
||||
|
||||
def config(self):
|
||||
if not self.check():
|
||||
return False
|
||||
|
||||
for service in self.services:
|
||||
if not service.configration():
|
||||
raise CloudInternalException()
|
||||
|
||||
def restore(self):
|
||||
for service in self.services:
|
||||
service.backup()
|
||||
|
||||
def check(self):
|
||||
return True
|
||||
|
||||
class sysConfigAgent(sysConfig):
|
||||
def check(self):
|
||||
if self.env.debug:
|
||||
return True
|
||||
|
||||
if os.geteuid() != 0:
|
||||
raise CloudInternalException("Need to execute with root permission")
|
||||
|
||||
kvmEnabled = self.svo.isKVMEnabled()
|
||||
if not kvmEnabled:
|
||||
raise CloudInternalException("Checking KVM...[Failed]\nPlease enable KVM on this machine\n")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class sysConfigAgentRedhatBase(sysConfigAgent):
|
||||
def __init__(self, env):
|
||||
self.svo = serviceOpsRedhat()
|
||||
super(sysConfigAgentRedhatBase, self).__init__(env)
|
||||
|
||||
class sysConfigAgentUbuntu(sysConfigAgent):
|
||||
def __init__(self, glbEnv):
|
||||
super(sysConfigAgentUbuntu, self).__init__(glbEnv)
|
||||
self.svo = serviceOpsUbuntu()
|
||||
|
||||
self.services = [cgroupConfig(self),
|
||||
securityPolicyConfigUbuntu(self),
|
||||
networkConfigUbuntu(self),
|
||||
libvirtConfigUbuntu(self),
|
||||
firewallConfigUbuntu(self),
|
||||
cloudAgentConfig(self)]
|
||||
|
||||
#it covers RHEL6/Fedora13/Fedora14
|
||||
class sysConfigRedhat6(sysConfigAgentRedhatBase):
|
||||
def __init__(self, glbEnv):
|
||||
super(sysConfigRedhat6, self).__init__(glbEnv)
|
||||
self.services = [cgroupConfig(self),
|
||||
securityPolicyConfigRedhat(self),
|
||||
networkConfigRedhat(self),
|
||||
libvirtConfigRedhat(self),
|
||||
firewallConfigAgent(self),
|
||||
cloudAgentConfig(self)]
|
||||
|
||||
#It covers RHEL5/CentOS5, the mainly difference is that there is no cgroup
|
||||
class sysConfigRedhat5(sysConfigAgentRedhatBase):
|
||||
def __init__(self, glbEnv):
|
||||
super(sysConfigRedhat5, self).__init__(glbEnv)
|
||||
self.services = [
|
||||
securityPolicyConfigRedhat(self),
|
||||
networkConfigRedhat(self),
|
||||
libvirtConfigRedhat(self),
|
||||
firewallConfigAgent(self),
|
||||
cloudAgentConfig(self)]
|
||||
|
||||
class sysConfigServer(sysConfig):
|
||||
def check(self):
|
||||
if os.geteuid() != 0:
|
||||
raise CloudInternalException("Need to execute with root permission")
|
||||
return True
|
||||
|
||||
class sysConfigServerRedhat(sysConfigServer):
|
||||
def __init__(self, glbEnv):
|
||||
super(sysConfigServerRedhat, self).__init__(glbEnv)
|
||||
self.svo = serviceOpsRedhat()
|
||||
self.services = [sudoersConfig(self),
|
||||
firewallConfigServer(self)]
|
||||
|
||||
class sysConfigServerUbuntu(sysConfigServer):
|
||||
def __init__(self, glbEnv):
|
||||
super(sysConfigServerUbuntu, self).__init__(glbEnv)
|
||||
self.svo = serviceOpsUbuntu()
|
||||
self.services = [sudoersConfig(self),
|
||||
firewallConfigServer(self)]
|
||||
175
python/lib/cloudutils/utilities.py
Normal file
175
python/lib/cloudutils/utilities.py
Normal file
@ -0,0 +1,175 @@
|
||||
from cloudException import CloudRuntimeException, formatExceptionInfo
|
||||
import logging
|
||||
from subprocess import PIPE, Popen
|
||||
from signal import alarm, signal, SIGALRM, SIGKILL
|
||||
import sys
|
||||
import os
|
||||
class bash:
|
||||
def __init__(self, args, timeout=600):
|
||||
self.args = args
|
||||
logging.debug("execute:%s"%args)
|
||||
self.timeout = timeout
|
||||
self.process = None
|
||||
self.success = False
|
||||
self.run()
|
||||
|
||||
def run(self):
|
||||
class Alarm(Exception):
|
||||
pass
|
||||
def alarm_handler(signum, frame):
|
||||
raise Alarm
|
||||
|
||||
try:
|
||||
self.process = Popen(self.args, shell=True, stdout=PIPE, stderr=PIPE)
|
||||
if self.timeout != -1:
|
||||
signal(SIGALRM, alarm_handler)
|
||||
alarm(self.timeout)
|
||||
|
||||
try:
|
||||
self.stdout, self.stderr = self.process.communicate()
|
||||
if self.timeout != -1:
|
||||
alarm(0)
|
||||
except Alarm:
|
||||
os.kill(self.process.pid, SIGKILL)
|
||||
raise CloudRuntimeException("Timeout during command execution")
|
||||
|
||||
self.success = self.process.returncode == 0
|
||||
except:
|
||||
raise CloudRuntimeException(formatExceptionInfo())
|
||||
|
||||
if not self.success:
|
||||
logging.debug("Failed to execute:" + self.getErrMsg())
|
||||
|
||||
def isSuccess(self):
|
||||
return self.success
|
||||
|
||||
def getStdout(self):
|
||||
return self.stdout.strip("\n")
|
||||
|
||||
def getLines(self):
|
||||
return self.stdout.split("\n")
|
||||
|
||||
def getStderr(self):
|
||||
return self.stderr.strip("\n")
|
||||
|
||||
def getErrMsg(self):
|
||||
if self.isSuccess():
|
||||
return ""
|
||||
|
||||
if self.getStderr() is None or self.getStderr() == "":
|
||||
return self.getStdout()
|
||||
else:
|
||||
return self.getStderr()
|
||||
|
||||
def initLoging(logFile=None):
|
||||
try:
|
||||
if logFile is None:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(filename=logFile, level=logging.DEBUG)
|
||||
except:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
def writeProgressBar(msg, result):
|
||||
if msg is not None:
|
||||
output = "%-30s"%msg
|
||||
elif result is True:
|
||||
output = "[%-2s]\n"%"OK"
|
||||
elif result is False:
|
||||
output = "[%-6s]\n"%"Failed"
|
||||
sys.stdout.write(output)
|
||||
sys.stdout.flush()
|
||||
|
||||
class DistributionDetector:
|
||||
def __init__(self):
|
||||
self.distro = "Unknown"
|
||||
|
||||
if os.path.exists("/etc/fedora-release"):
|
||||
self.distro = "Fedora"
|
||||
elif os.path.exists("/etc/centos-release"):
|
||||
self.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:
|
||||
self.distro = "RHEL6"
|
||||
elif version.find("CentOS release") != -1:
|
||||
self.distro = "CentOS"
|
||||
else:
|
||||
self.distro = "RHEL5"
|
||||
elif os.path.exists("/etc/legal") and "Ubuntu" in file("/etc/legal").read(-1):
|
||||
self.distro = "Ubuntu"
|
||||
else:
|
||||
self.distro = "Unknown"
|
||||
|
||||
def getVersion(self):
|
||||
return self.distro
|
||||
|
||||
class serviceOps:
|
||||
pass
|
||||
class serviceOpsRedhat(serviceOps):
|
||||
def isServiceRunning(self, servicename):
|
||||
try:
|
||||
o = bash("service " + servicename + " status")
|
||||
if "start/running" in o.getStdout():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except:
|
||||
return False
|
||||
|
||||
def stopService(self, servicename,force=False):
|
||||
if self.isServiceRunning(servicename) or force:
|
||||
return bash("service " + servicename +" stop").isSuccess()
|
||||
|
||||
return True
|
||||
def disableService(self, servicename):
|
||||
result = self.stopService(servicename)
|
||||
bash("chkconfig --del " + servicename)
|
||||
return result
|
||||
|
||||
def startService(self, servicename,force=False):
|
||||
if not self.isServiceRunning(servicename) or force:
|
||||
return bash("service " + servicename + " start").isSuccess()
|
||||
return True
|
||||
|
||||
def enableService(self, servicename,forcestart=False):
|
||||
bash("chkconfig --level 2345 " + servicename + " on")
|
||||
return self.startService(servicename,force=forcestart)
|
||||
|
||||
def isKVMEnabled(self):
|
||||
if os.path.exists("/dev/kvm"):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
class serviceOpsUbuntu(serviceOps):
|
||||
def isServiceRunning(self, servicename):
|
||||
try:
|
||||
o = bash("service " + servicename + " status")
|
||||
if "start/running" in o.getStdout():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except:
|
||||
return False
|
||||
|
||||
def stopService(self, servicename,force=False):
|
||||
if self.isServiceRunning(servicename) or force:
|
||||
return bash("service " + servicename +" stop").isSuccess()
|
||||
|
||||
def disableService(self, servicename):
|
||||
result = self.stopService(servicename)
|
||||
bash("update-rc.d -f " + servicename + " remove")
|
||||
return result
|
||||
|
||||
def startService(self, servicename,force=False):
|
||||
if not self.isServiceRunning(servicename) or force:
|
||||
return bash("service " + servicename + " start").isSuccess()
|
||||
|
||||
def enableService(self, servicename,forcestart=False):
|
||||
bash("update-rc.d -f " + servicename + " remove")
|
||||
bash("update-rc.d -f " + servicename + " start 2 3 4 5 .")
|
||||
return self.startService(servicename,force=forcestart)
|
||||
|
||||
def isKVMEnabled(self):
|
||||
return bash("kvm-ok").isSuccess()
|
||||
@ -343,6 +343,7 @@ def build_xml_api_description ():
|
||||
)
|
||||
|
||||
bld.install_files("${PYTHONDIR}/cloudtool", 'cloud-cli/cloudtool/*')
|
||||
bld.install_files("${PYTHONDIR}/cloudutils", 'python/lib/cloudutils/*')
|
||||
bld.install_as("${PYTHONDIR}/cloudapis.py", 'cloud-cli/cloudapis/cloud.py')
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user