diff --git a/plugins/apache/check.sh b/plugins/apache/check.sh new file mode 100755 index 000000000..e6b36e6de --- /dev/null +++ b/plugins/apache/check.sh @@ -0,0 +1,35 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# OpenResty服务名称 +service_name="openresty" + +# 检查OpenResty是否正在运行 +if systemctl is-active --quiet "$service_name"; then + # 检查是否存在僵尸进程 + zombie_processes=$(ps -ef | grep -i openresty | grep -v grep | awk '{print $2}' | xargs ps -o state= -p 2>/dev/null | grep -c Z) + if [ "$zombie_processes" -gt 0 ]; then + echo "kill nginx 僵尸进程" + ps -ef|grep nginx| grep -v grep| awk '{print $2}' | xargs kill -9 + echo "检测到OpenResty僵尸进程,正在重启服务..." + systemctl restart "$service_name" + echo "服务已重启" + else + echo "OpenResty运行正常" + fi +else + echo "kill nginx" + ps -ef|grep nginx| grep -v grep| awk '{print $2}' | xargs kill -9 + echo "OpenResty未运行,正在启动服务..." + systemctl start "$service_name" + echo "服务已启动" +fi + +NGINX_IDS=`ps -ef|grep nginx | grep -v grep| awk '{print $2}'` +if [ "$NGINX_IDS" == "" ];then + ps -ef|grep nginx| grep -v grep| awk '{print $2}' | xargs kill -9 + systemctl start "$service_name" + echo "OpenResty未运行,正在启动服务..." +fi + diff --git a/plugins/apache/conf/httpd-mpm.conf b/plugins/apache/conf/httpd-mpm.conf new file mode 100644 index 000000000..fb273eecc --- /dev/null +++ b/plugins/apache/conf/httpd-mpm.conf @@ -0,0 +1,57 @@ + + PidFile "logs/httpd.pid" + + + + StartServers 5 + MinSpareServers 5 + MaxSpareServers 10 + MaxRequestWorkers 250 + MaxConnectionsPerChild 0 + + + + StartServers 3 + MinSpareThreads 75 + MaxSpareThreads 250 + ThreadsPerChild 25 + MaxRequestWorkers 400 + MaxConnectionsPerChild 0 + + + + StartServers 3 + MinSpareThreads 75 + MaxSpareThreads 250 + ThreadsPerChild 25 + MaxRequestWorkers 400 + MaxConnectionsPerChild 0 + + + + ThreadStackSize 65536 + StartThreads 250 + MinSpareThreads 25 + MaxSpareThreads 250 + MaxThreads 1000 + MaxConnectionsPerChild 0 + + + + StartServers 2 + MinSpareThreads 5 + MaxSpareThreads 10 + MaxConnectionsPerChild 0 + + + + ThreadsPerChild 150 + MaxConnectionsPerChild 0 + + + + MaxMemFree 2048 + + + MaxMemFree 100 + diff --git a/plugins/apache/conf/httpd.conf b/plugins/apache/conf/httpd.conf new file mode 100644 index 000000000..297a8ba3a --- /dev/null +++ b/plugins/apache/conf/httpd.conf @@ -0,0 +1,105 @@ +ServerRoot "{$SERVER_PATH}/apache/httpd" +Listen 8280 + +LoadModule authn_file_module modules/mod_authn_file.so +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule authz_core_module modules/mod_authz_core.so +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule auth_basic_module modules/mod_auth_basic.so +LoadModule reqtimeout_module modules/mod_reqtimeout.so +LoadModule filter_module modules/mod_filter.so +LoadModule brotli_module modules/mod_brotli.so +LoadModule mime_module modules/mod_mime.so +LoadModule log_config_module modules/mod_log_config.so +LoadModule env_module modules/mod_env.so +LoadModule expires_module modules/mod_expires.so +LoadModule headers_module modules/mod_headers.so +LoadModule unique_id_module modules/mod_unique_id.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule version_module modules/mod_version.so +LoadModule unixd_module modules/mod_unixd.so +LoadModule status_module modules/mod_status.so +LoadModule dir_module modules/mod_dir.so +LoadModule alias_module modules/mod_alias.so +LoadModule rewrite_module modules/mod_rewrite.so + + +User daemon +Group daemon + + +ServerAdmin you@example.com +ServerName localhost:8280 + + + AllowOverride none + Require all denied + + +DocumentRoot "{$SERVER_PATH}/apache/httpd/htdocs" + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + + + DirectoryIndex index.html + + + + Require all denied + + +ErrorLog "logs/error.log" +LogLevel warn + + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + CustomLog "logs/access.log" common + + + + ScriptAlias /cgi-bin/ "{$SERVER_PATH}/apache/httpd/cgi-bin/" + + + + + + + AllowOverride None + Options None + Require all granted + + + + RequestHeader unset Proxy early + + + + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + +EnableSendfile on + +Include conf/extra/httpd-info.conf +Include conf/extra/httpd-mpm.conf + + +SSLRandomSeed startup builtin +SSLRandomSeed connect builtin + + + + diff --git a/plugins/apache/conf/httpd.conf.tpl b/plugins/apache/conf/httpd.conf.tpl new file mode 100644 index 000000000..41aff4bce --- /dev/null +++ b/plugins/apache/conf/httpd.conf.tpl @@ -0,0 +1,506 @@ +# +# This is the main Apache HTTP server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information. +# In particular, see +# +# for a discussion of each configuration directive. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so "logs/access_log" +# with ServerRoot set to "/usr/local/apache2" will be interpreted by the +# server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log" +# will be interpreted as '/logs/access_log'. + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# Do not add a slash at the end of the directory path. If you point +# ServerRoot at a non-local disk, be sure to specify a local disk on the +# Mutex directive, if file-based mutexes are used. If you wish to share the +# same ServerRoot for multiple httpd daemons, you will need to change at +# least PidFile. +# +ServerRoot "/Users/midoks/Desktop/mwdev/server/apache/httpd" + +# +# Mutex: Allows you to set the mutex mechanism and mutex file directory +# for individual mutexes, or change the global defaults +# +# Uncomment and change the directory if mutexes are file-based and the default +# mutex file directory is not on a local disk or is not appropriate for some +# other reason. +# +# Mutex default:logs + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the +# directive. +# +# Change this to Listen on specific IP addresses as shown below to +# prevent Apache from glomming onto all bound IP addresses. +# +#Listen 12.34.56.78:80 +Listen 80 + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Statically compiled modules (those listed by `httpd -l') do not need +# to be loaded here. +# +# Example: +# LoadModule foo_module modules/mod_foo.so +# +LoadModule authn_file_module modules/mod_authn_file.so +#LoadModule authn_dbm_module modules/mod_authn_dbm.so +#LoadModule authn_anon_module modules/mod_authn_anon.so +#LoadModule authn_dbd_module modules/mod_authn_dbd.so +#LoadModule authn_socache_module modules/mod_authn_socache.so +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_user_module modules/mod_authz_user.so +#LoadModule authz_dbm_module modules/mod_authz_dbm.so +#LoadModule authz_owner_module modules/mod_authz_owner.so +#LoadModule authz_dbd_module modules/mod_authz_dbd.so +LoadModule authz_core_module modules/mod_authz_core.so +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule auth_basic_module modules/mod_auth_basic.so +#LoadModule auth_form_module modules/mod_auth_form.so +#LoadModule auth_digest_module modules/mod_auth_digest.so +#LoadModule allowmethods_module modules/mod_allowmethods.so +#LoadModule file_cache_module modules/mod_file_cache.so +#LoadModule cache_module modules/mod_cache.so +#LoadModule cache_disk_module modules/mod_cache_disk.so +#LoadModule cache_socache_module modules/mod_cache_socache.so +#LoadModule socache_shmcb_module modules/mod_socache_shmcb.so +#LoadModule socache_dbm_module modules/mod_socache_dbm.so +#LoadModule socache_memcache_module modules/mod_socache_memcache.so +#LoadModule socache_redis_module modules/mod_socache_redis.so +#LoadModule watchdog_module modules/mod_watchdog.so +#LoadModule macro_module modules/mod_macro.so +#LoadModule dbd_module modules/mod_dbd.so +#LoadModule dumpio_module modules/mod_dumpio.so +#LoadModule buffer_module modules/mod_buffer.so +#LoadModule ratelimit_module modules/mod_ratelimit.so +LoadModule reqtimeout_module modules/mod_reqtimeout.so +#LoadModule ext_filter_module modules/mod_ext_filter.so +#LoadModule request_module modules/mod_request.so +#LoadModule include_module modules/mod_include.so +LoadModule filter_module modules/mod_filter.so +#LoadModule substitute_module modules/mod_substitute.so +#LoadModule sed_module modules/mod_sed.so +#LoadModule brotli_module modules/mod_brotli.so +LoadModule mime_module modules/mod_mime.so +LoadModule log_config_module modules/mod_log_config.so +#LoadModule log_debug_module modules/mod_log_debug.so +#LoadModule logio_module modules/mod_logio.so +LoadModule env_module modules/mod_env.so +#LoadModule expires_module modules/mod_expires.so +LoadModule headers_module modules/mod_headers.so +#LoadModule unique_id_module modules/mod_unique_id.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule version_module modules/mod_version.so +#LoadModule remoteip_module modules/mod_remoteip.so +#LoadModule proxy_module modules/mod_proxy.so +#LoadModule proxy_connect_module modules/mod_proxy_connect.so +#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so +#LoadModule proxy_http_module modules/mod_proxy_http.so +#LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so +#LoadModule proxy_scgi_module modules/mod_proxy_scgi.so +#LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so +#LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so +#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so +#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so +#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so +#LoadModule proxy_express_module modules/mod_proxy_express.so +#LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so +#LoadModule session_module modules/mod_session.so +#LoadModule session_cookie_module modules/mod_session_cookie.so +#LoadModule session_dbd_module modules/mod_session_dbd.so +#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so +#LoadModule ssl_module modules/mod_ssl.so +#LoadModule http2_module modules/mod_http2.so +#LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so +#LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so +#LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so +#LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so +LoadModule unixd_module modules/mod_unixd.so +#LoadModule dav_module modules/mod_dav.so +LoadModule status_module modules/mod_status.so +LoadModule autoindex_module modules/mod_autoindex.so +#LoadModule info_module modules/mod_info.so +#LoadModule cgid_module modules/mod_cgid.so +#LoadModule dav_fs_module modules/mod_dav_fs.so +#LoadModule vhost_alias_module modules/mod_vhost_alias.so +#LoadModule negotiation_module modules/mod_negotiation.so +LoadModule dir_module modules/mod_dir.so +#LoadModule actions_module modules/mod_actions.so +#LoadModule speling_module modules/mod_speling.so +#LoadModule userdir_module modules/mod_userdir.so +LoadModule alias_module modules/mod_alias.so +#LoadModule rewrite_module modules/mod_rewrite.so + + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# It is usually good practice to create a dedicated user and group for +# running httpd, as with most system services. +# +User daemon +Group daemon + + + +# 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +# +ServerAdmin you@example.com + +# +# ServerName gives the name and port that the server uses to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# +# If your host doesn't have a registered DNS name, enter its IP address here. +# +#ServerName www.example.com:80 + +# +# Deny access to the entirety of your server's filesystem. You must +# explicitly permit access to web content directories in other +# blocks below. +# + + AllowOverride none + Require all denied + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "/Users/midoks/Desktop/mwdev/server/apache/httpd/htdocs" + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs/2.4/mod/core.html#options + # for more information. + # + Options Indexes FollowSymLinks + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # AllowOverride FileInfo AuthConfig Limit + # + AllowOverride None + + # + # Controls who can get stuff from this server. + # + Require all granted + + +# +# DirectoryIndex: sets the file that Apache will serve if a directory +# is requested. +# + + DirectoryIndex index.html + + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog "logs/error_log" + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + CustomLog "logs/access_log" common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + #CustomLog "logs/access_log" combined + + + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "/Users/midoks/Desktop/mwdev/server/apache/httpd/cgi-bin/" + + + + + # + # ScriptSock: On threaded servers, designate the path to the UNIX + # socket used to communicate with the CGI daemon of mod_cgid. + # + #Scriptsock cgisock + + +# +# "/Users/midoks/Desktop/mwdev/server/apache/httpd/cgi-bin" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Require all granted + + + + # + # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied + # backend servers which have lingering "httpoxy" defects. + # 'Proxy' request header is undefined by the IETF, not listed by IANA + # + RequestHeader unset Proxy early + + + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig conf/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + #AddType text/html .shtml + #AddOutputFilter INCLUDES .shtml + + +# +# The mod_mime_magic module allows the server to use various hints from the +# contents of the file itself to determine its type. The MIMEMagicFile +# directive tells the module where the hint definitions are located. +# +#MIMEMagicFile conf/magic + +# +# Customizable error responses come in three flavors: +# 1) plain text 2) local redirects 3) external redirects +# +# Some examples: +#ErrorDocument 500 "The server made a boo boo." +#ErrorDocument 404 /missing.html +#ErrorDocument 404 "/cgi-bin/missing_handler.pl" +#ErrorDocument 402 http://www.example.com/subscription_info.html +# + +# +# MaxRanges: Maximum number of Ranges in a request before +# returning the entire resource, or one of the special +# values 'default', 'none' or 'unlimited'. +# Default setting is to accept 200 Ranges. +#MaxRanges unlimited + +# +# EnableMMAP and EnableSendfile: On systems that support it, +# memory-mapping or the sendfile syscall may be used to deliver +# files. This usually improves server performance, but must +# be turned off when serving from networked-mounted +# filesystems or if support for these functions is otherwise +# broken on your system. +# Defaults: EnableMMAP On, EnableSendfile Off +# +#EnableMMAP off +#EnableSendfile on + +# Supplemental configuration +# +# The configuration files in the conf/extra/ directory can be +# included to add extra features or to modify the default configuration of +# the server, or you may simply copy their contents here and change as +# necessary. + +# Server-pool management (MPM specific) +#Include conf/extra/httpd-mpm.conf + +# Multi-language error messages +#Include conf/extra/httpd-multilang-errordoc.conf + +# Fancy directory listings +#Include conf/extra/httpd-autoindex.conf + +# Language settings +#Include conf/extra/httpd-languages.conf + +# User home directories +#Include conf/extra/httpd-userdir.conf + +# Real-time info on requests and configuration +#Include conf/extra/httpd-info.conf + +# Virtual hosts +#Include conf/extra/httpd-vhosts.conf + +# Local access to the Apache HTTP Server Manual +#Include conf/extra/httpd-manual.conf + +# Distributed authoring and versioning (WebDAV) +#Include conf/extra/httpd-dav.conf + +# Various default settings +#Include conf/extra/httpd-default.conf + +# Configure mod_proxy_html to understand HTML4/XHTML1 + +Include conf/extra/proxy-html.conf + + +# Secure (SSL/TLS) connections +#Include conf/extra/httpd-ssl.conf +# +# Note: The following must must be present to support +# starting without SSL on platforms with no /dev/random equivalent +# but a statically compiled-in mod_ssl. +# + +SSLRandomSeed startup builtin +SSLRandomSeed connect builtin + + diff --git a/plugins/apache/ico.png b/plugins/apache/ico.png new file mode 100644 index 000000000..a679b1026 Binary files /dev/null and b/plugins/apache/ico.png differ diff --git a/plugins/apache/index.html b/plugins/apache/index.html new file mode 100755 index 000000000..2b70e55a7 --- /dev/null +++ b/plugins/apache/index.html @@ -0,0 +1,25 @@ +
+ +
+
+

