You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-2.2-lib/pym/server/services.py

478 lines
20 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#-*- coding: utf-8 -*-
# Copyright 2008-2010 Calculate Ltd. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with 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.
import os
import sys
import types
import time
from cl_print import color_print
from cl_template import template
from server.utils import execProg
# Перевод модуля
import cl_lang
tr = cl_lang.lang()
tr.setLocalDomain('cl_lib')
tr.setLanguage(sys.modules[__name__])
class services(color_print):
"""Общие методы для серверных программ,
Методы для работы с сервисами"""
# Переменная объект Vars
clVars = False
# Сервисы и демоны
servicesDaemons = {"ldap":["slapd"],
"unix":["slapd"],
"samba":["samba"],
"mail":["postfix","dovecot"],
"mail_relay":["postfix"],
"jabber":["ejabberd"],
"ftp":["proftpd"],
"proxy":["squid"],
"dns":["named"],
"dhcp":["dhcpd"]}
def getServiceSetup(self):
"""находит установленные сервисы
Выдаем список [установленные сервисы]
"""
# инсталированнные сервисы
servInstalled = []
# доступные сервисы
services = ('ldap', 'unix', 'samba', 'mail',
'jabber', 'ftp', 'proxy', 'dns', 'dhcp')
for serv in services:
if self.clVars.Get("sr_%s_set"%serv) == "on":
servInstalled.append(serv)
return servInstalled
def _getDefaultRunlevelDaemons(self):
"""Получаем всех демонов в default уровне"""
execStr = "rc-update show"
textLine = execProg(execStr, None, False)
if textLine == False:
self.printERROR(_("ERROR") + ": " + execStr)
return False
else:
splLines = filter(lambda x: len(x)==2 and "default" in x[1],\
map(lambda x: x.split("|"),textLine))
splLines = map(lambda x: x[0].strip(), splLines)
return splLines
def setDaemonAutostart(self, daemon):
"""Прописывает демона в автозагрузку"""
if daemon in self._getDefaultRunlevelDaemons():
return True
execStr = "rc-update add %s default" %daemon
textLine = execProg(execStr)
if textLine == False:
self.printERROR(_("ERROR") + ": " + execStr)
self.printERROR(_("Can not add '%s' at default runlevel")%daemon)
return False
else:
return True
def delDaemonAutostart(self, daemon):
"""Удаляет демона из автозагрузки"""
if not (daemon in self._getDefaultRunlevelDaemons()):
return True
self._getDefaultRunlevelDaemons()
execStr = "rc-update del %s default" %daemon
textLine = execProg(execStr)
if textLine == False:
self.printERROR(_("ERROR") + ": " + execStr)
self.printERROR(_("Can not deleted '%s' from default runlevel")\
%daemon)
return False
else:
return True
def runLdapServer(self):
"""Запускает LDAP сервер"""
textLines = execProg("/etc/init.d/slapd start")
if textLines == False:
self.printNotOK(_("Starting LDAP")+ " ...")
return False
else:
return True
def restartLdapServer(self):
"""Запускает LDAP сервер"""
textLines = execProg("/etc/init.d/slapd restart")
if textLines == False:
self.printNotOK(_("Restarting LDAP")+ " ...")
return False
else:
return True
def stopLdapServer(self):
"""Останавливает LDAP сервер"""
textLines = execProg("/etc/init.d/slapd stop")
if textLines == False:
self.printNotOK(_("Stopping LDAP")+ " ...")
return False
else:
return True
def getALLServices(self):
"""Получаем все сервисы которые описаны в шаблонах"""
# путь к директории шаблонов
templatePath = self.clVars.Get("cl_template_path")[0]
data = os.listdir(templatePath)
service = []
for fileData in data:
if os.path.isdir(os.path.join(templatePath, fileData)):
service.append(fileData)
if service:
# После добавления сервисов в класс необходимо удалить
# apache и backup
if 'backup' in service:
service.remove('backup')
if 'apache' in service:
service.remove('apache')
return service
def getTemplatePath(self, nameService):
"""список накладываемых профилей в зависимости от сервиса"""
profpath = []
profPaths = ['/usr/lib/calculate/calculate-server/profile/%s'\
%nameService,
'/var/calculate/remote/server-profile/%s'%nameService,
'/var/calculate/server-profile/%s'%nameService]
for profPath in profPaths:
if os.path.exists(profPath):
profpath.append(profPath)
return profpath
def applyTemplatesFromService(self, service, verbose=False):
"""Применяем шаблоны для данного сервиса"""
# Пути к шаблонам для сервиса
profPaths = self.getTemplatePath(service)
# Устанавливаем пути к шаблонам для сервиса
self.clVars.Set("cl_template_path", profPaths, True)
clTempl = template(self.clVars)
# Объединяем шаблоны
data = clTempl.applyTemplates()
if clTempl.getError():
self.printERROR(clTempl.getError())
return False
else:
if verbose and type(data) == types.TupleType:
dirs, files = data
return files
return True
def delServicesAutostart(self, servInstalled):
"""Удаляет из автозагрузки сервисы
Входные данные - список названий сервисов
"""
flagError = False
delDaemons = []
for service in servInstalled:
if not service in self.servicesDaemons.keys():
self.printERROR(_("Not supported service '%s'")%service)
self.printERROR(\
_("Can not deleted service from default runlevel"))
flagError = True
break
for daemon in self.servicesDaemons[service]:
if not daemon in delDaemons:
delDaemons.append(daemon)
if not self.delDaemonAutostart(daemon):
flagError = True
break
if flagError:
break
if flagError:
return False
else:
return True
def startDaemons(self, service, daemons, printSuccess=True):
"""Стартует демонов"""
flagError = False
for daemon in daemons:
if not self.getRunDaemons([daemon]):
textLines = execProg("/etc/init.d/%s start" %(daemon))
if textLines == False:
self.printERROR( _("Daemon %s was not started") %daemon)
flagError = True
break
prnService = self.printNameService(service)
if flagError:
self.printNotOK(_("Starting") + " " + prnService + " " +\
_("service") + " ...")
return False
else:
if printSuccess:
self.printOK(_("Starting") + " " + prnService + " "+\
_("service") + " ...")
return True
def startServices(self, servInstalled, printSuccess=True):
"""Запускает все сервисы поданные на вход этому методу
Также прописывает в автозагрузку
Входные даннные - список названий сервисов
"""
addDaemons = []
if 'ldap' in servInstalled or 'unix' in servInstalled:
if not self.startDaemons('ldap',['slapd'], printSuccess):
return False
# Устанавливаем автозапуск демона
if not self.setDaemonAutostart("slapd"):
return False
addDaemons.append("slapd")
flagError = False
for service in servInstalled:
if not service in self.servicesDaemons.keys():
self.printERROR(_("Can not supported service '%s'")%service)
self.printERROR(_("Can not add service at default runlevel"))
flagError = True
break
for daemon in self.servicesDaemons[service]:
if not daemon in addDaemons:
addDaemons.append(daemon)
if not self.startDaemons(service, [daemon], printSuccess):
flagError = True
break
if not self.setDaemonAutostart(daemon):
flagError = True
break
if flagError:
break
if flagError:
return False
else:
return True
def stopServices(self, servInstalled):
"""Останавливает все сервисы поданные на вход этому методу
Входные даннные - список названий сервисов
"""
addDaemons = []
if 'ldap' in servInstalled or 'unix' in servInstalled:
addDaemons.append("slapd")
flagError = False
for service in servInstalled:
if not service in self.servicesDaemons.keys():
self.printERROR(_("Can not supported service '%s'")%service)
self.printERROR(_("Can not stop service"))
flagError = True
break
# Название сервиса для вывода на экран
servicePrn = self.printNameService(service)
for daemon in self.servicesDaemons[service]:
if not daemon in addDaemons:
addDaemons.append(daemon)
# Если демон запущен и не squid то останавливаем его
if not daemon in ["squid"] and self.getRunDaemons([daemon]):
ret = execProg("/etc/init.d/%s stop"%daemon)
if ret == False:
self.printERROR(servicePrn + " " +\
_("service is not stopped"))
flagError = True
break
# Удаляем процессы ejabberd
if daemon == "ejabberd":
strCmd = "ps ax"
listProcess = execProg(strCmd,False,False)
if listProcess == False:
self.printERROR(_('Can not execute "%s"')%strCmd)
return False
killPid = []
for process in listProcess:
if "erlang" in process:
killPid.append(process.split(" ")[0])
if killPid and " ".join(killPid).strip():
textLine=execProg("kill %s" %" ".join(killPid))
if textLine == False:
self.printERROR(_("Can not 'kill %s'")\
%" ".join(killPid))
flagError = True
break
elif daemon == "squid" and self.getRunDaemons(["squid"]):
errStopProxy = False
# Создаем 2 процесса
pid = os.fork()
tic = 0
if pid:
message = _("Waiting for squid to shutdown") + " "
self.printSUCCESS(message, 0, False)
perm = [0]
offset = 0
while not perm[0]:
perm = os.waitpid(pid, os.WNOHANG)
if perm[1]:
errStopProxy = True
break
time.sleep(0.1)
tic += 1
if tic>=15:
sys.stdout.flush()
sys.stdout.write(".")
offset += 1
tic = 0
if errStopProxy:
self.printOnlyNotOK(" ",\
self.lenString(message)+\
offset+3)
else:
self.printOnlyOK(" ",self.lenString(message)+\
offset+3)
else:
sys.stdout.flush()
if os.system("/etc/init.d/squid stop &>/dev/null"):
sys.exit(1)
else:
sys.exit(0)
# Если ошибка при остановке proxy сервера
if errStopProxy:
self.printERROR(servicePrn + " " +\
_("service is not stopped"))
flagError = True
break
if flagError:
break
if not flagError and "slapd" in addDaemons:
if self.getRunService('ldap'):
textLines = execProg("/etc/init.d/slapd stop")
if textLines == False:
self.printERROR("LDAP" + " " +\
_("service is not stopped"))
flagError = True
if flagError:
return False
else:
return True
def getRunDaemons(self, daemons, printError=False):
"""Проверка, запущены ли демоны"""
baseDir = "/var/run"
runDaemons = {}
flagBaselayoutDir = False
for daemon in daemons:
# Проверка на запуск демона postfix
if daemon == 'postfix':
flagRun = False
strCmd = "ps ax"
listProcess = execProg(strCmd, False, False)
if not listProcess:
self.printERROR(_('Can not execute "%s"')%strCmd)
return False
for process in listProcess:
if "postfix/master" in process:
flagRun = True
break
if flagRun:
runDaemons['postfix'] = True
else:
runDaemons['postfix'] = False
continue
addDirDict = {"slapd":("openldap","slapd.pid"),
"dovecot":("dovecot","master.pid"),
"proftpd":("","proftpd.pid"),
"squid":("","squid.pid")}
baselayoutDir = "/var/lib/init.d/daemons"
if not flagBaselayoutDir:
if os.path.exists(baselayoutDir):
flagBaselayoutDir = True
if flagBaselayoutDir:
addDirDict["ejabberd"] = (baselayoutDir,"ejabberd")
addDirDict["samba"] = (baselayoutDir,"samba")
addDirDict["named"] = (baselayoutDir,"named")
addDirDict["dhcpd"] = (baselayoutDir,"dhcpd")
elif daemon in ["ejabberd", "samba", "named", "dhcpd"]:
if not os.system("/lib/rc/bin/service_started %s" %daemon):
runDaemons[daemon] = True
else:
runDaemons[daemon] = False
continue
if addDirDict[daemon][0][:1] == "/":
pidDir = addDirDict[daemon][0]
else:
pidDir = os.path.join(baseDir,addDirDict[daemon][0])
if os.access(pidDir, os.F_OK) and os.listdir(pidDir) and\
os.path.exists(os.path.join(pidDir,addDirDict[daemon][1])):
runDaemons[daemon] = True
else:
runDaemons[daemon] = False
if printError:
for daemon in daemons:
if not runDaemons[daemon]:
self.printERROR(_("Daemon %s is not started") %daemon)
if False in runDaemons.values():
return False
else:
return True
def getRunService(self, nameService, printError=False):
"""Проверка, запущен ли сервис с данным именем"""
flagError = False
if not nameService in self.servicesDaemons.keys():
self.printERROR(_("Can not supported service '%s'")%nameService)
self.printERROR(_("Can not check run service"))
return False
# Названия демонов для сервиса
daemons = self.servicesDaemons[nameService]
if not self.getRunDaemons(daemons, printError):
flagError = True
if flagError:
if printError:
self.printERROR(self.printNameService(nameService) + " " +\
_("service is not started"))
return False
return True
def isServiceSetup(self, service, printError=True):
"""Проверяет установлен ли сервис"""
if not self.clVars:
# Cоздаем объект переменные
self.createClVars()
if self.clVars.Get("sr_%s_set"%service) == "on":
return True
if printError:
self.printERROR(_("Service %s is not installed")%service)
return False
def initialChecks(self, service, printError=True):
"""Начальная проверка перед запуском методов сервиса"""
# Создаем объект переменных
self.createClVars()
if self.clVars.Get("sr_mail_relay_set") == "on":
if printError:
self.printERROR(_("This server is a mail relay. \
This command is not allowed."))
return False
if not self.isServiceSetup(service, printError):
return False
return True
def initialChecksSetup(self):
# Создаем объект переменных
self.createClVars()
"""Начальная проверка перед запуском метода setup"""
if self.clVars.Get("sr_mail_relay_set") == "on":
self.printERROR(_("This server is a mail relay. \
This command is not allowed."))
return False
return True