|
|
#-*- 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
|