服务

+

自启动

+

配置修改

+

负载状态

+

MPM性能调整

+

错误日志

+

维护功能

+
+
+
+
+
+ +
+ + \ No newline at end of file diff --git a/plugins/apache/index.py b/plugins/apache/index.py new file mode 100755 index 000000000..ba2727472 --- /dev/null +++ b/plugins/apache/index.py @@ -0,0 +1,593 @@ +# coding:utf-8 + +import sys +import io +import os +import time +import threading +import subprocess +import re + + +web_dir = os.getcwd() + "/web" +if os.path.exists(web_dir): + sys.path.append(web_dir) + os.chdir(web_dir) + +import core.mw as mw + +app_debug = False +if mw.isAppleSystem(): + app_debug = True + + +def getPluginName(): + return 'apache' + + +def getPluginDir(): + return mw.getPluginDir() + '/' + getPluginName() + + +def getServerDir(): + return mw.getServerDir() + '/' + getPluginName() + + +def getInitDFile(): + current_os = mw.getOs() + if current_os == 'darwin': + return '/tmp/' + getPluginName() + + if current_os.startswith('freebsd'): + return '/etc/rc.d/' + getPluginName() + + return '/etc/init.d/' + getPluginName() + + +def getArgs(): + args = sys.argv[2:] + # print(args) + tmp = {} + args_len = len(args) + + if args_len == 1: + t = args[0].strip('{').strip('}') + t = t.split(':',2) + tmp[t[0]] = t[1] + elif args_len > 1: + for i in range(len(args)): + t = args[i].split(':',2) + tmp[t[0]] = t[1] + # print(tmp) + return tmp + + +def checkArgs(data, ck=[]): + for i in range(len(ck)): + if not ck[i] in data: + return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!')) + return (True, mw.returnJson(True, 'ok')) + + +def clearTemp(): + path_bin = getServerDir() + "/httpd" + + +def getConf(): + path = getServerDir() + "/httpd/conf/httpd.conf" + return path + + +def getConfMpm(): + path = getServerDir() + "/httpd/conf/extra/httpd-mpm.conf" + return path + + +def getConfTpl(): + path = getPluginDir() + '/conf/httpd.conf' + return path + + +def getOs(): + data = {} + data['os'] = mw.getOs() + data['auth'] = True + return mw.getJson(data) + + +def getInitDTpl(): + path = getPluginDir() + "/init.d/httpd.tpl" + return path + + +def getPidFile(): + file = getConf() + content = mw.readFile(file) + rep = r'pid\s*(.*);' + tmp = re.search(rep, content) + return tmp.groups()[0].strip() + + +def getFileOwner(filename): + import pwd + stat = os.lstat(filename) + uid = stat.st_uid + pw = pwd.getpwuid(uid) + return pw.pw_name + + +def checkAuthEq(file, owner='root'): + fowner = getFileOwner(file) + if (fowner == owner): + return True + return False + + +def confReplace(): + service_path = mw.getServerDir() + content = mw.readFile(getConfTpl()) + content = content.replace('{$SERVER_PATH}', service_path) + + # 主配置文件 + nconf = getServerDir() + '/httpd/conf/httpd.conf' + mw.writeFile(nconf, content) + + +def initDreplace(): + + file_tpl = getInitDTpl() + service_path = mw.getServerDir() + + initD_path = getServerDir() + '/init.d' + + # OpenResty is not installed + if not os.path.exists(getServerDir()): + print("ok") + exit(0) + + # init.d + file_bin = initD_path + '/' + getPluginName() + if not os.path.exists(initD_path): + os.mkdir(initD_path) + + # initd replace + content = mw.readFile(file_tpl) + content = content.replace('{$SERVER_PATH}', service_path) + mw.writeFile(file_bin, content) + mw.execShell('chmod +x ' + file_bin) + + # config replace + confReplace() + + # systemd + # /usr/lib/systemd/system + systemDir = mw.systemdCfgDir() + systemService = systemDir + '/httpd.service' + if os.path.exists(systemDir) and not os.path.exists(systemService): + systemServiceTpl = getPluginDir() + '/init.d/httpd.service.tpl' + se_content = mw.readFile(systemServiceTpl) + se_content = se_content.replace('{$SERVER_PATH}', service_path) + mw.writeFile(systemService, se_content) + mw.execShell('systemctl daemon-reload') + + return file_bin + + +def status(): + cmd = "ps -ef|grep 'httpd/bin/httpd' |grep -v grep | grep -v python | awk '{print $2}'" + data = mw.execShell(cmd) + if data[0] == '': + return 'stop' + return 'start' + + +def restyOp(method): + file = initDreplace() + + # 启动时,先检查一下配置文件 + check = getServerDir() + "/httpd/bin/httpd -t" + check_data = mw.execShell(check) + if not check_data[1].find('Syntax OK') > -1: + return check_data[1] + + current_os = mw.getOs() + if current_os == "darwin": + data = mw.execShell(file + ' ' + method) + if data[1] == '': + return 'ok' + return data[1] + + if current_os.startswith("freebsd"): + mw.execShell('service httpd '+method) + if data[1] == '': + return 'ok' + return data[1] + + data = mw.execShell('systemctl ' + method + ' httpd') + if data[1] == '': + return 'ok' + return data[1] + + +def op_submit_systemctl_restart(): + current_os = mw.getOs() + if current_os.startswith("freebsd"): + mw.execShell('service httpd restart') + return True + + mw.execShell('systemctl restart httpd') + return True + + +def op_submit_init_restart(file): + mw.execShell(file + ' restart') + + +def restyOp_restart(): + file = initDreplace() + + # 启动时,先检查一下配置文件 + check = getServerDir() + "/httpd/bin/httpd -t" + check_data = mw.execShell(check) + if not check_data[1].find('Syntax OK') > -1: + return 'ERROR: 配置出错
' + check_data[1].replace("\n", '
') + '
' + + if not mw.isAppleSystem(): + threading.Timer(2, op_submit_systemctl_restart).start() + return 'ok' + + threading.Timer(2, op_submit_init_restart, args=(file,)).start() + return 'ok' + + +def start(): + return restyOp('start') + + +def stop(): + r = restyOp('stop') + + mw.execShell("ps -ef|grep httpd | grep -v grep | awk '{print $2}'|xargs -r kill") + return r + + +def restart(): + return restyOp_restart() + + +def reload(): + confReplace() + return restyOp('reload') + + +def initdStatus(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + if current_os.startswith('freebsd'): + initd_bin = getInitDFile() + if os.path.exists(initd_bin): + return 'ok' + + shell_cmd = 'systemctl status httpd | grep loaded | grep "enabled;"' + data = mw.execShell(shell_cmd) + if data[0] == '': + return 'fail' + return 'ok' + + +def initdInstall(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + # freebsd initd install + if current_os.startswith('freebsd'): + import shutil + source_bin = initDreplace() + initd_bin = getInitDFile() + shutil.copyfile(source_bin, initd_bin) + mw.execShell('chmod +x ' + initd_bin) + mw.execShell('sysrc httpd_enable="YES"') + return 'ok' + + mw.execShell('systemctl enable httpd') + return 'ok' + + +def initdUinstall(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + if current_os.startswith('freebsd'): + initd_bin = getInitDFile() + os.remove(initd_bin) + mw.execShell('sysrc httpd_enable="NO"') + return 'ok' + + mw.execShell('systemctl disable httpd') + return 'ok' + +def getHttpdStatusPort(): + conf = mw.getServerDir() + '/apache/httpd/conf/httpd.conf' + content = mw.readFile(conf) + if not content: + return None + rep = r'^\s*Listen\s*(?:\d+\.\d+\.\d+\.\d+:)?(\d+)' # 匹配非注释行的 Listen 指令,忽略大小写 + tmp = re.search(rep, content, re.IGNORECASE | re.MULTILINE) + if tmp: + port = tmp.groups()[0].strip() + return port + return None + + +def runInfoDone(data): + result = {} + if not data: + return result + + # 解析服务器状态数据 + lines = data.strip().split('\n') + for line in lines: + if ':' in line: + key, value = line.split(':', 1) + key = key.strip() + value = value.strip() + result[key] = value + + return result + + +def runInfo(): + op_status = status() + if op_status == 'stop': + return mw.returnJson(False, "未启动!") + + port = getHttpdStatusPort() + if not port: + return mw.returnJson(False, "无法获取端口信息!") + + # 取Openresty负载状态 + try: + url = 'http://127.0.0.1:%s/server-status?auto' % port + result = mw.httpGet(url, timeout=3) + data = runInfoDone(result) + return mw.getJson(data) + except Exception as e: + try: + url = 'http://' + mw.getHostAddr() + ':%s/server-status?auto' % port + result = mw.httpGet(url) + data = runInfoDone(result) + return mw.getJson(data) + except Exception as e: + return mw.returnJson(False, "apache异常!") + + except Exception as e: + return mw.returnJson(False, "apache not started!") + + +def errorLogPath(): + return getServerDir() + '/httpd/logs/error.log' + + +def getCfg(): + cfg = getConfMpm() + content = mw.readFile(cfg) + + unitrep = "[kmgKMG]" + + # 获取当前 MPM 模块 + mpm_module = "" + mpm_match = re.search(r"mpm_(\w+)_module", content) + if mpm_match: + mpm_module = mpm_match.group(1) + + # MPM 配置参数 + mpm_cfg_args = { + "prefork": [ + {"name": "StartServers", "ps": "服务器进程启动数量", 'type': 2}, + {"name": "MinSpareServers", "ps": "保持空闲的最小服务器进程数", 'type': 2}, + {"name": "MaxSpareServers", "ps": "保持空闲的最大服务器进程数", 'type': 2}, + {"name": "MaxRequestWorkers", "ps": "允许启动的最大服务器进程数", 'type': 2}, + {"name": "MaxConnectionsPerChild", "ps": "服务器进程服务的最大连接数", 'type': 2}, + ], + "worker": [ + {"name": "StartServers", "ps": "初始服务器进程数", 'type': 2}, + {"name": "MinSpareThreads", "ps": "保持空闲的最小工作线程数", 'type': 2}, + {"name": "MaxSpareThreads", "ps": "保持空闲的最大工作线程数", 'type': 2}, + {"name": "ThreadsPerChild", "ps": "每个服务器进程的工作线程数", 'type': 2}, + {"name": "MaxRequestWorkers", "ps": "最大工作线程数", 'type': 2}, + {"name": "MaxConnectionsPerChild", "ps": "服务器进程服务的最大连接数", 'type': 2}, + ], + "event": [ + {"name": "StartServers", "ps": "初始服务器进程数", 'type': 2}, + {"name": "MinSpareThreads", "ps": "保持空闲的最小工作线程数", 'type': 2}, + {"name": "MaxSpareThreads", "ps": "保持空闲的最大工作线程数", 'type': 2}, + {"name": "ThreadsPerChild", "ps": "每个服务器进程的工作线程数", 'type': 2}, + {"name": "MaxRequestWorkers", "ps": "最大工作线程数", 'type': 2}, + {"name": "MaxConnectionsPerChild", "ps": "服务器进程服务的最大连接数", 'type': 2}, + ], + "netware": [ + {"name": "ThreadStackSize", "ps": "每个工作线程分配的堆栈大小", 'type': 2}, + {"name": "StartThreads", "ps": "服务器启动时启动的工作线程数", 'type': 2}, + {"name": "MinSpareThreads", "ps": "保持空闲的最小线程数", 'type': 2}, + {"name": "MaxSpareThreads", "ps": "保持空闲的最大线程数", 'type': 2}, + {"name": "MaxThreads", "ps": "同时活跃的最大工作线程数", 'type': 2}, + {"name": "MaxConnectionsPerChild", "ps": "线程服务的最大连接数", 'type': 2}, + ], + "mpmt_os2": [ + {"name": "StartServers", "ps": "维护的服务器进程数", 'type': 2}, + {"name": "MinSpareThreads", "ps": "每个进程的最小空闲线程数", 'type': 2}, + {"name": "MaxSpareThreads", "ps": "每个进程的最大空闲线程数", 'type': 2}, + {"name": "MaxConnectionsPerChild", "ps": "每个服务器进程的最大连接数", 'type': 2}, + ], + "winnt": [ + {"name": "ThreadsPerChild", "ps": "服务器进程中的工作线程数", 'type': 2}, + {"name": "MaxConnectionsPerChild", "ps": "服务器进程服务的最大连接数", 'type': 2}, + ] + } + + # 通用配置参数 + common_cfg_args = [ + {"name": "MaxMemFree", "ps": "每个分配器允许持有的最大空闲KB数", 'type': 2}, + ] + + # 合并配置参数 + cfg_args = [] + if mpm_module in mpm_cfg_args: + cfg_args.extend(mpm_cfg_args[mpm_module]) + cfg_args.extend(common_cfg_args) + + rdata = [] + for i in cfg_args: + # 匹配 MPM 特定配置 + rep = r".*?(%s)\s+(\w+).*?" % (mpm_module, i["name"]) + k = re.search(rep, content, re.DOTALL) + + # 如果没有找到 MPM 特定配置,尝试匹配通用配置 + if not k: + rep = r"(%s)\s+(\w+)" % i["name"] + k = re.search(rep, content) + + if not k: + continue + + key = k.group(1) + v = k.group(2) if len(k.groups()) > 1 else "" + + if re.search(unitrep, v): + u = str.upper(v[-1]) + v = v[:-1] + if len(u) == 1: + psstr = u + "B," + i["ps"] + else: + psstr = u + "," + i["ps"] + else: + u = "" + + kv = {"name": key, "value": v, "unit": u, + "ps": i["ps"], "type": i["type"]} + rdata.append(kv) + return mw.returnJson(True, "ok", rdata) + +def replaceChar(value, index, new_char): + return value[:index] + new_char + value[index+1:] + +def setCfg(): + args = getArgs() + + # 检查参数,允许动态参数 + cfg = getConfMpm() + mw.backFile(cfg) + content = mw.readFile(cfg) + + # 获取当前 MPM 模块 + mpm_module = "" + mpm_match = re.search(r"mpm_(\w+)_module", content) + if mpm_match: + mpm_module = mpm_match.group(1) + + # 验证参数值 + for k, v in args.items(): + # 检查是否为数字参数 + if not re.search(r"\d+", v): + return mw.returnJson(False, '参数值错误,请输入数字整数') + + # 替换 MPM 特定配置 + if mpm_module: + def replace_mpm_config(match): + return match.group(1) + k + match.group(2) + v + match.group(3) + rep = r"(.*?)%s(\s+)\d+(.*?)" % (mpm_module, k) + if re.search(rep, content, re.DOTALL): + content = re.sub(rep, replace_mpm_config, content, flags=re.DOTALL) + + # 替换通用配置 + def replace_common_config(match): + return k + match.group(1) + v + rep = r"%s(\s+)\d+" % k + if re.search(rep, content): + content = re.sub(rep, replace_common_config, content) + + mw.writeFile(cfg, content) + isError = mw.checkHttpdConfig() + if (isError != True): + mw.restoreFile(cfg) + return mw.returnJson(False, 'ERROR: 配置出错
' + isError.replace("\n", '
') + '
') + + mw.restartWeb() + return mw.returnJson(True, '设置成功') + + +def cronAddCheck(): + try: + import tool_task + tool_task.createBgTask() + return mw.returnJson(True, '添加检查任务成功') + except Exception as e: + return mw.returnJson(False, '添加检查任务失败:'+str(e)) + +def cronDelCheck(): + try: + import tool_task + tool_task.removeBgTask() + return mw.returnJson(True, '删除检查任务成功') + except Exception as e: + return mw.returnJson(False, '删除检查任务失败:'+str(e)) + +def cronCheck(): + return 'ok' + + +def installPreInspection(): + return 'ok' + + +if __name__ == "__main__": + + version = '2.4' + version_pl = getServerDir() + "/version.pl" + if os.path.exists(version_pl): + version = mw.readFile(version_pl) + + + func = sys.argv[1] + if func == 'status': + print(status()) + elif func == 'start': + print(start()) + elif func == 'stop': + print(stop()) + elif func == 'restart': + print(restart()) + elif func == 'reload': + print(reload()) + elif func == 'initd_status': + print(initdStatus()) + elif func == 'initd_install': + print(initdInstall()) + elif func == 'initd_uninstall': + print(initdUinstall()) + elif func == 'install_pre_inspection': + print(installPreInspection()) + elif func == 'conf': + print(getConf()) + elif func == 'get_os': + print(getOs()) + elif func == 'run_info': + print(runInfo()) + elif func == 'error_log': + print(errorLogPath()) + elif func == 'get_cfg': + print(getCfg()) + elif func == 'set_cfg': + print(setCfg()) + elif func == 'check': + print(cronCheck()) + elif func == 'cron_add_check': + print(cronAddCheck()) + elif func == 'cron_del_check': + print(cronDelCheck()) + else: + print('error') diff --git a/plugins/apache/info.json b/plugins/apache/info.json new file mode 100755 index 000000000..37fb515fe --- /dev/null +++ b/plugins/apache/info.json @@ -0,0 +1,18 @@ +{ + "sort": 0, + "title":"apache", + "tip":"soft", + "name":"apache", + "type":"其他插件", + "ps":"世界排名第一,快速、可靠并且可通过简单的API扩充", + "shell":"install.sh", + "install_pre_inspection":true, + "checks":"server/apache", + "path":"server/apache", + "author":"apache", + "home":"https://downloads.apache.org/httpd/", + "date":"2026-04-11", + "pid": "1", + "versions": ["2.4"], + "updates": ["2.4:66"] +} \ No newline at end of file diff --git a/plugins/apache/init.d/httpd.service.tpl b/plugins/apache/init.d/httpd.service.tpl new file mode 100644 index 000000000..8585790b4 --- /dev/null +++ b/plugins/apache/init.d/httpd.service.tpl @@ -0,0 +1,16 @@ +[Unit] +Description=Apache Web Server +After=network.target + +[Service] +Type=simple +Environment=LANG=C +ExecStart={$SERVER_PATH}/apache/httpd/bin/httpd $OPTIONS -DFOREGROUND +ExecReload={$SERVER_PATH}/apache/httpd/bin/httpd $OPTIONS -k graceful +KillSignal=SIGWINCH + +KillMode=mixed +PrivateTmp=true + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/plugins/apache/init.d/httpd.service2.tpl b/plugins/apache/init.d/httpd.service2.tpl new file mode 100644 index 000000000..97f3a73fb --- /dev/null +++ b/plugins/apache/init.d/httpd.service2.tpl @@ -0,0 +1,17 @@ +[Unit] +Description=Apache Web Server +After=network.target + +[Service] +Type=forking +PIDFile={$SERVER_PATH}/apache/httpd/logs/httpd.pid +ExecStart={$SERVER_PATH}/apache/httpd/bin/apachectl start +ExecReload={$SERVER_PATH}/apache/httpd/bin/apachectl graceful +ExecStop={$SERVER_PATH}/apache/httpd/bin/apachectl stop +PrivateTmp=true +User=www +Group=www +Restart=on-failure + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/plugins/apache/init.d/httpd.tpl b/plugins/apache/init.d/httpd.tpl new file mode 100644 index 000000000..232843809 --- /dev/null +++ b/plugins/apache/init.d/httpd.tpl @@ -0,0 +1,47 @@ +#!/bin/bash +# chkconfig: 345 85 15 +# description: Apache Server + +### BEGIN INIT INFO +# Provides: apache +# Required-Start: $network +# Required-Stop: $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Description: Apache Server +### END INIT INFO + + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/homebrew/bin +# Apache 可执行文件的路径 +DAEMON={$SERVER_PATH}/apache/httpd/bin/httpd +# 进程的 PID 文件路径 +PIDFILE={$SERVER_PATH}/apache/httpd/logs/httpd.pid + +# 根据传入的参数执行不同操作 +case "$1" in + start) + echo "Starting Apache..." + $DAEMON -k start + ;; + stop) + echo "Stopping Apache..." + $DAEMON -k stop + ;; + restart) + echo "Restarting Apache..." + $DAEMON -k restart + ;; + status) + if [ -f $PIDFILE ]; then + echo "Apache is running." + else + echo "Apache is not running." + fi + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 +esac + +exit 0 \ No newline at end of file diff --git a/plugins/apache/install.sh b/plugins/apache/install.sh new file mode 100755 index 000000000..dd350bc5c --- /dev/null +++ b/plugins/apache/install.sh @@ -0,0 +1,87 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/apache && bash install.sh install 2.4 +# cd /www/server/mdserver-web/plugins/apache && bash install.sh install 2.4 +# cd /www/server/mdserver-web/plugins/apache && bash install.sh upgrade 2.4 + +# curl -I -H "Accept-Encoding: br" http://localhost +# curl -I -H "Accept-Encoding: zstd" http://localhost +# curl --http3 -v https://www.xxx.com + +# apt install ncat -y +# nc -u -v www.xx.com 443 + +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/apache && python3 plugins/apache/index.py start +# cd /www/server/mdserver-web && python3 plugins/apache/index.py start +# cd /www/server/mdserver-web && python3 plugins/apache/index.py run_info +# ps -ef|grep httpd | grep -v grep | awk '{print $2}'|xargs kill + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") + +sysName=`uname` +action=$1 +type=$2 + +VERSION=$2 +openrestyDir=${serverPath}/source/apache + +if id www &> /dev/null ;then + echo "www uid is `id -u www`" + echo "www shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `" +else + groupadd www + useradd -g www -s /bin/bash www +fi + +if [ "${action}" == "upgrade" ];then + sh -x $curPath/versions/$2/install.sh $1 + + echo "${VERSION}" > $serverPath/apache/version.pl + + mkdir -p $serverPath/web_conf/php/conf + echo 'set $PHP_ENV 0;' > $serverPath/web_conf/php/conf/enable-php-00.conf + + #初始化 + cd ${rootPath} && python3 ${rootPath}/plugins/apache/index.py start + cd ${rootPath} && python3 ${rootPath}/plugins/apache/index.py initd_install + exit 0 +fi + + +if [ "${2}" == "" ];then + echo '缺少安装脚本版本...' + exit 0 +fi + +if [ "${action}" == "uninstall" ];then + if [ -f /usr/lib/systemd/system/httpd.service ] || [ -f /lib/systemd/system/httpd.service ];then + systemctl stop httpd + rm -rf /usr/systemd/system/httpd.service + rm -rf /lib/systemd/system/httpd.service + systemctl daemon-reload + fi + + if [ -f $serverPath/apache/init.d/httpd ];then + $serverPath/apache/init.d/httpd stop + fi + + rm -rf $serverPath/apache +fi + +sh -x $curPath/versions/$2/install.sh $1 + +if [ "${action}" == "install" ] && [ -d $serverPath/apache ];then + echo "${VERSION}" > $serverPath/apache/version.pl + + mkdir -p $serverPath/web_conf/php/conf + echo 'set $PHP_ENV 0;' > $serverPath/web_conf/php/conf/enable-php-00.conf + + #初始化 + cd ${rootPath} && python3 ${rootPath}/plugins/apache/index.py start + cd ${rootPath} && python3 ${rootPath}/plugins/apache/index.py initd_install +fi diff --git a/plugins/apache/js/httpd.js b/plugins/apache/js/httpd.js new file mode 100755 index 000000000..af987f244 --- /dev/null +++ b/plugins/apache/js/httpd.js @@ -0,0 +1,278 @@ +function httpPost(method, args, callback){ + var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 }); + $.post('/plugins/run', {name:'apache', func:method, args:JSON.stringify(args)}, function(data) { + layer.close(loadT); + if (!data.status){ + layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']}); + return; + } + + if(typeof(callback) == 'function'){ + callback(data); + } + },'json'); +} + +function httpPluginService(_name, version){ + var data = {name:_name, func:'status'} + if ( typeof(version) != 'undefined' ){ + data['version'] = version; + } else { + version = ''; + } + + httpPost('status', data, function(data){ + if (data.data == 'start'){ + orPluginSetService(_name, true, version); + } else { + orPluginSetService(_name, false, version); + } + }); +} + +function orPluginSetService(_name ,status, version){ + var serviceCon ='

当前状态:'+(status ? '开启' : '关闭' )+ + '

\ + \ + \ + \ +
'; + $(".soft-man-con").html(serviceCon); +} + + +function orPluginOpService(a, b, v,request_callback) { + + var c = "name=" + a + "&func=" + b; + if(v != ''){ + c = c + '&version='+v; + } + + var d = ""; + + switch(b) { + case "stop":d = '停止';break; + case "start":d = '启动';break; + case "restart":d = '重启';break; + case "reload":d = '重载';break; + } + layer.confirm( msgTpl('您真的要{1}{2}{3}服务吗?', [d,a,v]), {icon:3,closeBtn: 2}, function() { + httpPost('get_os',{},function(data){ + var rdata = $.parseJSON(data.data); + if (!rdata['auth']){ + layer.prompt({title: '检查到权限不足,需要输入密码!', formType: 1},function(pwd, index){ + + layer.close(index); + var data = {'pwd':pwd}; + c += '&args='+JSON.stringify(data); + orPluginOpServiceOp(a,b,c,d,a,v,request_callback); + }); + } else { + orPluginOpServiceOp(a,b,c,d,a,v,request_callback); + + } + }); + }) +} + +function orPluginOpServiceOp(a,b,c,d,a,v,request_callback){ + + var request_path = "/plugins/run"; + if (request_callback == 'yes'){ + request_path = "/plugins/callback"; + } + + var e = layer.msg(msgTpl('正在{1}{2}{3}服务,请稍候...',[d,a,v]), {icon: 16,time: 0}); + $.post(request_path, c, function(g) { + layer.close(e); + + var f = g.data == 'ok' ? msgTpl('{1}{2}服务已{3}',[a,v,d]) : msgTpl('{1}{2}服务{3}失败!',[a,v,d]); + layer.msg(f, {icon: g.data == 'ok' ? 1 : 2}); + + if( b != "reload" && g.data == 'ok' ) { + if ( b == 'start' ) { + orPluginSetService(a, true, v); + } else if ( b == 'stop' ){ + orPluginSetService(a, false, v); + } + } + + if( g.status && g.data != 'ok' ) { + layer.msg(g.data, {icon: 2,time: 10000,shade: 0.3}); + } + + },'json').error(function() { + layer.close(e); + layer.msg('操作异常!', {icon: 2}); + }); +} + + +// 定时器变量 +var httpdStatusTimer = null; + +//查看Apache负载状态 +function getHttpdStatus() { + $.post('/plugins/run', {name:'apache', func:'run_info'}, function(data) { + try { + var rdata = $.parseJSON(data.data); + + console.log(rdata); + if ('status' in rdata && !rdata.status){ + showMsg(rdata.msg, function(){}, null,3000); + return; + } + + var con = "
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
服务器版本(ServerVersion)" + (rdata.ServerVersion || '-') + "
服务器MPM(ServerMPM)" + (rdata.ServerMPM || '-') + "
服务器构建时间(Server Built)" + (rdata['Server Built'] || '-') + "
当前时间(CurrentTime)" + (rdata.CurrentTime || '-') + "
重启时间(RestartTime)" + (rdata.RestartTime || '-') + "
服务器运行时间(ServerUptime)" + (rdata.ServerUptime || '-') + "
服务器运行秒数(ServerUptimeSeconds)" + (rdata.ServerUptimeSeconds || '-') + "
1分钟负载(Load1)" + (rdata.Load1 || '-') + "
5分钟负载(Load5)" + (rdata.Load5 || '-') + "
15分钟负载(Load15)" + (rdata.Load15 || '-') + "
总访问次数(Total Accesses)" + (rdata['Total Accesses'] || '-') + "
总流量(Total kBytes)" + (rdata['Total kBytes'] || '-') + " KB
总请求时间(Total Duration)" + (rdata['Total Duration'] || '-') + "
CPU用户时间(CPUUser)" + (rdata.CPUUser || '-') + "
CPU系统时间(CPUSystem)" + (rdata.CPUSystem || '-') + "
CPU负载(CPULoad)" + (rdata.CPULoad || '-') + "
每秒请求数(ReqPerSec)" + (rdata.ReqPerSec || '-') + "
每秒流量(BytesPerSec)" + (rdata.BytesPerSec || '-') + "
每请求流量(BytesPerReq)" + (rdata.BytesPerReq || '-') + "
每请求时间(DurationPerReq)" + (rdata.DurationPerReq || '-') + "
活动工作进程(BusyWorkers)" + (rdata.BusyWorkers || '-') + "
优雅关闭进程(GracefulWorkers)" + (rdata.GracefulWorkers || '-') + "
空闲工作进程(IdleWorkers)" + (rdata.IdleWorkers || '-') + "
进程数(Processes)" + (rdata.Processes || '-') + "
总连接数(ConnsTotal)" + (rdata.ConnsTotal || '-') + "
"; + $(".soft-man-con").html(con); + }catch(err){ + showMsg(data.data, function(){}, null,3000); + } + },'json'); +} + +// 启动自动刷新 +function startHttpdStatusAutoRefresh() { + // 先清除现有的定时器 + if (httpdStatusTimer) { + clearInterval(httpdStatusTimer); + } + + // 立即执行一次 + getHttpdStatus(); + + // 设置定时器,每5秒刷新一次 + httpdStatusTimer = setInterval(getHttpdStatus, 5000); +} + +// 停止自动刷新 +function stopHttpdStatusAutoRefresh() { + if (httpdStatusTimer) { + clearInterval(httpdStatusTimer); + httpdStatusTimer = null; + } +} + + +function setOpCfg(){ + httpPost('get_cfg', {}, function(data){ + var rdata = $.parseJSON(data.data); + var rdata = rdata.data; + // console.log(rdata); + + var mlist = ''; + for (var i = 0; i < rdata.length; i++) { + var w = '70' + var ibody = ''; + switch (rdata[i].type) { + case 0: + var selected_1 = (rdata[i].value == 1) ? 'selected' : ''; + var selected_0 = (rdata[i].value == 0) ? 'selected' : ''; + ibody = ''; + break; + case 1: + var selected_1 = (rdata[i].value == 'on') ? 'selected' : ''; + var selected_0 = (rdata[i].value == 'off') ? 'selected' : ''; + ibody = ''; + break; + } + mlist += '

' + rdata[i].name + '' + ibody + ""+rdata[i].unit+"" +', ' + rdata[i].ps + '

'; + } + var con = '
\ + ' + mlist + '\ +
\ + \ + \ +
\ +
' + $(".soft-man-con").html(con); + }); +} + +function submitConf() { + var data = {}; + + // 收集所有配置参数 + $("input[name]").each(function() { + data[$(this).attr('name')] = $(this).val(); + }); + + $("select[name]").each(function() { + data[$(this).attr('name')] = $(this).val() || 'on'; + }); + + // console.log(data); + httpPost('set_cfg', data, function(rdata){ + var rdata = $.parseJSON(rdata.data); + // console.log(rdata); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + +function otherFunc(){ + var con = '

\ + \ + \ +

'; + $(".soft-man-con").html(con); +} + +function cronAddCheck(){ + httpPost('cron_add_check', {}, function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + +function cronDelCheck(){ + httpPost('cron_del_check', {}, function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + + + + + + + + + + + + diff --git a/plugins/apache/tool_task.py b/plugins/apache/tool_task.py new file mode 100644 index 000000000..4be4006f8 --- /dev/null +++ b/plugins/apache/tool_task.py @@ -0,0 +1,124 @@ +# coding:utf-8 + +import sys +import io +import os +import time +import json + +web_dir = os.getcwd() + "/web" +if os.path.exists(web_dir): + sys.path.append(web_dir) + os.chdir(web_dir) + +import core.mw as mw +from utils.crontab import crontab as MwCrontab + + +app_debug = False +if mw.isAppleSystem(): + app_debug = True + + +def getPluginName(): + return 'apache' + + +def getPluginDir(): + return mw.getPluginDir() + '/' + getPluginName() + + +def getServerDir(): + return mw.getServerDir() + '/' + getPluginName() + + +def getTaskConf(): + conf = getServerDir() + "/task_config.json" + return conf + + +def getConfigData(): + conf = getTaskConf() + if os.path.exists(conf): + return json.loads(mw.readFile(getTaskConf())) + return { + "task_id": -1, + "period": "minute-n", + "where1": "3", + "hour": "0", + "minute": "0", + } + + +def createBgTask(): + removeBgTask() + createBgTaskByName(getPluginName()) + + +def createBgTaskByName(name): + args = getConfigData() + _name = "[apache]检查任务" + res = mw.M("crontab").field("id, name").where("name=?", (_name,)).find() + if res: + return True + + if "task_id" in args and args["task_id"] > 0: + res = mw.M("crontab").field("id, name").where( + "id=?", (args["task_id"],)).find() + if res and res["id"] == args["task_id"]: + print("计划任务已经存在!") + return True + + mw_dir = mw.getPanelDir() + cmd = ''' +mw_dir=%s +rname=%s +plugin_path=%s +script_path=%s +''' % (mw_dir, name, getServerDir(), getPluginDir()) + cmd += 'echo "bash $script_path/check.sh"' + "\n" + cmd += 'cd $mw_dir && bash $script_path/check.sh' + "\n" + + params = { + 'name': _name, + 'type': args['period'], + 'week': "", + 'where1': args['where1'], + 'hour': args['hour'], + 'minute': args['minute'], + 'save': "", + 'backup_to': "", + 'stype': "toShell", + 'sname': '', + 'sbody': cmd, + 'url_address': '', + } + + task_id = MwCrontab.instance().add(params) + if task_id > 0: + args["task_id"] = task_id + args["name"] = name + mw.writeFile(getTaskConf(), json.dumps(args)) + + +def removeBgTask(): + cfg = getConfigData() + if "task_id" in cfg and cfg["task_id"] > 0: + res = mw.M("crontab").field("id, name").where( + "id=?", (cfg["task_id"],)).find() + if res and res["id"] == cfg["task_id"]: + data = MwCrontab.instance().delete(cfg["task_id"]) + if data["status"]: + cfg["task_id"] = -1 + mw.writeFile(getTaskConf(), json.dumps(cfg)) + return True + return False + + +if __name__ == "__main__": + if len(sys.argv) > 1: + action = sys.argv[1] + if action == "remove": + removeBgTask() + elif action == "add": + createBgTask() diff --git a/plugins/apache/versions/2.4/install.sh b/plugins/apache/versions/2.4/install.sh new file mode 100644 index 000000000..4825acbf6 --- /dev/null +++ b/plugins/apache/versions/2.4/install.sh @@ -0,0 +1,172 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/apache && bash install.sh install 2.4 +# cd /www/server/mdserver-web/plugins/apache && bash install.sh install 2.4 + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") + +sysName=`uname` +action=$1 +type=$2 + +VERSION=2.4.66 +apacheDir=${serverPath}/source/apache + +Install_App() +{ + if [ "${action}" == "install" ];then + if [ -d $serverPath/apache ];then + exit 0 + fi + fi + + # ----- cpu start ------ + if [ -z "${cpuCore}" ]; then + cpuCore="1" + fi + + if [ -f /proc/cpuinfo ];then + cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l` + fi + + MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}') + if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then + if [ "${cpuCore}" -gt "${MEM_INFO}" ];then + cpuCore="${MEM_INFO}" + fi + else + cpuCore="1" + fi + + if [ "$cpuCore" -gt "2" ];then + cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'` + else + cpuCore="1" + fi + # ----- cpu end ------ + + mkdir -p ${apacheDir} + echo 'install script ...' + OPTIONS='' + + # 安装 APR 和 APR-util + APR_VERSION=1.7.6 + APR_UTIL_VERSION=1.6.3 + + if [ ! -f ${apacheDir}/apr-${APR_VERSION}.tar.bz2 ];then + wget --no-check-certificate -O ${apacheDir}/apr-${APR_VERSION}.tar.bz2 https://downloads.apache.org/apr/apr-${APR_VERSION}.tar.bz2 -T 3 + fi + + if [ ! -f ${apacheDir}/apr-util-${APR_UTIL_VERSION}.tar.bz2 ];then + wget --no-check-certificate -O ${apacheDir}/apr-util-${APR_UTIL_VERSION}.tar.bz2 https://downloads.apache.org/apr/apr-util-${APR_UTIL_VERSION}.tar.bz2 -T 3 + fi + + # 安装 APR + if [ ! -d ${serverPath}/apache/apr ];then + cd ${apacheDir} && tar -jxf apr-${APR_VERSION}.tar.bz2 + cd ${apacheDir}/apr-${APR_VERSION} && ./configure --prefix=${serverPath}/apache/apr + make -j${cpuCore} && make install + if [ "$?" == "0" ];then + # 检查 APR 配置文件 + APR_CONFIG=$(find ${serverPath}/apache/apr -name "apr-*config" | head -1) + if [ -z "$APR_CONFIG" ];then + echo "APR installation failed: apr-config not found" + exit 1 + fi + echo "APR installed successfully: $APR_CONFIG" + else + echo "APR configure failed" + exit 1 + fi + fi + + # 安装 APR-util + if [ ! -d ${serverPath}/apache/apr-util ];then + cd ${apacheDir} && tar -jxf apr-util-${APR_UTIL_VERSION}.tar.bz2 + cd ${apacheDir}/apr-util-${APR_UTIL_VERSION} && ./configure --prefix=${serverPath}/apache/apr-util --with-apr=${serverPath}/apache/apr + make -j${cpuCore} && make install + if [ "$?" == "0" ];then + # 检查 APR-util 配置文件 + APU_CONFIG=$(find ${serverPath}/apache/apr-util -name "apu-*config" | head -1) + if [ -z "$APU_CONFIG" ];then + echo "APR-util installation failed: apu-config not found" + find ${serverPath}/apache/apr-util -name "apu-*config" + exit 1 + fi + echo "APR-util installed successfully: $APU_CONFIG" + else + echo "APR-util configure failed" + exit 1 + fi + fi + + if [ ! -f ${apacheDir}/httpd-${VERSION}.tar.bz2 ];then + wget --no-check-certificate -O ${apacheDir}/httpd-${VERSION}.tar.bz2 https://downloads.apache.org/httpd/httpd-${VERSION}.tar.bz2 -T 3 + fi + + if [ ! -d ${apacheDir}/httpd-${VERSION} ];then + cd ${apacheDir} && tar -jxf ${apacheDir}/httpd-${VERSION}.tar.bz2 + fi + + + # 检查 APR 和 APR-util 可执行文件 + APR_CONFIG=$(find ${serverPath}/apache/apr -name "apr-*config" | head -1) + APU_CONFIG=$(find ${serverPath}/apache/apr-util -name "apu-*config" | head -1) + + if [ -z "$APR_CONFIG" ];then + echo "APR config not found" + exit 1 + fi + + if [ -z "$APU_CONFIG" ];then + echo "APR-util config not found" + exit 1 + fi + + OPTIONS="${OPTIONS} --with-apr=$APR_CONFIG" + OPTIONS="${OPTIONS} --with-apr-util=$APU_CONFIG" + + # if [ "$sysName" != "Darwin" ];then + # OPTIONS="${OPTIONS} --enable-systemd" + # fi + # echo "cd ${apacheDir}/httpd-${VERSION} && ./configure --prefix=$serverPath/apache $OPTIONS" + cd ${apacheDir}/httpd-${VERSION} && ./configure \ + --prefix=$serverPath/apache/httpd \ + $OPTIONS + + make -j${cpuCore} && make install && make clean + + + if [ -d ${apacheDir}/apr-${APR_VERSION} ];then + rm -rf ${apacheDir}/apr-${APR_VERSION} + fi + + if [ -d ${apacheDir}/apr-util-${APR_UTIL_VERSION} ];then + rm -rf ${apacheDir}/apr-util-${APR_UTIL_VERSION} + fi + + if [ -d ${apacheDir}/httpd-${APR_UTIL_VERSION} ];then + rm -rf ${apacheDir}/httpd-${APR_UTIL_VERSION} + fi + + echo 'installation of apache completed' +} + +Uninstall_App() +{ + echo 'uninstalling apache completed' +} + +action=$1 +if [ "${1}" == "install" ];then + Install_App +elif [ "${1}" == "upgrade" ];then + Install_App +else + Uninstall_App +fi diff --git a/plugins/caddy/check.sh b/plugins/caddy/check.sh new file mode 100755 index 000000000..4cb2277cc --- /dev/null +++ b/plugins/caddy/check.sh @@ -0,0 +1,35 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# OpenResty服务名称 +service_name="caddy" + +# 检查OpenResty是否正在运行 +if systemctl is-active --quiet "$service_name"; then + # 检查是否存在僵尸进程 + zombie_processes=$(ps -ef | grep -i caddy | grep -v grep | awk '{print $2}' | xargs ps -o state= -p 2>/dev/null | grep -c Z) + if [ "$zombie_processes" -gt 0 ]; then + echo "kill caddy 僵尸进程" + ps -ef|grep caddy| grep -v grep| awk '{print $2}' | xargs kill -9 + echo "检测到OpenResty僵尸进程,正在重启服务..." + systemctl restart "$service_name" + echo "服务已重启" + else + echo "OpenResty运行正常" + fi +else + echo "kill caddy" + ps -ef|grep caddy| grep -v grep| awk '{print $2}' | xargs kill -9 + echo "caddy未运行,正在启动服务..." + systemctl start "$service_name" + echo "服务已启动" +fi + +NGINX_IDS=`ps -ef|grep caddy | grep -v grep| awk '{print $2}'` +if [ "$NGINX_IDS" == "" ];then + ps -ef|grep caddy| grep -v grep| awk '{print $2}' | xargs kill -9 + systemctl start "$service_name" + echo "caddy未运行,正在启动服务..." +fi + diff --git a/plugins/caddy/conf/Caddyfile b/plugins/caddy/conf/Caddyfile new file mode 100644 index 000000000..98594e3a2 --- /dev/null +++ b/plugins/caddy/conf/Caddyfile @@ -0,0 +1,13 @@ +:8080 { + # Set this path to your site's directory. + root * /tmp + + # Enable the static file server. + file_server + + # Another common task is to set up a reverse proxy: + # reverse_proxy localhost:8080 + + # Or serve a PHP site through php-fpm: + # php_fastcgi localhost:9000 +} \ No newline at end of file diff --git a/plugins/caddy/ico.png b/plugins/caddy/ico.png new file mode 100644 index 000000000..91071011e Binary files /dev/null and b/plugins/caddy/ico.png differ diff --git a/plugins/caddy/index.html b/plugins/caddy/index.html new file mode 100755 index 000000000..92cba9ba6 --- /dev/null +++ b/plugins/caddy/index.html @@ -0,0 +1,24 @@ +
+ +
+
+

服务

+

自启动

+

配置修改

+

负载状态

+

性能调整

+

错误日志

+

维护功能

+
+
+
+
+
+ +
+ + \ No newline at end of file diff --git a/plugins/caddy/index.py b/plugins/caddy/index.py new file mode 100755 index 000000000..3afeb540e --- /dev/null +++ b/plugins/caddy/index.py @@ -0,0 +1,445 @@ +# coding:utf-8 + +import sys +import io +import os +import time +import threading +import subprocess +import re + + +web_dir = os.getcwd() + "/web" +if os.path.exists(web_dir): + sys.path.append(web_dir) + os.chdir(web_dir) + +import core.mw as mw + +app_debug = False +if mw.isAppleSystem(): + app_debug = True + + +def getPluginName(): + return 'caddy' + + +def getPluginDir(): + return mw.getPluginDir() + '/' + getPluginName() + + +def getServerDir(): + return mw.getServerDir() + '/' + getPluginName() + + +def getInitDFile(): + current_os = mw.getOs() + if current_os == 'darwin': + return '/tmp/' + getPluginName() + + if current_os.startswith('freebsd'): + return '/etc/rc.d/' + getPluginName() + + return '/etc/init.d/' + getPluginName() + + +def getArgs(): + args = sys.argv[2:] + # print(args) + tmp = {} + args_len = len(args) + + if args_len == 1: + t = args[0].strip('{').strip('}') + t = t.split(':',2) + tmp[t[0]] = t[1] + elif args_len > 1: + for i in range(len(args)): + t = args[i].split(':',2) + tmp[t[0]] = t[1] + # print(tmp) + return tmp + + +def checkArgs(data, ck=[]): + for i in range(len(ck)): + if not ck[i] in data: + return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!')) + return (True, mw.returnJson(True, 'ok')) + + +def getOs(): + data = {} + data['os'] = mw.getOs() + data['auth'] = True + return mw.getJson(data) + +def getConf(): + path = getServerDir() + "/Caddyfile" + return path + + +def getConfTpl(): + path = getPluginDir() + '/conf/Caddyfile' + return path + + +def getInitDTpl(): + path = getPluginDir() + "/init.d/caddy.tpl" + return path + +def initDreplace(): + file_tpl = getInitDTpl() + service_path = mw.getServerDir() + initD_path = getServerDir() + '/init.d' + + # init.d + file_bin = initD_path + '/' + getPluginName() + + if not os.path.exists(initD_path): + os.mkdir(initD_path) + + # initd replace + content = mw.readFile(file_tpl) + content = content.replace('{$SERVER_PATH}', service_path) + mw.writeFile(file_bin, content) + mw.execShell('chmod +x ' + file_bin) + + caddy_file = getConf() + if not os.path.exists(caddy_file): + caddy_file_tpl = getConfTpl() + content = mw.readFile(systemServiceTpl) + content = content.replace('{$SERVER_PATH}', service_path) + mw.writeFile(caddy_file, content) + + # systemd + # /usr/lib/systemd/system + systemDir = mw.systemdCfgDir() + systemService = systemDir + '/caddy.service' + if os.path.exists(systemDir) and not os.path.exists(systemService): + systemServiceTpl = getPluginDir() + '/init.d/caddy.service.tpl' + se_content = mw.readFile(systemServiceTpl) + se_content = se_content.replace('{$SERVER_PATH}', service_path) + mw.writeFile(systemService, se_content) + mw.execShell('systemctl daemon-reload') + + return file_bin + + +def status(): + cmd = "ps -ef|grep 'caddy run' |grep -v grep | grep -v python | awk '{print $2}'" + data = mw.execShell(cmd) + if data[0] == '': + return 'stop' + return 'start' + + +def caddyOp(method): + file = initDreplace() + + current_os = mw.getOs() + if current_os == "darwin": + data = mw.execShell(file + ' ' + method) + if data[1] == '': + return 'ok' + return data[1] + + if current_os.startswith("freebsd"): + data = mw.execShell('service caddy ' + method) + if data[1] == '': + return 'ok' + return data[1] + + data = mw.execShell('systemctl ' + method + ' caddy') + if data[1] == '': + return 'ok' + return data[1] + +def start(): + return caddyOp('start') + + +def stop(): + r = caddyOp('stop') + return r + + +def restart(): + return restyOp_restart() + + +def reload(): + confReplace() + return caddyOp('reload') + + +def initdStatus(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + if current_os.startswith('freebsd'): + initd_bin = getInitDFile() + if os.path.exists(initd_bin): + return 'ok' + + shell_cmd = 'systemctl status caddy | grep loaded | grep "enabled;"' + data = mw.execShell(shell_cmd) + if data[0] == '': + return 'fail' + return 'ok' + + +def initdInstall(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + # freebsd initd install + if current_os.startswith('freebsd'): + import shutil + source_bin = initDreplace() + initd_bin = getInitDFile() + shutil.copyfile(source_bin, initd_bin) + mw.execShell('chmod +x ' + initd_bin) + mw.execShell('sysrc ' + getPluginName() + '_enable="YES"') + return 'ok' + + mw.execShell('systemctl enable caddy') + return 'ok' + + +def initdUinstall(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + if current_os.startswith('freebsd'): + initd_bin = getInitDFile() + os.remove(initd_bin) + mw.execShell('sysrc ' + getPluginName() + '_enable="NO"') + return 'ok' + + mw.execShell('systemctl disable caddy') + return 'ok' + + +def runInfo(): + op_status = status() + if op_status == 'stop': + return mw.returnJson(False, "未启动!") + + +def errorLogPath(): + return getServerDir() + '/nginx/logs/error.log' + + +def getCfg(): + cfg = getConf() + content = mw.readFile(cfg) + + unitrep = "[kmgKMG]" + cfg_args = [ + {"name": "worker_processes", "ps": "处理进程,auto表示自动,数字表示进程数", 'type': 2}, + {"name": "worker_connections", "ps": "最大并发链接数", 'type': 2}, + {"name": "keepalive_timeout", "ps": "连接超时时间", 'type': 2}, + {"name": "zstd", "ps": "是否开启zstd压缩传输", 'type': 1}, + {"name": "brotli", "ps": "是否开启brotli压缩传输", 'type': 1}, + {"name": "gzip", "ps": "是否开启gzip压缩传输", 'type': 1}, + {"name": "gzip_min_length", "ps": "最小压缩文件", 'type': 2}, + {"name": "gzip_comp_level", "ps": "压缩率", 'type': 2}, + {"name": "client_max_body_size", "ps": "最大上传文件", 'type': 2}, + {"name": "server_names_hash_bucket_size", + "ps": "服务器名字的hash表大小", 'type': 2}, + {"name": "client_header_buffer_size", "ps": "客户端请求头buffer大小", 'type': 2}, + ] + + # {"name": "client_body_buffer_size", "ps": "请求主体缓冲区"} + rdata = [] + for i in cfg_args: + rep = r"(%s)\s+(\w+)" % i["name"] + k = re.search(rep, content) + if not k: + return mw.returnJson(False, "获取 key {} 失败".format(k)) + k = k.group(1) + v = re.search(rep, content) + if not v: + return mw.returnJson(False, "获取 value {} 失败".format(v)) + v = v.group(2) + + if re.search(unitrep, v): + u = str.upper(v[-1]) + v = v[:-1] + if len(u) == 1: + psstr = u + "B," + i["ps"] + else: + psstr = u + "," + i["ps"] + else: + u = "" + + kv = {"name": k, "value": v, "unit": u, + "ps": i["ps"], "type": i["type"]} + rdata.append(kv) + + return mw.returnJson(True, "ok", rdata) + +def replaceChar(value, index, new_char): + return value[:index] + new_char + value[index+1:] + +def makeWorkerCpuAffinity(val): + if val == "auto": + return "auto" + + if mw.isNumber(val): + core_num = int(val) + default_core_str = "0"*core_num + core_num_arr = [] + for x in range(core_num): + t = replaceChar(default_core_str, x , "1") + core_num_arr.append(t) + return " ".join(core_num_arr) + + return 'auto' + +def setCfg(): + + args = getArgs() + data = checkArgs(args, [ + 'worker_processes', 'worker_connections', 'keepalive_timeout','zstd','brotli', + 'gzip', 'gzip_min_length', 'gzip_comp_level', 'client_max_body_size', + 'server_names_hash_bucket_size', 'client_header_buffer_size' + ]) + if not data[0]: + return data[1] + + cfg = getConf() + mw.backFile(cfg) + content = mw.readFile(cfg) + + unitrep = "[kmgKMG]" + cfg_args = [ + {"name": "worker_processes", "ps": "处理进程,auto表示自动,数字表示进程数", 'type': 2}, + {"name": "worker_connections", "ps": "最大并发链接数", 'type': 2}, + {"name": "keepalive_timeout", "ps": "连接超时时间", 'type': 2}, + {"name": "zstd", "ps": "是否开启zstd压缩传输", 'type': 1}, + {"name": "brotli", "ps": "是否开启brotli压缩传输", 'type': 1}, + {"name": "gzip", "ps": "是否开启压缩传输", 'type': 1}, + {"name": "gzip_min_length", "ps": "最小压缩文件", 'type': 2}, + {"name": "gzip_comp_level", "ps": "压缩率", 'type': 2}, + {"name": "client_max_body_size", "ps": "最大上传文件", 'type': 2}, + {"name": "server_names_hash_bucket_size", + "ps": "服务器名字的hash表大小", 'type': 2}, + {"name": "client_header_buffer_size", "ps": "客户端请求头buffer大小", 'type': 2}, + ] + + # print(args) + for k, v in args.items(): + # print(k, v) + rep = r"%s\s+[^kKmMgG\;\n]+" % k + if k == "worker_processes" or k == "gzip": + if not re.search(r"auto|on|off|\d+", v): + return mw.returnJson(False, '参数值错误') + elif k == "zstd" or k == "brotli": + if not re.search(r"auto|on|off|\d+", v): + return mw.returnJson(False, '参数值错误') + else: + if not re.search(r"\d+", v): + return mw.returnJson(False, '参数值错误,请输入数字整数') + + if k == "worker_processes" : + k_wca = "worker_cpu_affinity" + rep_wca = r"%s\s+[^\;\n]+" % k_wca + v_wca = makeWorkerCpuAffinity(v) + newconf = "%s %s" % (k_wca, v_wca) + content = re.sub(rep_wca, newconf, content) + + + if re.search(rep, content): + newconf = "%s %s" % (k, v) + content = re.sub(rep, newconf, content) + elif re.search(rep, content): + newconf = "%s %s" % (k, v) + content = re.sub(rep, newconf, content) + + mw.writeFile(cfg, content) + isError = mw.checkWebConfig() + if (isError != True): + mw.restoreFile(cfg) + return mw.returnJson(False, 'ERROR: 配置出错
' + isError.replace("\n", '
') + '
') + + mw.restartWeb() + return mw.returnJson(True, '设置成功') + + +def cronAddCheck(): + try: + import tool_task + tool_task.createBgTask() + return mw.returnJson(True, '添加检查任务成功') + except Exception as e: + return mw.returnJson(False, '添加检查任务失败:'+str(e)) + +def cronDelCheck(): + try: + import tool_task + tool_task.removeBgTask() + return mw.returnJson(True, '删除检查任务成功') + except Exception as e: + return mw.returnJson(False, '删除检查任务失败:'+str(e)) + +def cronCheck(): + return 'ok' + + +def installPreInspection(): + return 'ok' + + +if __name__ == "__main__": + + version = '1.27.1' + version_pl = getServerDir() + "/version.pl" + if os.path.exists(version_pl): + version = mw.readFile(version_pl) + + + func = sys.argv[1] + if func == 'status': + print(status()) + elif func == 'start': + print(start()) + elif func == 'stop': + print(stop()) + elif func == 'restart': + print(restart()) + elif func == 'reload': + print(reload()) + elif func == 'initd_status': + print(initdStatus()) + elif func == 'initd_install': + print(initdInstall()) + elif func == 'initd_uninstall': + print(initdUinstall()) + elif func == 'install_pre_inspection': + print(installPreInspection()) + elif func == 'conf': + print(getConf()) + elif func == 'get_os': + print(getOs()) + elif func == 'run_info': + print(runInfo()) + elif func == 'error_log': + print(errorLogPath()) + elif func == 'get_cfg': + print(getCfg()) + elif func == 'set_cfg': + print(setCfg()) + elif func == 'check': + print(cronCheck()) + elif func == 'cron_add_check': + print(cronAddCheck()) + elif func == 'cron_del_check': + print(cronDelCheck()) + else: + print('error') diff --git a/plugins/caddy/info.json b/plugins/caddy/info.json new file mode 100755 index 000000000..97a69c069 --- /dev/null +++ b/plugins/caddy/info.json @@ -0,0 +1,18 @@ +{ + "sort": 0, + "title":"caddy", + "tip":"soft", + "name":"caddy", + "type":"其他插件", + "ps":"一款功能强大、企业级、开源 Web 服务器,具有用 Go 编写的自动 HTTPS", + "shell":"install.sh", + "install_pre_inspection":true, + "checks":"server/caddy", + "path":"server/caddy", + "author":"caddyserver", + "home":"https://caddyserver.com/", + "date":"2026-04-11", + "pid": "1", + "versions": ["2.11"], + "updates": ["2.11.2"] +} \ No newline at end of file diff --git a/plugins/caddy/init.d/caddy.service.tpl b/plugins/caddy/init.d/caddy.service.tpl new file mode 100644 index 000000000..724eb30d7 --- /dev/null +++ b/plugins/caddy/init.d/caddy.service.tpl @@ -0,0 +1,36 @@ +# caddy.service +# +# For using Caddy with a config file. +# +# Make sure the ExecStart and ExecReload commands are correct +# for your installation. +# +# See https://caddyserver.com/docs/install for instructions. +# +# WARNING: This service does not use the --resume flag, so if you +# use the API to make changes, they will be overwritten by the +# Caddyfile next time the service is restarted. If you intend to +# use Caddy's API to configure it, add the --resume flag to the +# `caddy run` command or use the caddy-api.service file instead. + +[Unit] +Description=Caddy +Documentation=https://caddyserver.com/docs/ +After=network.target network-online.target +Requires=network-online.target + +[Service] +Type=notify +User=caddy +Group=caddy +ExecStart={$SERVER_PATH}/caddy/bin/caddy run --environ --config {$SERVER_PATH}/caddy/Caddyfile +ExecReload={$SERVER_PATH}/caddy/bin/caddy reload --config {$SERVER_PATH}/caddy/Caddyfile --force +TimeoutStopSec=5s +LimitNOFILE=1048576 +LimitNPROC=512 +PrivateTmp=true +ProtectSystem=full +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target diff --git a/plugins/caddy/init.d/caddy.tpl b/plugins/caddy/init.d/caddy.tpl new file mode 100644 index 000000000..e89186483 --- /dev/null +++ b/plugins/caddy/init.d/caddy.tpl @@ -0,0 +1,111 @@ +#!/bin/sh +# +# /etc/rc.d/init.d/caddy +# +# Runs the caddy +# +# +# chkconfig: - 85 15 +# + +### BEGIN INIT INFO +# Provides: caddy +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Should-Start: caddy +# Should-Stop: caddy +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start caddy at boot time. +# Description: Control caddy. +### END INIT INFO + +# Source function library. +if [ -f /etc/init.d/functions ];then + . /etc/init.d/functions +fi + +if [ -f /etc/rc.d/init.d/functions ];then + . /etc/rc.d/init.d/functions +fi + +# Default values +export HOME={$HOME_DIR} +export USER={$RUN_USER} +NAME=caddy +CADDY_HOME={$SERVER_PATH}/caddy +CADDY_PATH=${CADDY_HOME}/bin/$NAME +CADDY_USER={$RUN_USER} +SERVICENAME="caddy" +LOCKFILE=/tmp/caddy.lock +LOGPATH=${CADDY_HOME}/log +LOGFILE=${LOGPATH}/caddy.log +RETVAL=0 + +if [ -d $LOGPATH ];then + mkdir -p $LOGPATH +fi + +[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME +DAEMON_OPTS="--check $NAME" +[ ! -z "$CADDY_USER" ] && DAEMON_OPTS="$DAEMON_OPTS --user=${CADDY_USER}" + +status(){ + isStart=`ps -ef|grep 'caddy run' |grep -v grep|awk '{print $2}'` + if [ "$isStart" == '' ];then + echo -e "${SERVICENAME} not running" + else + echo -e "${SERVICENAME}(pid $(echo $isStart)) already running" + fi +} + +start() { + isStart=`ps -ef | grep 'caddy run' | grep -v grep | awk '{print $2}'` + if [ "$isStart" != '' ];then + echo "${SERVICENAME}(pid $(echo $isStart)) already running" + return $RETVAL + fi + + cd ${CADDY_HOME} + echo -e "starting ${SERVICENAME}: \c" + ${CADDY_PATH} run --environ --config ${CADDY_HOME}/Caddyfile > ${LOGFILE} 2>&1 & + RETVAL=$? + [ $RETVAL = 0 ] && touch ${LOCKFILE} && echo -e "\033[32mdone\033[0m" + return $RETVAL +} + +stop() { + pids=`ps -ef | grep 'caddy run' | grep -v grep | awk '{print $2}'` + arr=($pids) + echo -e "stopping caddy... \c" + for p in ${arr[@]} + do + kill -9 $p + done + echo -e "\033[32mdone\033[0m" +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status + ;; + restart) + stop + start + ;; + reload) + stop + start + ;; + *) + echo "Usage: ${NAME} {start|stop|status|restart}" + exit 1 + ;; +esac +exit $RETVAL diff --git a/plugins/caddy/install.sh b/plugins/caddy/install.sh new file mode 100755 index 000000000..cf40b02da --- /dev/null +++ b/plugins/caddy/install.sh @@ -0,0 +1,76 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/caddy && bash install.sh install 1.21.4 +# cd /www/server/mdserver-web/plugins/caddy && bash install.sh install 1.21.4 +# cd /www/server/mdserver-web/plugins/caddy && bash install.sh install 1.29.2 +# cd /www/server/mdserver-web/plugins/caddy && bash install.sh upgrade 1.29.2 + +# curl -I -H "Accept-Encoding: br" http://localhost +# curl -I -H "Accept-Encoding: zstd" http://localhost +# curl --http3 -v https://www.xxx.com + +# cd /www/server/mdserver-web && python3 plugins/caddy/index.py run_info + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") + +sysName=`uname` +action=$1 +type=$2 + +VERSION=$2 +openrestyDir=${serverPath}/source/caddy + +if id www &> /dev/null ;then + echo "www uid is `id -u www`" + echo "www shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `" +else + groupadd www + useradd -g www -s /bin/bash www +fi + +if [ "${action}" == "upgrade" ];then + sh -x $curPath/versions/$2/install.sh $1 + + echo "${VERSION}" > $serverPath/caddy/version.pl + + #初始化 + cd ${rootPath} && python3 ${rootPath}/plugins/caddy/index.py start + cd ${rootPath} && python3 ${rootPath}/plugins/caddy/index.py initd_install + exit 0 +fi + + +if [ "${2}" == "" ];then + echo '缺少安装脚本版本...' + exit 0 +fi + +if [ "${action}" == "uninstall" ];then + if [ -f /usr/lib/systemd/system/caddy.service ] || [ -f /lib/systemd/system/caddy.service ];then + systemctl stop caddy + rm -rf /usr/systemd/system/caddy.service + rm -rf /lib/systemd/system/caddy.service + systemctl daemon-reload + fi + + if [ -f $serverPath/caddy/init.d/caddy ];then + $serverPath/caddy/init.d/caddy stop + fi + + rm -rf $serverPath/caddy +fi + +sh -x $curPath/versions/$2/install.sh $1 + +if [ "${action}" == "install" ] && [ -d $serverPath/caddy ];then + echo "${VERSION}" > $serverPath/caddy/version.pl + + #初始化 + cd ${rootPath} && python3 ${rootPath}/plugins/caddy/index.py start + cd ${rootPath} && python3 ${rootPath}/plugins/caddy/index.py initd_install +fi diff --git a/plugins/caddy/js/caddy.js b/plugins/caddy/js/caddy.js new file mode 100755 index 000000000..3eccb9fce --- /dev/null +++ b/plugins/caddy/js/caddy.js @@ -0,0 +1,238 @@ +function caddyPost(method, args, callback){ + var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 }); + $.post('/plugins/run', {name:'caddy', func:method, args:JSON.stringify(args)}, function(data) { + layer.close(loadT); + if (!data.status){ + layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']}); + return; + } + + if(typeof(callback) == 'function'){ + callback(data); + } + },'json'); +} + +function orPluginService(_name, version){ + var data = {name:_name, func:'status'} + if ( typeof(version) != 'undefined' ){ + data['version'] = version; + } else { + version = ''; + } + + caddyPost('status', data, function(data){ + if (data.data == 'start'){ + orPluginSetService(_name, true, version); + } else { + orPluginSetService(_name, false, version); + } + }); +} + +function orPluginSetService(_name ,status, version){ + var serviceCon ='

当前状态:'+(status ? '开启' : '关闭' )+ + '

\ + \ + \ + \ +
'; + $(".soft-man-con").html(serviceCon); +} + + +function orPluginOpService(a, b, v,request_callback) { + + var c = "name=" + a + "&func=" + b; + if(v != ''){ + c = c + '&version='+v; + } + + var d = ""; + + switch(b) { + case "stop":d = '停止';break; + case "start":d = '启动';break; + case "restart":d = '重启';break; + case "reload":d = '重载';break; + } + layer.confirm( msgTpl('您真的要{1}{2}{3}服务吗?', [d,a,v]), {icon:3,closeBtn: 2}, function() { + caddyPost('get_os',{},function(data){ + var rdata = $.parseJSON(data.data); + if (!rdata['auth']){ + layer.prompt({title: '检查到权限不足,需要输入密码!', formType: 1},function(pwd, index){ + + layer.close(index); + var data = {'pwd':pwd}; + c += '&args='+JSON.stringify(data); + orPluginOpServiceOp(a,b,c,d,a,v,request_callback); + }); + } else { + orPluginOpServiceOp(a,b,c,d,a,v,request_callback); + + } + }); + }) +} + +function orPluginOpServiceOp(a,b,c,d,a,v,request_callback){ + + var request_path = "/plugins/run"; + if (request_callback == 'yes'){ + request_path = "/plugins/callback"; + } + + var e = layer.msg(msgTpl('正在{1}{2}{3}服务,请稍候...',[d,a,v]), {icon: 16,time: 0}); + $.post(request_path, c, function(g) { + layer.close(e); + + var f = g.data == 'ok' ? msgTpl('{1}{2}服务已{3}',[a,v,d]) : msgTpl('{1}{2}服务{3}失败!',[a,v,d]); + layer.msg(f, {icon: g.data == 'ok' ? 1 : 2}); + + if( b != "reload" && g.data == 'ok' ) { + if ( b == 'start' ) { + orPluginSetService(a, true, v); + } else if ( b == 'stop' ){ + orPluginSetService(a, false, v); + } + } + + if( g.status && g.data != 'ok' ) { + layer.msg(g.data, {icon: 2,time: 10000,shade: 0.3}); + } + + },'json').error(function() { + layer.close(e); + layer.msg('操作异常!', {icon: 2}); + }); +} + + +//查看Nginx负载状态 +function getOpStatus() { + var loadT = layer.msg('正在处理,请稍后...', { icon: 16, time: 0, shade: 0.3 }); + $.post('/plugins/run', {name:'openresty', func:'run_info'}, function(data) { + layer.close(loadT); + try { + var rdata = $.parseJSON(data.data); + if ('status' in rdata && !rdata.status){ + showMsg(rdata.msg, function(){}, null,3000); + return; + } + + var con = "
\ + \ + \ + \ + \ + \ + \ + \ +
活动连接(Active connections)" + rdata.active + "
总连接次数(accepts)" + rdata.accepts + "
总握手次数(handled)" + rdata.handled + "
总请求数(requests)" + rdata.requests + "
请求数(Reading)" + rdata.Reading + "
响应数(Writing)" + rdata.Writing + "
驻留进程(Waiting)" + rdata.Waiting + "
"; + $(".soft-man-con").html(con); + }catch(err){ + showMsg(data.data, function(){}, null,3000); + } + },'json'); +} + + +function setOpCfg(){ + caddyPost('get_cfg', {}, function(data){ + var rdata = $.parseJSON(data.data); + var rdata = rdata.data; + // console.log(rdata); + + var mlist = ''; + for (var i = 0; i < rdata.length; i++) { + var w = '70' + var ibody = ''; + switch (rdata[i].type) { + case 0: + var selected_1 = (rdata[i].value == 1) ? 'selected' : ''; + var selected_0 = (rdata[i].value == 0) ? 'selected' : ''; + ibody = ''; + break; + case 1: + var selected_1 = (rdata[i].value == 'on') ? 'selected' : ''; + var selected_0 = (rdata[i].value == 'off') ? 'selected' : ''; + ibody = ''; + break; + } + mlist += '

' + rdata[i].name + '' + ibody + ""+rdata[i].unit+"" +', ' + rdata[i].ps + '

'; + } + var con = '
\ + ' + mlist + '\ +
\ + \ + \ +
\ +
' + $(".soft-man-con").html(con); + }); +} + +function submitConf() { + var data = { + worker_processes: $("input[name='worker_processes']").val(), + worker_connections: $("input[name='worker_connections']").val(), + keepalive_timeout: $("input[name='keepalive_timeout']").val(), + zstd: $("select[name='zstd']").val() || 'on', + brotli: $("select[name='brotli']").val() || 'on', + gzip: $("select[name='gzip']").val() || 'on', + gzip_min_length: $("input[name='gzip_min_length']").val(), + gzip_comp_level: $("input[name='gzip_comp_level']").val(), + client_max_body_size: $("input[name='client_max_body_size']").val(), + server_names_hash_bucket_size: $("input[name='server_names_hash_bucket_size']").val(), + client_header_buffer_size: $("input[name='client_header_buffer_size']").val(), + }; + + // console.log(data); + caddyPost('set_cfg', data, function(rdata){ + var rdata = $.parseJSON(rdata.data); + // console.log(rdata); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + +function otherFunc(){ + var con = '

\ + \ + \ +

'; + $(".soft-man-con").html(con); +} + +function cronAddCheck(){ + caddyPost('cron_add_check', {}, function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + +function cronDelCheck(){ + caddyPost('cron_del_check', {}, function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + + + + + + + + + + + + diff --git a/plugins/caddy/tool_task.py b/plugins/caddy/tool_task.py new file mode 100644 index 000000000..f20ba8348 --- /dev/null +++ b/plugins/caddy/tool_task.py @@ -0,0 +1,124 @@ +# coding:utf-8 + +import sys +import io +import os +import time +import json + +web_dir = os.getcwd() + "/web" +if os.path.exists(web_dir): + sys.path.append(web_dir) + os.chdir(web_dir) + +import core.mw as mw +from utils.crontab import crontab as MwCrontab + + +app_debug = False +if mw.isAppleSystem(): + app_debug = True + + +def getPluginName(): + return 'caddy' + + +def getPluginDir(): + return mw.getPluginDir() + '/' + getPluginName() + + +def getServerDir(): + return mw.getServerDir() + '/' + getPluginName() + + +def getTaskConf(): + conf = getServerDir() + "/task_config.json" + return conf + + +def getConfigData(): + conf = getTaskConf() + if os.path.exists(conf): + return json.loads(mw.readFile(getTaskConf())) + return { + "task_id": -1, + "period": "minute-n", + "where1": "3", + "hour": "0", + "minute": "0", + } + + +def createBgTask(): + removeBgTask() + createBgTaskByName(getPluginName()) + + +def createBgTaskByName(name): + args = getConfigData() + _name = "[caddy]检查任务" + res = mw.M("crontab").field("id, name").where("name=?", (_name,)).find() + if res: + return True + + if "task_id" in args and args["task_id"] > 0: + res = mw.M("crontab").field("id, name").where( + "id=?", (args["task_id"],)).find() + if res and res["id"] == args["task_id"]: + print("计划任务已经存在!") + return True + + mw_dir = mw.getPanelDir() + cmd = ''' +mw_dir=%s +rname=%s +plugin_path=%s +script_path=%s +''' % (mw_dir, name, getServerDir(), getPluginDir()) + cmd += 'echo "bash $script_path/check.sh"' + "\n" + cmd += 'cd $mw_dir && bash $script_path/check.sh' + "\n" + + params = { + 'name': _name, + 'type': args['period'], + 'week': "", + 'where1': args['where1'], + 'hour': args['hour'], + 'minute': args['minute'], + 'save': "", + 'backup_to': "", + 'stype': "toShell", + 'sname': '', + 'sbody': cmd, + 'url_address': '', + } + + task_id = MwCrontab.instance().add(params) + if task_id > 0: + args["task_id"] = task_id + args["name"] = name + mw.writeFile(getTaskConf(), json.dumps(args)) + + +def removeBgTask(): + cfg = getConfigData() + if "task_id" in cfg and cfg["task_id"] > 0: + res = mw.M("crontab").field("id, name").where( + "id=?", (cfg["task_id"],)).find() + if res and res["id"] == cfg["task_id"]: + data = MwCrontab.instance().delete(cfg["task_id"]) + if data["status"]: + cfg["task_id"] = -1 + mw.writeFile(getTaskConf(), json.dumps(cfg)) + return True + return False + + +if __name__ == "__main__": + if len(sys.argv) > 1: + action = sys.argv[1] + if action == "remove": + removeBgTask() + elif action == "add": + createBgTask() diff --git a/plugins/caddy/versions/2.11/install.sh b/plugins/caddy/versions/2.11/install.sh new file mode 100644 index 000000000..e97027b78 --- /dev/null +++ b/plugins/caddy/versions/2.11/install.sh @@ -0,0 +1,87 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/caddy && bash install.sh install 2.11 +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/caddy && bash install.sh upgrade 2.11 +# cd /www/server/mdserver-web/plugins/caddy && bash install.sh install 2.11 + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") + +sysName=`uname` +action=$1 +type=$2 + +OS=`uname` +OSNAME='' +case $(uname) in + Darwin) OSNAME="mac" ;; + Linux) OSNAME="linux" ;; +esac + +ARCH=`uname -m` +ARCH_NAME='' +case $(uname -m) in + i386) ARCH_NAME="386" ;; + i686) ARCH_NAME="386" ;; + x86_64) ARCH_NAME="amd64" ;; + arm) ARCH_NAME="arm64" ;; + arm64) ARCH_NAME="arm64" ;; +esac + +VERSION=2.11.2 + +caddyDir=${serverPath}/source/caddy + +Install_App() +{ + if [ "${action}" == "install" ];then + if [ -d $serverPath/caddy ];then + exit 0 + fi + fi + + mkdir -p ${caddyDir} + # mkdir -p ${serverPath}/caddy + echo 'install scripts ...' + + FILE_NAME="caddy_${VERSION}_${OSNAME}_${ARCH_NAME}.tar.gz" + + if [ ! -f ${caddyDir}/${FILE_NAME} ];then + wget --no-check-certificate -O ${caddyDir}/${FILE_NAME} "https://github.com/caddyserver/caddy/releases/download/v${VERSION}/${FILE_NAME}" + fi + + + echo "cd $serverPath/source/caddy/caddy && tar -zxvf ${caddyDir}/$FILE_NAME" + + mkdir -p cd $serverPath/source/caddy/caddy + cd $serverPath/source/caddy/caddy && tar -zxvf ${caddyDir}/$FILE_NAME + if [ "$OSNAME" == "mac" ];then + xattr -cr caddy + fi + + if [ ! -f $serverPath/caddy/bin ];then + mkdir -p $serverPath/caddy/bin + mv $serverPath/source/caddy/caddy/* $serverPath/caddy/bin + chmod +x $serverPath/caddy/bin/caddy + fi + + echo 'Installation of caddy completed' +} + +Uninstall_App() +{ + echo 'Uninstalling caddy completed' +} + +action=$1 +if [ "${1}" == "install" ];then + Install_App +elif [ "${1}" == "upgrade" ];then + Install_App +else + Uninstall_App +fi diff --git a/plugins/clean/index.py b/plugins/clean/index.py index d712d1078..2ddbdf30e 100755 --- a/plugins/clean/index.py +++ b/plugins/clean/index.py @@ -160,6 +160,7 @@ def initConf(): "/www/server/php/85/var/log", "/www/server/openresty/nginx/logs", "/www/server/phpmyadmin", + "/www/server/apache/httpd/logs", "/www/server/redis/data", "/www/server/alist/data/log", "/www/server/dztasks/logs", diff --git a/plugins/haproxy/info.json b/plugins/haproxy/info.json index 98700f813..2bdc07622 100755 --- a/plugins/haproxy/info.json +++ b/plugins/haproxy/info.json @@ -4,7 +4,7 @@ "name": "haproxy", "title": "haproxy", "shell": "install.sh", - "versions":["2.6"], + "versions":["2.6","2.8","3.0","3.2"], "updates":["2.6"], "tip": "soft", "checks": "server/haproxy", diff --git a/plugins/haproxy/tpl/tcp.tpl b/plugins/haproxy/tpl/tcp.tpl new file mode 100644 index 000000000..91600d3c9 --- /dev/null +++ b/plugins/haproxy/tpl/tcp.tpl @@ -0,0 +1,37 @@ +global + daemon + pidfile /tmp/haproxy.pid + maxconn 4000 + user haproxy + group haproxy + + +defaults + mode tcp + log local local0 + option tcplog + timeout connect 10s + timeout client 15s + timeout server 15s + + +listen stats + mode http + bind *:10800 + stats enable + stats refresh 10 + stats uri /haproxy + stats realm Haproxy\ Statistics + stats auth {$HA_USER}:{$HA_PWD} + + +frontend tcp_frontend + bind *:8090 + mode tcp + default_backend tcp_backend + +backend tcp_backend + mode tcp + server tcp1 192.168.1.100:8090 check + + diff --git a/plugins/haproxy/versions/2.8/install.sh b/plugins/haproxy/versions/2.8/install.sh new file mode 100755 index 000000000..f6e527064 --- /dev/null +++ b/plugins/haproxy/versions/2.8/install.sh @@ -0,0 +1,101 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") +sysName=`uname` + +bash ${rootPath}/scripts/getos.sh +OSNAME=`cat ${rootPath}/data/osname.pl` +OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'` + + +VERSION=2.8.20 +MIN_VERSION=2.8 +Install_App() +{ + echo '正在安装Haproxy软件...' + mkdir -p $serverPath/haproxy + + APP_DIR=${serverPath}/source/haproxy + mkdir -p $APP_DIR + echo $MIN_VERSION > $serverPath/haproxy/version.pl + + LOCAL_ADDR=common + cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"") + if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then + LOCAL_ADDR=cn + fi + + + if [ "${LOCAL_ADDR}" == "cn" ];then + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://dl.midoks.icu/soft/haproxy/haproxy-${VERSION}.tar.gz + fi + fi + + + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + if [ $sysName == 'Darwin' ]; then + wget --no-check-certificate -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + else + curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + fi + fi + + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + fi + + + cd ${APP_DIR} && tar -zxvf haproxy-${VERSION}.tar.gz + + if [ "$OSNAME" == "macos" ];then + cd ${APP_DIR}/haproxy-${VERSION} && make TARGET=osx && make install PREFIX=$serverPath/haproxy + else + cd ${APP_DIR}/haproxy-${VERSION} && make TARGET=linux-glibc && make install PREFIX=$serverPath/haproxy + fi + + echo '安装Haproxy成功' + + #Haproxy日志配置 + if [ -f /etc/rsyslog.conf ];then + find_ha=`cat /etc/rsyslog.conf | grep haproxy` + if [ "$find_ha" != "" ];then + echo $find_ha + else + echo "---------------------------------------------" + echo "" > ${serverPath}/haproxy/haproxy.log + echo "local0.* ${serverPath}/haproxy/haproxy.log" >> /etc/rsyslog.conf + systemctl restart syslog + echo "syslog默认的haproxy配置" + echo "local0.* ${serverPath}/haproxy/haproxy.log >> /etc/rsyslog.conf" + echo "---------------------------------------------" + fi + fi + + #删除解压源码 + if [ -d ${APP_DIR}/haproxy-${VERSION} ];then + rm -rf ${APP_DIR}/haproxy-${VERSION} + fi +} + +Uninstall_App() +{ + if [ -f $serverPath/haproxy/initd/haproxy ];then + $serverPath/haproxy/initd/haproxy stop + fi + + rm -rf $serverPath/haproxy + echo "卸载Haproxy成功" +} + +action=$1 +if [ "${1}" == 'install' ];then + Install_App +else + Uninstall_App +fi diff --git a/plugins/haproxy/versions/3.0/install.sh b/plugins/haproxy/versions/3.0/install.sh new file mode 100755 index 000000000..0e586755f --- /dev/null +++ b/plugins/haproxy/versions/3.0/install.sh @@ -0,0 +1,101 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") +sysName=`uname` + +bash ${rootPath}/scripts/getos.sh +OSNAME=`cat ${rootPath}/data/osname.pl` +OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'` + + +VERSION=3.0.19 +MIN_VERSION=3.0 +Install_App() +{ + echo '正在安装Haproxy软件...' + mkdir -p $serverPath/haproxy + + APP_DIR=${serverPath}/source/haproxy + mkdir -p $APP_DIR + echo $MIN_VERSION > $serverPath/haproxy/version.pl + + LOCAL_ADDR=common + cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"") + if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then + LOCAL_ADDR=cn + fi + + + if [ "${LOCAL_ADDR}" == "cn" ];then + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://dl.midoks.icu/soft/haproxy/haproxy-${VERSION}.tar.gz + fi + fi + + + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + if [ $sysName == 'Darwin' ]; then + wget --no-check-certificate -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + else + curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + fi + fi + + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + fi + + + cd ${APP_DIR} && tar -zxvf haproxy-${VERSION}.tar.gz + + if [ "$OSNAME" == "macos" ];then + cd ${APP_DIR}/haproxy-${VERSION} && make TARGET=osx && make install PREFIX=$serverPath/haproxy + else + cd ${APP_DIR}/haproxy-${VERSION} && make TARGET=linux-glibc && make install PREFIX=$serverPath/haproxy + fi + + echo '安装Haproxy成功' + + #Haproxy日志配置 + if [ -f /etc/rsyslog.conf ];then + find_ha=`cat /etc/rsyslog.conf | grep haproxy` + if [ "$find_ha" != "" ];then + echo $find_ha + else + echo "---------------------------------------------" + echo "" > ${serverPath}/haproxy/haproxy.log + echo "local0.* ${serverPath}/haproxy/haproxy.log" >> /etc/rsyslog.conf + systemctl restart syslog + echo "syslog默认的haproxy配置" + echo "local0.* ${serverPath}/haproxy/haproxy.log >> /etc/rsyslog.conf" + echo "---------------------------------------------" + fi + fi + + #删除解压源码 + if [ -d ${APP_DIR}/haproxy-${VERSION} ];then + rm -rf ${APP_DIR}/haproxy-${VERSION} + fi +} + +Uninstall_App() +{ + if [ -f $serverPath/haproxy/initd/haproxy ];then + $serverPath/haproxy/initd/haproxy stop + fi + + rm -rf $serverPath/haproxy + echo "卸载Haproxy成功" +} + +action=$1 +if [ "${1}" == 'install' ];then + Install_App +else + Uninstall_App +fi diff --git a/plugins/haproxy/versions/3.2/install.sh b/plugins/haproxy/versions/3.2/install.sh new file mode 100755 index 000000000..ef20c4167 --- /dev/null +++ b/plugins/haproxy/versions/3.2/install.sh @@ -0,0 +1,101 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") +sysName=`uname` + +bash ${rootPath}/scripts/getos.sh +OSNAME=`cat ${rootPath}/data/osname.pl` +OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'` + + +VERSION=3.2.15 +MIN_VERSION=3.2 +Install_App() +{ + echo '正在安装Haproxy软件...' + mkdir -p $serverPath/haproxy + + APP_DIR=${serverPath}/source/haproxy + mkdir -p $APP_DIR + echo $MIN_VERSION > $serverPath/haproxy/version.pl + + LOCAL_ADDR=common + cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"") + if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then + LOCAL_ADDR=cn + fi + + + if [ "${LOCAL_ADDR}" == "cn" ];then + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://dl.midoks.icu/soft/haproxy/haproxy-${VERSION}.tar.gz + fi + fi + + + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + if [ $sysName == 'Darwin' ]; then + wget --no-check-certificate -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + else + curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + fi + fi + + if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then + curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz + fi + + + cd ${APP_DIR} && tar -zxvf haproxy-${VERSION}.tar.gz + + if [ "$OSNAME" == "macos" ];then + cd ${APP_DIR}/haproxy-${VERSION} && make TARGET=osx && make install PREFIX=$serverPath/haproxy + else + cd ${APP_DIR}/haproxy-${VERSION} && make TARGET=linux-glibc && make install PREFIX=$serverPath/haproxy + fi + + echo '安装Haproxy成功' + + #Haproxy日志配置 + if [ -f /etc/rsyslog.conf ];then + find_ha=`cat /etc/rsyslog.conf | grep haproxy` + if [ "$find_ha" != "" ];then + echo $find_ha + else + echo "---------------------------------------------" + echo "" > ${serverPath}/haproxy/haproxy.log + echo "local0.* ${serverPath}/haproxy/haproxy.log" >> /etc/rsyslog.conf + systemctl restart syslog + echo "syslog默认的haproxy配置" + echo "local0.* ${serverPath}/haproxy/haproxy.log >> /etc/rsyslog.conf" + echo "---------------------------------------------" + fi + fi + + #删除解压源码 + if [ -d ${APP_DIR}/haproxy-${VERSION} ];then + rm -rf ${APP_DIR}/haproxy-${VERSION} + fi +} + +Uninstall_App() +{ + if [ -f $serverPath/haproxy/initd/haproxy ];then + $serverPath/haproxy/initd/haproxy stop + fi + + rm -rf $serverPath/haproxy + echo "卸载Haproxy成功" +} + +action=$1 +if [ "${1}" == 'install' ];then + Install_App +else + Uninstall_App +fi diff --git a/plugins/lvs/readme.md b/plugins/lvs/readme.md index 29ef5bd64..0254d7ef9 100644 --- a/plugins/lvs/readme.md +++ b/plugins/lvs/readme.md @@ -7,10 +7,15 @@ ifconfig ens256 172.16.204.100 netmask 255.255.255.255 broadcast 192.168.212.100 route add -host 172.16.204.100 dev ens256 - ipvsadm -A -t 172.16.204.100:80 -s rr ipvsadm -a -t 172.16.204.100:80 -r 172.16.204.129:80 -m +跨机房 +ipvsadm -A -t 154.21.1.1:8016 -s wlc +ipvsadm -a -t 154.21.1.1:8016 -r 103.39.78.2 -i +源 +ifconfig tunl0 154.21.1.1 netmask 255.255.255.255 up + # 清空LVS规则 ipvsadm -C diff --git a/plugins/openresty/install.sh b/plugins/openresty/install.sh index 722242d57..f4167b951 100755 --- a/plugins/openresty/install.sh +++ b/plugins/openresty/install.sh @@ -12,7 +12,7 @@ export PATH # curl --http3 -v https://www.xxx.com # apt install ncat -y -# nc -u -v www.xxmhaa.com 443 +# nc -u -v www.xx.com 443 # cd /www/server/mdserver-web && python3 plugins/openresty/index.py run_info diff --git a/plugins/openresty/versions/1.29.2/install.sh b/plugins/openresty/versions/1.29.2/install.sh index bdfb1f969..3542b6b4c 100644 --- a/plugins/openresty/versions/1.29.2/install.sh +++ b/plugins/openresty/versions/1.29.2/install.sh @@ -132,11 +132,11 @@ Install_openresty() fi # br - if [ ! -d ${openrestyDir}/openresty-${VERSION}/ngx_brotli ];then - cd ${openrestyDir}/openresty-${VERSION} && git clone https://github.com/wxx9248/ngx_brotli.git - cd ${openrestyDir}/openresty-${VERSION}/ngx_brotli && git submodule update --init + if [ ! -d ${openrestyDir}/ngx_brotli ];then + cd ${openrestyDir} && git clone https://github.com/wxx9248/ngx_brotli.git + cd ${openrestyDir}/ngx_brotli && git submodule update --init - OPTIONS="${OPTIONS} --add-module=${openrestyDir}/openresty-${VERSION}/ngx_brotli" + OPTIONS="${OPTIONS} --add-module=${openrestyDir}/ngx_brotli" fi OPTIONS="${OPTIONS} --with-threads" diff --git a/scripts/init.d/mw.tpl b/scripts/init.d/mw.tpl index bf11e6b71..1b6331151 100755 --- a/scripts/init.d/mw.tpl +++ b/scripts/init.d/mw.tpl @@ -48,11 +48,13 @@ mw_start_panel() cd ${PANEL_DIR}/web && gunicorn -c setting.py app:app port=$(cat ${PANEL_DIR}/data/port.pl) isStart="" + n=0 while [[ "$isStart" == "" ]]; do echo -e ".\c" sleep 0.5 - isStart=$(lsof -n -P -i:$port|grep LISTEN|grep -v grep|awk '{print $2}'|xargs) + # isStart=$(lsof -n -P -i:$port|grep LISTEN|grep -v grep|awk '{print $2}'|xargs) + isStart=$(ss -tulnp | grep ":$port" |grep LISTEN|grep -v grep|awk '{print $2}'|xargs) if [[ "$isStart" == "" ]];then isStart=$(ps -ef|grep python3|grep mdserver-web|grep app:app|awk '{print $2}'|xargs) fi @@ -132,7 +134,7 @@ mw_stop_task() mw_stop_panel() { echo -e "stopping mw-panel... \c"; - pidfile=${PANEL_DIR}/logs/mw.pid + pidfile=${PANEL_DIR}/logs/panel.pid if [ -f $pidfile ];then pid=`cat $pidfile` kill -9 $pid > /dev/null 2>&1 @@ -759,13 +761,19 @@ case "$1" in 'reload') mw_reload;; 'restart') mw_stop - mw_start;; + sleep 2 + mw_start + mw_default;; 'restart_panel') mw_stop_panel - mw_start_panel;; + sleep 2 + mw_start_panel + mw_default;; 'restart_task') - mw_stop_task - mw_start_task;; + mw_stop_task + sleep 2 + mw_start_task + mw_default;; 'status') mw_status;; 'logs') error_logs;; 'close') mw_close;; diff --git a/scripts/install/alma.sh b/scripts/install/alma.sh index 0b89004ce..02b3030b5 100755 --- a/scripts/install/alma.sh +++ b/scripts/install/alma.sh @@ -22,6 +22,7 @@ yum install -y numactl yum install -y sshpass yum install -y libzstd-devel yum install -y postgresql-devel +yum install -y brotli-devel SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'` if [ "$SSH_PORT" == "" ];then diff --git a/scripts/install/amazon.sh b/scripts/install/amazon.sh index a16134e47..2b420026a 100755 --- a/scripts/install/amazon.sh +++ b/scripts/install/amazon.sh @@ -29,6 +29,7 @@ yum install -y ncurses-compat-libs yum install -y numactl yum install -y sshpass yum install -y libzstd-devel +yum install -y brotli-devel SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'` if [ "$SSH_PORT" == "" ];then diff --git a/scripts/install/centos.sh b/scripts/install/centos.sh index 59ed47040..0165d647f 100755 --- a/scripts/install/centos.sh +++ b/scripts/install/centos.sh @@ -40,6 +40,7 @@ yum install -y numactl yum install -y sshpass yum install -y libzstd-devel yum install -y postgresql-devel +yum install -y brotli-devel # if [ -f /usr/sbin/iptables ];then diff --git a/scripts/install/debian.sh b/scripts/install/debian.sh index 9d773b754..f652f62f5 100644 --- a/scripts/install/debian.sh +++ b/scripts/install/debian.sh @@ -94,6 +94,7 @@ apt install -y apache2-utils apt install -y numactl apt install -y xxd apt install -y sshpass +apt install -y libbrotli P_VER=`python3 -V | awk '{print $2}'` if version_ge "$P_VER" "3.11.0" ;then diff --git a/scripts/install/euler.sh b/scripts/install/euler.sh index 19720f9c6..44d6fd9f2 100755 --- a/scripts/install/euler.sh +++ b/scripts/install/euler.sh @@ -40,6 +40,7 @@ yum install -y numactl yum install -y sshpass yum install -y libzstd-devel yum install -y postgresql-devel +yum install -y brotli-devel # if [ -f /usr/sbin/iptables ];then diff --git a/scripts/install/fedora.sh b/scripts/install/fedora.sh index c64576c8d..ff402b15b 100644 --- a/scripts/install/fedora.sh +++ b/scripts/install/fedora.sh @@ -20,6 +20,7 @@ yum install -y numactl yum install -y sshpass yum install -y libzstd-devel yum install -y postgresql-devel +yum install -y brotli-devel dnf install crontabs -y SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'` diff --git a/scripts/install/freebsd.sh b/scripts/install/freebsd.sh index 09d1624c2..8cc92d3d2 100644 --- a/scripts/install/freebsd.sh +++ b/scripts/install/freebsd.sh @@ -67,7 +67,7 @@ pkg install -y bzip2-devel pkg install -y numactl pkg install -y sshpass pkg install -y libzstd-devel - +pkg install -y brotli-devel # curl https://sh.rustup.rs -sSf | sh pkg install -y rust diff --git a/scripts/install/opensuse.sh b/scripts/install/opensuse.sh index d1190256c..e1196cf8a 100644 --- a/scripts/install/opensuse.sh +++ b/scripts/install/opensuse.sh @@ -61,6 +61,7 @@ zypper install -y libargon2-devel zypper install -y net-tools-deprecated zypper install -y numactl zypper install -y sshpass +zypper install -y brotli-devel # zypper install -y php-config diff --git a/scripts/install/rhel.sh b/scripts/install/rhel.sh index a85c60b8a..a1721e579 100644 --- a/scripts/install/rhel.sh +++ b/scripts/install/rhel.sh @@ -46,6 +46,7 @@ $PKGMGR install -y libncurses* $PKGMGR install -y sshpass $PKGMGR install -y libzstd-devel $PKGMGR install -y postgresql-devel +$PKGMGR install -y brotli-devel echo "install remi source" if [ "$VERSION_ID" == "9" ];then diff --git a/scripts/install/rocky.sh b/scripts/install/rocky.sh index 01ad38d1d..29d19df63 100644 --- a/scripts/install/rocky.sh +++ b/scripts/install/rocky.sh @@ -30,6 +30,7 @@ yum install -y numactl yum install -y sshpass yum install -y libzstd-devel yum install -y postgresql-devel +yum install -y brotli-devel if [ -f /usr/sbin/iptables ];then diff --git a/scripts/install/ubuntu.sh b/scripts/install/ubuntu.sh index 3f1b0c436..37b415b98 100644 --- a/scripts/install/ubuntu.sh +++ b/scripts/install/ubuntu.sh @@ -61,6 +61,7 @@ apt install -y liblz4-tool apt install -y zstd apt install -y sshpass apt install -y libzstd-dev +apt install -y libbrotli P_VER=`python3 -V | awk '{print $2}'` if version_ge "$P_VER" "3.11.0" ;then diff --git a/version/r3.8.txt b/version/r3.8.txt new file mode 100644 index 000000000..0863401ee --- /dev/null +++ b/version/r3.8.txt @@ -0,0 +1,39 @@ +cryptography==36.0.1 +flask==2.0.3 +pyOpenSSL==22.0.0 +requests==2.27.1 +gevent==22.10.2 +gunicorn==21.2.0 +setuptools>=33.1.1 +Werkzeug>=1.0.1,<3.0.0 +wheel>=0.37.1 +requests>=2.27.1 +urllib3>=1.21.1 +flask-session==0.3.2 +flask-helper==0.19 +flask-bcrypt==1.0.1 +flask-caching>=1.10.1 +cache==1.0.3 +gevent-websocket==0.10.1 +psutil==5.9.1 +chardet==3.0.4 +flask-sqlalchemy==2.3.2 +configparser==5.2.0 +python-engineio==4.3.2 +python-socketio>=4.2.0 +flask-socketio==5.2.0 +flask-sockets==0.2.1 +zmq==0.0.0 +paramiko>=2.8.0 +pymongo +pymemcache +redis +pillow +Jinja2>=2.11.2 +PyMySQL==1.0.2 +whitenoise==5.3.0 +pyotp +pytz +pyTelegramBotAPI +telebot +pyyaml \ No newline at end of file diff --git a/version/r3.9.txt b/version/r3.9.txt new file mode 100644 index 000000000..0863401ee --- /dev/null +++ b/version/r3.9.txt @@ -0,0 +1,39 @@ +cryptography==36.0.1 +flask==2.0.3 +pyOpenSSL==22.0.0 +requests==2.27.1 +gevent==22.10.2 +gunicorn==21.2.0 +setuptools>=33.1.1 +Werkzeug>=1.0.1,<3.0.0 +wheel>=0.37.1 +requests>=2.27.1 +urllib3>=1.21.1 +flask-session==0.3.2 +flask-helper==0.19 +flask-bcrypt==1.0.1 +flask-caching>=1.10.1 +cache==1.0.3 +gevent-websocket==0.10.1 +psutil==5.9.1 +chardet==3.0.4 +flask-sqlalchemy==2.3.2 +configparser==5.2.0 +python-engineio==4.3.2 +python-socketio>=4.2.0 +flask-socketio==5.2.0 +flask-sockets==0.2.1 +zmq==0.0.0 +paramiko>=2.8.0 +pymongo +pymemcache +redis +pillow +Jinja2>=2.11.2 +PyMySQL==1.0.2 +whitenoise==5.3.0 +pyotp +pytz +pyTelegramBotAPI +telebot +pyyaml \ No newline at end of file diff --git a/web/core/mw.py b/web/core/mw.py index f588db225..e208b9797 100644 --- a/web/core/mw.py +++ b/web/core/mw.py @@ -1463,7 +1463,19 @@ def checkWebConfig(): result = execShell(cmd) searchStr = 'test is successful' if result[1].find(searchStr) == -1: - msg = getInfo('配置文件错误: {1}', (result[1],)) + msg = getInfo('配置文件错误[openresty]: {1}', (result[1],)) + writeLog("软件管理", msg) + return result[1] + return True + +def checkHttpdConfig(): + op_dir = getServerDir() + '/apache/httpd' + # "ulimit -n 10240 && " + + cmd = op_dir + "/bin/httpd -t" + result = execShell(cmd) + searchStr = 'Syntax OK' + if result[1].find(searchStr) == -1: + msg = getInfo('配置文件错误[httpd]: {1}', (result[1],)) writeLog("软件管理", msg) return result[1] return True