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-3-core/pym/core/server/cl_server.py

389 lines
13 KiB

# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. 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 sys
import os
from calculate.lib.utils.tools import unpack_single_opts
from . import cert_cmd
import pwd
from .func import clearDataVars
from calculate.lib.cl_lang import setLocalTranslate
import calculate.contrib
# from spyne.protocol.http import HttpRpc
# from spyne.protocol.xml import XmlDocument
# from spyne.protocol.json import JsonDocument
from spyne.protocol.soap import Soap11
from spyne import Application
# from spyne.server.wsgi import WsgiApplication
from .spyne_adapter import CoreInnerWsdl, make_service
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
_("User must be root")
_('Failed to import %s')
_('No module named %s')
@clearDataVars
def main(*args, **keywords):
_args = list(unpack_single_opts(sys.argv[1:]))
caller = os.path.basename(sys.argv[0])
#TODO uncomment
# if not (caller == 'cl-core' or caller == 'cl-core_py3'):
if False:
parser = cert_cmd.parse(full=False)
args, unknown_args = parser.parse_known_args(_args)
args.method = '_temp_'
else:
parser = cert_cmd.parse(full=True)
args, unknown_args = parser.parse_known_args(_args)
if args.method:
parser = cert_cmd.parse(full=False)
args, unknown_args = parser.parse_known_args(_args)
if not args.method:
if unknown_args:
args = parser.parse_args(_args)
if args.help and not args.method:
parser.print_help()
return 0
from calculate.core.datavars import DataVarsCore
ob = DataVarsCore()
ob.importCore()
# set var env
if not ob.flIniFile():
sys.exit(1)
# cl_wsdl = ob.Get('cl_wsdl')
cl_wsdl = ob.Get('cl_wsdl_available')
data_path = ob.Get('cl_core_data')
local_data_path = ob.Get('cl_core_local_data')
certbase = ob.Get('cl_core_database')
serv_certbase = ob.Get('cl_core_serv_database')
rights = ob.Get('cl_core_rights')
group_rights = ob.Get('cl_core_group_rights_path')
sids = ob.Get('cl_core_sids_path')
pids = ob.Get('cl_core_pids_path')
sids_pids = ob.Get('cl_core_sids_pids')
sids_file = ob.Get('cl_core_sids_file')
pids_file = ob.Get('cl_core_pids_file')
max_sid = ob.Get('cl_core_max_sid')
max_pid = ob.Get('cl_core_max_pid')
cert_path = ob.Get('cl_core_cert_path')
cert = ob.Get('cl_core_cert')
key = ob.Get('cl_core_key')
cl_ver = ob.Get('cl_ver')
log_path_var = ob.Get('cl_log_path')
cl_core_port = ob.GetInteger('cl_core_port')
port = cl_core_port
file_logger = None
# создать симлинки на команды
if not args.method and args.create_symlink:
from .func import create_symlink, initialization
initialization(cl_wsdl)
create_symlink(local_data_path, data_path)
return 0
if args.version:
print(cl_ver)
return 0
log_filename = None
if ob.Get('cl_ebuild_phase') == '' and os.getuid() == 0:
import logging
import logging.handlers
# logging.raiseExceptions = 0
log_path = args.log_path if args.log_path else log_path_var
if not os.path.exists(log_path):
os.makedirs(log_path)
log_filename = os.path.join(log_path, 'logging_cl_core.out')
file_logger = logging.getLogger('MyLogger')
file_logger.setLevel(logging.DEBUG)
# Add the log message handler to the logger
try:
handler = logging.handlers.RotatingFileHandler(
log_filename, maxBytes=10000000, backupCount=3)
file_logger.addHandler(handler)
# debug
if args.debug:
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('spyne.server.wsgi')
logger.setLevel(logging.DEBUG)
except IOError:
pass
from urllib.error import URLError
from traceback import print_exc
ob.close()
if not args.method:
try:
port = args.port or cl_core_port
if args.check:
from . import bootstrap
bootstrap.check(cert, key)
return 0
if args.bootstrap_user_name:
from . import bootstrap
bootstrap.init(cert, key, cert_path, data_path, certbase, args,
port)
if not args.cert_user_name:
return 0
if args.clear_user_cert:
from . import bootstrap
bootstrap.clear_localuser_certificates(certbase)
if not args.cert_user_name:
return 0
if args.cert_user_name:
cert_user_name = args.cert_user_name
try:
pwd.getpwnam(cert_user_name)
except KeyError:
print(_("User %s does not exist") % cert_user_name)
return 1
from . import bootstrap
bootstrap.force_user_cert(cert, cert_path, data_path,
certbase, cert_user_name, dv=ob)
return 0
if args.revoke_cert_id:
cert_cmd.revoke_signed_cert(args.revoke_cert_id, data_path,
cert_path)
return 0
if (args.host or args.gen_root_cert or args.root_host or
args.use_root_cert):
cert_cmd.check_server_certificate(cert, key, cert_path, args,
port)
return 0
if args.id_client_req:
cert_cmd.sing_req_by_server(args.id_client_req, cert_path,
data_path)
return 0
if args.Id:
cert_cmd.view_cert(args, certbase, data_path, rights,
group_rights)
return 0
if args.cert_id:
cert_cmd.view_signed_cert(args, serv_certbase, data_path)
return 0
if args.req_id:
cert_cmd.view_client_request(args, certbase, data_path)
return 0
# Sign request by root certificate
if args.id_server_req:
cert_cmd.sing_req_by_root(args, cert_path, data_path)
return 0
if args.id_del_req or args.id_del_client_req:
cert_cmd.del_request(args.id_del_req, args.id_del_client_req,
serv_certbase, certbase, data_path)
return 0
except BaseException as e:
from urllib.error import URLError
if isinstance(e, URLError) and log_filename:
if file_logger:
fd = open(log_filename, 'a')
file_logger.debug(print_exc(file=fd))
fd.close()
print(e)
else:
raise
params_list = ["start", "create_symlink", "method",
"list_methods"]
for param in params_list:
if hasattr(args, param) and getattr(args, param):
break
else:
parser.print_help()
return 0
#####################
# importing other modules
from .func import initialization
outer_wsdl_classes = initialization(cl_wsdl)
pack = "calculate.core.server"
import importlib
func_metaclass = importlib.import_module('%s.func_metaclass' % pack)
core_wsdl_classes = []
core_wsdl_classes.append(func_metaclass.Func_MetaClass)
from calculate.core.server.baseClass import Basic
# make server metaclass
if args.method or args.list_methods:
from .local_call import local_method, LocalCall
ClService = CoreInnerWsdl("ClService",
tuple([LocalCall] + outer_wsdl_classes + [Basic] + core_wsdl_classes),
{
"__metaclass__" : CoreInnerWsdl
})
tc = ClService()
tc.set_comb_class_ref(tc)
return local_method(tc, args, unknown_args)
ClService = make_service(Basic, core_wsdl_classes, outer_wsdl_classes, "ClService")
from .server_class import ClApplication, OpenSSLAdapter
#do we even need this anymore?
tc = ClService()
App = Application([ClService], 'tns',
name="ClApplication",
in_protocol=Soap11(),
out_protocol=Soap11(),
)
# delete all sid and pid informations file
wsgi_application = ClApplication(App, log=file_logger)
cert_cmd.create_path(data_path, certbase, rights, group_rights,
local_data_path)
# set all path
tc.set_paths(data_path, certbase, serv_certbase,
rights, group_rights, sids, pids, sids_pids,
sids_file, pids_file, max_sid,
max_pid, cert_path, log_filename,
cert, key)
tc.set_comb_class_ref(tc)
tc.run_tasks()
max_num = 99999999
import calculate.contrib
# from cherrypy.wsgiserver import CherryPyWSGIServer, WSGIPathInfoDispatcher
from cheroot import wsgi
# dispatcher = WSGIPathInfoDispatcher({'': wsgi_application})
# server = CherryPyWSGIServer(('0.0.0.0', port), dispatcher,
# numthreads=10, max=max_num,
# request_queue_size=max_num)
server = wsgi.Server(('0.0.0.0', port), wsgi_application,
numthreads=10, max=max_num,
request_queue_size=max_num)
# logger = logging.getLogger("spyne.application")
# logger.setLevel(0)
print(_("listening to https://0.0.0.0:%d") % port)
print(_("wsdl is located at: https://0.0.0.0:%d/?wsdl") % port)
ca_cert = cert_path + "/ca_root.crt"
if not os.path.exists(ca_cert):
ca_cert = None
ssl_adapter = OpenSSLAdapter(cert, key, ca_cert)
ssl_adapter.certbase = certbase
server.ssl_adapter = ssl_adapter
server.certbase = certbase
server.serv_certbase = serv_certbase
server.rights = rights
server.group_rights = group_rights
server.sids = sids
server.pids = pids
server.sids_file = sids_file
server.pids_file = pids_file
server.data_path = data_path
server.cert_path = cert_path
server.ssl_certificate = cert
server.ssl_private_key = key
from OpenSSL.SSL import Error as SSLError
import socket
try:
if args.pidfile:
try:
with open(args.pidfile, "w") as f:
f.write(str(os.getpid()))
except OSError:
sys.stderr.write(_("failed to create PID file %s")
% args.pidfile + "\n")
sys.exit(1)
# For cleaning of sessions at server reboot
from .clean import clean
from .gen_pid import clear_finished_pids
from calculate.lib.utils.files import writeFile
clean(sids_file, pids_file, sids_pids, sids, pids)
clear_finished_pids(ob)
print(_("Server started"))
dbus_stop_file = ob.Get('cl_core_dbus_stop_path')
if args.inactiveclose:
try:
writeFile(dbus_stop_file).close()
except (OSError, IOError):
pass
else:
if os.path.exists(dbus_stop_file):
os.unlink(dbus_stop_file)
server.start()
except KeyboardInterrupt:
try:
ClService.killall()
except KeyboardInterrupt:
pass
print('\n' + _("Server stopped"))
server.stop()
sys.exit(0)
except socket.error as e:
if e == "No socket could be created":
print(_("No socket could be created"))
print(_('Port %d already in use') % port)
else:
if file_logger:
fd = open(log_filename, 'a')
file_logger.debug(print_exc(file=fd))
fd.close()
print(e)
except SSLError:
print('\n', _('Server certificate not found')) # , e
print(_("use cl-core with option --gen-cert-by HOST "
"(--get-cert-from HOST) or --use-root-as-server)"))
except Exception:
if file_logger:
fd = open(log_filename, 'a')
file_logger.debug(print_exc(file=fd))
fd.close()
server.stop()
if args.pidfile:
if os.path.exists(args.pidfile):
os.unlink(args.pidfile)
sys.exit(0)