InPanel 1.2.6__tar.gz → 1.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/PKG-INFO +1 -1
- {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/SOURCES.txt +29 -3
- {inpanel-1.2.6 → inpanel-1.2.7}/PKG-INFO +1 -1
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/app.py +2 -1
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/base.py +14 -8
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/config.py +1 -1
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/filelock.py +1 -1
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/pxssh.py +2 -2
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/acme.py +16 -18
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/aliyuncs.py +3 -4
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/apt.py +35 -35
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/brew.py +46 -46
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/certificate.py +7 -7
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/config.py +3 -3
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/cron.py +7 -7
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/disk.py +19 -22
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/dnf.py +25 -25
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/docker_source.py +30 -30
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/file.py +443 -154
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/ftp.py +19 -19
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/httpd.py +10 -10
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/login.py +7 -8
- inpanel-1.2.7/inpanel/mod/logs.py +840 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/mysql.py +68 -69
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/nginx.py +2326 -2326
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/php.py +7 -7
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/pip.py +13 -13
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/process.py +3 -3
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/query.py +4 -4
- inpanel-1.2.7/inpanel/mod/redis.py +518 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/remote.py +10 -10
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/server.py +92 -97
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/service.py +1 -1
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/setting.py +3 -3
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/ssh.py +324 -324
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/task.py +2 -1
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/user.py +5 -5
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/yum.py +50 -50
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/css/global.css +5 -14
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/index.html +6 -2
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/controllers.js +0 -9
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/database.js +258 -12
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/file.js +139 -42
- inpanel-1.2.7/inpanel/public/js/controllers/logs.js +291 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/utils.js +182 -23
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/core.js +247 -246
- inpanel-1.2.7/inpanel/public/lib/codemirror/addon/edit/matchbrackets.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/addon/search/match-highlighter.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/addon/selection/active-line.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/codemirror.min.css +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/codemirror.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/css/css.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/diff/diff.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/dockerfile/dockerfile.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/go/go.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/htmlmixed/htmlmixed.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/javascript/javascript.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/lua/lua.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/markdown/markdown.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/nginx/nginx.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/perl/perl.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/php/php.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/properties/properties.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/python/python.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/ruby/ruby.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/rust/rust.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/shell/shell.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/sql/sql.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/toml/toml.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/xml/xml.min.js +1 -0
- inpanel-1.2.7/inpanel/public/lib/codemirror/mode/yaml/yaml.min.js +1 -0
- inpanel-1.2.7/inpanel/public/partials/database/index.html +401 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/file/trash.html +4 -2
- inpanel-1.2.7/inpanel/public/partials/logs.html +442 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/index.html +20 -20
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/sources.html +181 -126
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/templates/index.html +6 -2
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/utils.py +9 -10
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/web.py +65 -40
- {inpanel-1.2.6 → inpanel-1.2.7}/pyproject.toml +1 -1
- inpanel-1.2.6/inpanel/public/lib/codemirror/codemirror-compressed.js +0 -1
- inpanel-1.2.6/inpanel/public/lib/codemirror/codemirror.css +0 -173
- inpanel-1.2.6/inpanel/public/partials/database/index.html +0 -172
- inpanel-1.2.6/inpanel/public/partials/log.html +0 -83
- {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/dependency_links.txt +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/entry_points.txt +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/requires.txt +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/InPanel.egg-info/top_level.txt +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/LICENSE +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/MANIFEST.in +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/README.md +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/__init__.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/__init__.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/async_process.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/magic.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/lib/pyDes.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/__init__.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/docker.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_base.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_firewalld.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_iptables.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_macos.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/firewall_ufw.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/lighttpd.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/named.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_apt.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_base.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_brew.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_dnf.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_map.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/package_yum.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/plugins.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/proftpd.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/pureftpd.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/service_manager.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/shell.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/system.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/mod/vsftpd.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/plugin.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/favicon.ico +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/images/alipay.jpg +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/images/loading.gif +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/images/weixin.jpg +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/container.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/ecs.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/plugins.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/service.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/controllers/site.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/directives.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/filters.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/js/services.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/angular/1.0.2/angular-resource.min.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/angular/1.0.2/angular.min.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/angular/1.0.8/angular.min.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap-theme.css +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap-theme.css.map +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css.map +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap.css +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap.css.map +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap.min.css +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/css/bootstrap.min.css.map +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.svg +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/img/glyphicons-halflings.png +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/js/bootstrap.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/js/bootstrap.min.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/bootstrap/js/npm.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/jquery/jquery-1.12.4.min.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/md5/md5.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/lib/md5/md5.min.js +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/message.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/navbar.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/selector.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvbase.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvext.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvfile.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvinstall.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvlog.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvminiop.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvuninstall.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/directives/srvupdate.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/container/index.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/database/mysql/dbedit.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/database/mysql/dbnew.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/database/mysql/useredit.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/database/mysql/usernew.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ecs/account.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ecs/ecs.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ecs/index.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ecs/setings.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/file/file.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/ftp.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/login.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/logout.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/main.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/plugins/config.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/plugins/detail.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/plugins/index.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/plugins/info.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/secure.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/apache.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/cron.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/fail2ban.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/firewalld.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/index.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/iptables.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/java11.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/java17.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/java21.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/java8.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/lighttpd.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/mariadb.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/memcache.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/minio.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/mongodb.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/mysql.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/named.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nginx.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nodejs18.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nodejs20.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nodejs22.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/nodejs24.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/ntp.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php56.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php74.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php80.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php81.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php82.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php83.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/php84.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/proftpd.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/pureftpd.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/redis.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/samba.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/sendmail.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/ssh.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/tomcat.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/ufw.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/service/vsftpd.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/setting.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/site/apache/site.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/site/index.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/site/nginx/site.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/sorry.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/autofm.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/backup.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/index.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/migrate.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/movedata.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/storage/remote.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/cron.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/firewall.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/network.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/process.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/shell.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/ssl.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/task.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/time.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/partials/utils/user.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/robots.txt +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/public/templates/file/preview.html +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/__init__.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/__init__.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/_common.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/categories.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/database.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/ftp.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/http.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/java.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/mail.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/nodejs.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/php.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/security.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/storage.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/services/system.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/__init__.py +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/apt.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/brew.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/dnf.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/docker.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/package_map.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/pip.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/third_party.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/inpanel/templates/sources/yum.json +0 -0
- {inpanel-1.2.6 → inpanel-1.2.7}/setup.cfg +0 -0
|
@@ -44,6 +44,7 @@ inpanel/mod/ftp.py
|
|
|
44
44
|
inpanel/mod/httpd.py
|
|
45
45
|
inpanel/mod/lighttpd.py
|
|
46
46
|
inpanel/mod/login.py
|
|
47
|
+
inpanel/mod/logs.py
|
|
47
48
|
inpanel/mod/mysql.py
|
|
48
49
|
inpanel/mod/named.py
|
|
49
50
|
inpanel/mod/nginx.py
|
|
@@ -61,6 +62,7 @@ inpanel/mod/process.py
|
|
|
61
62
|
inpanel/mod/proftpd.py
|
|
62
63
|
inpanel/mod/pureftpd.py
|
|
63
64
|
inpanel/mod/query.py
|
|
65
|
+
inpanel/mod/redis.py
|
|
64
66
|
inpanel/mod/remote.py
|
|
65
67
|
inpanel/mod/server.py
|
|
66
68
|
inpanel/mod/service.py
|
|
@@ -89,6 +91,7 @@ inpanel/public/js/controllers/controllers.js
|
|
|
89
91
|
inpanel/public/js/controllers/database.js
|
|
90
92
|
inpanel/public/js/controllers/ecs.js
|
|
91
93
|
inpanel/public/js/controllers/file.js
|
|
94
|
+
inpanel/public/js/controllers/logs.js
|
|
92
95
|
inpanel/public/js/controllers/plugins.js
|
|
93
96
|
inpanel/public/js/controllers/service.js
|
|
94
97
|
inpanel/public/js/controllers/site.js
|
|
@@ -114,15 +117,38 @@ inpanel/public/lib/bootstrap/img/glyphicons-halflings.png
|
|
|
114
117
|
inpanel/public/lib/bootstrap/js/bootstrap.js
|
|
115
118
|
inpanel/public/lib/bootstrap/js/bootstrap.min.js
|
|
116
119
|
inpanel/public/lib/bootstrap/js/npm.js
|
|
117
|
-
inpanel/public/lib/codemirror/codemirror
|
|
118
|
-
inpanel/public/lib/codemirror/codemirror.
|
|
120
|
+
inpanel/public/lib/codemirror/codemirror.min.css
|
|
121
|
+
inpanel/public/lib/codemirror/codemirror.min.js
|
|
122
|
+
inpanel/public/lib/codemirror/addon/edit/matchbrackets.min.js
|
|
123
|
+
inpanel/public/lib/codemirror/addon/search/match-highlighter.min.js
|
|
124
|
+
inpanel/public/lib/codemirror/addon/selection/active-line.min.js
|
|
125
|
+
inpanel/public/lib/codemirror/mode/css/css.min.js
|
|
126
|
+
inpanel/public/lib/codemirror/mode/diff/diff.min.js
|
|
127
|
+
inpanel/public/lib/codemirror/mode/dockerfile/dockerfile.min.js
|
|
128
|
+
inpanel/public/lib/codemirror/mode/go/go.min.js
|
|
129
|
+
inpanel/public/lib/codemirror/mode/htmlmixed/htmlmixed.min.js
|
|
130
|
+
inpanel/public/lib/codemirror/mode/javascript/javascript.min.js
|
|
131
|
+
inpanel/public/lib/codemirror/mode/lua/lua.min.js
|
|
132
|
+
inpanel/public/lib/codemirror/mode/markdown/markdown.min.js
|
|
133
|
+
inpanel/public/lib/codemirror/mode/nginx/nginx.min.js
|
|
134
|
+
inpanel/public/lib/codemirror/mode/perl/perl.min.js
|
|
135
|
+
inpanel/public/lib/codemirror/mode/php/php.min.js
|
|
136
|
+
inpanel/public/lib/codemirror/mode/properties/properties.min.js
|
|
137
|
+
inpanel/public/lib/codemirror/mode/python/python.min.js
|
|
138
|
+
inpanel/public/lib/codemirror/mode/ruby/ruby.min.js
|
|
139
|
+
inpanel/public/lib/codemirror/mode/rust/rust.min.js
|
|
140
|
+
inpanel/public/lib/codemirror/mode/shell/shell.min.js
|
|
141
|
+
inpanel/public/lib/codemirror/mode/sql/sql.min.js
|
|
142
|
+
inpanel/public/lib/codemirror/mode/toml/toml.min.js
|
|
143
|
+
inpanel/public/lib/codemirror/mode/xml/xml.min.js
|
|
144
|
+
inpanel/public/lib/codemirror/mode/yaml/yaml.min.js
|
|
119
145
|
inpanel/public/lib/jquery/jquery-1.12.4.min.js
|
|
120
146
|
inpanel/public/lib/md5/md5.js
|
|
121
147
|
inpanel/public/lib/md5/md5.min.js
|
|
122
148
|
inpanel/public/partials/ftp.html
|
|
123
|
-
inpanel/public/partials/log.html
|
|
124
149
|
inpanel/public/partials/login.html
|
|
125
150
|
inpanel/public/partials/logout.html
|
|
151
|
+
inpanel/public/partials/logs.html
|
|
126
152
|
inpanel/public/partials/main.html
|
|
127
153
|
inpanel/public/partials/secure.html
|
|
128
154
|
inpanel/public/partials/setting.html
|
|
@@ -125,7 +125,7 @@ def cmd_start():
|
|
|
125
125
|
force_https = config.getboolean('server', 'forcehttps')
|
|
126
126
|
print(f'InPanel: running on: http{"s" if force_https else ""}://*:{server_port}')
|
|
127
127
|
else:
|
|
128
|
-
print('InPanel: failed to start, check log file:
|
|
128
|
+
print(f'InPanel: failed to start, check log file: {logfile}')
|
|
129
129
|
sys.exit(1)
|
|
130
130
|
return
|
|
131
131
|
except OSError as e:
|
|
@@ -384,6 +384,7 @@ def run_server():
|
|
|
384
384
|
(r'/api/service/(.+?)(?:/(.+))?', web.ServiceHandler),
|
|
385
385
|
(r'/api/firewall/(.+)', web.FirewallHandler),
|
|
386
386
|
(r'/api/setting/(.+)', web.SettingHandler),
|
|
387
|
+
(r'/api/logs/(.+)', web.LogsHandler),
|
|
387
388
|
(r'/api/operation/(.+)', web.OperationHandler),
|
|
388
389
|
(r'/api/task/(.+)', web.TaskHandler),
|
|
389
390
|
(r'/api/sitepackage/(.+)', web.SitePackageHandler),
|
|
@@ -40,8 +40,8 @@ __author__ = 'Jackson Dou'
|
|
|
40
40
|
__license__ = 'BSD'
|
|
41
41
|
|
|
42
42
|
app_name = 'InPanel'
|
|
43
|
-
releasetime = '2026-07-
|
|
44
|
-
DEBUG =
|
|
43
|
+
releasetime = '2026-07-26'
|
|
44
|
+
DEBUG = False
|
|
45
45
|
COMMENTFLAG = '#INPANEL#'
|
|
46
46
|
GENBY = 'AUTOMATICALLY GENERATED BY INPANEL'
|
|
47
47
|
|
|
@@ -62,14 +62,15 @@ app_api = {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
execfile = '/usr/bin/inpanel'
|
|
65
|
-
data_path = '/var/lib/inpanel/'
|
|
66
65
|
config_path = '/etc/inpanel/'
|
|
66
|
+
data_path = '/var/lib/inpanel/'
|
|
67
|
+
logging_path = '/var/log/inpanel/'
|
|
67
68
|
config_file = '/etc/inpanel/config.ini'
|
|
68
69
|
lastfile_path = '/etc/inpanel/lastfile.ini'
|
|
69
70
|
bookmarks_path = '/etc/inpanel/bookmarks.ini'
|
|
70
71
|
upgrade_path = '/etc/inpanel/upgrade.ini'
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
files_log = '/var/log/inpanel/files.log'
|
|
73
|
+
filespath_log = '/var/log/inpanel/filespath.log'
|
|
73
74
|
logfile = '/var/log/inpanel/main.log'
|
|
74
75
|
logerror = '/var/log/inpanel/error.log'
|
|
75
76
|
pidfile = '/var/run/inpanel.pid'
|
|
@@ -83,7 +84,11 @@ if hasattr(sys, 'frozen') and hasattr(sys, '_MEIPASS'):
|
|
|
83
84
|
root_path = sys._MEIPASS
|
|
84
85
|
else:
|
|
85
86
|
package_dir = Path(__file__).parent.resolve()
|
|
87
|
+
is_develop_mode = False
|
|
86
88
|
if package_dir.parts[-2] == 'site-packages' or 'dist-packages' in str(package_dir):
|
|
89
|
+
if Path(__file__).is_symlink():
|
|
90
|
+
is_develop_mode = True
|
|
91
|
+
if not is_develop_mode and (package_dir.parts[-2] == 'site-packages' or 'dist-packages' in str(package_dir)):
|
|
87
92
|
run_type = 'system'
|
|
88
93
|
root_path = str(package_dir)
|
|
89
94
|
pkg_str = str(package_dir)
|
|
@@ -101,12 +106,13 @@ else:
|
|
|
101
106
|
execfile = str(Path(root_path) / 'app.py')
|
|
102
107
|
data_path = str(Path(root_path) / 'data')
|
|
103
108
|
config_path = str(Path(root_path) / 'data')
|
|
109
|
+
logging_path = str(Path(root_path) / 'data')
|
|
104
110
|
config_file = str(Path(root_path) / 'data' / 'config.ini')
|
|
105
111
|
lastfile_path = str(Path(root_path) / 'data' / 'lastfile.ini')
|
|
106
112
|
bookmarks_path = str(Path(root_path) / 'data' / 'bookmarks.ini')
|
|
107
113
|
upgrade_path = str(Path(root_path) / 'data' / 'upgrade.ini')
|
|
108
|
-
|
|
109
|
-
|
|
114
|
+
files_log = str(Path(root_path) / 'data' / 'files.log')
|
|
115
|
+
filespath_log = str(Path(root_path) / 'data' / 'filespath.log')
|
|
110
116
|
logfile = str(Path(root_path) / 'data' / 'main.log')
|
|
111
117
|
logerror = str(Path(root_path) / 'data' / 'error.log')
|
|
112
118
|
pidfile = str(Path(root_path) / 'data' / 'inpanel.pid')
|
|
@@ -199,7 +205,7 @@ __all__ = [
|
|
|
199
205
|
'releasetime', 'version_info', 'server_info', 'os_name', 'os_title',
|
|
200
206
|
'os_version', 'os_versint', 'os_platform', 'kernel_name', 'kernel_release',
|
|
201
207
|
'kernel_version', 'hostname', 'machine', 'lastfile_path', 'bookmarks_path', 'upgrade_path',
|
|
202
|
-
'
|
|
208
|
+
'files_log', 'filespath_log', 'logfile', 'logerror', 'pidfile', 'processor'
|
|
203
209
|
]
|
|
204
210
|
|
|
205
211
|
if __name__ == '__main__':
|
|
@@ -119,7 +119,7 @@ Examples:
|
|
|
119
119
|
key = md5(randstr().encode('utf-8')).hexdigest()
|
|
120
120
|
md5_password = md5(value.encode('utf-8')).hexdigest()
|
|
121
121
|
pwd = hmac_new(key.encode('utf-8'), md5_password.encode('utf-8'), md5).hexdigest()
|
|
122
|
-
value = '
|
|
122
|
+
value = f'{pwd}:{key}'
|
|
123
123
|
logger.info(f'Password hash generated, key length: {len(key)}, hash length: {len(pwd)}')
|
|
124
124
|
|
|
125
125
|
result = config.set(section, option, value)
|
|
@@ -21,7 +21,7 @@ class FileLock(object):
|
|
|
21
21
|
the maximum timeout and the delay between each attempt to lock.
|
|
22
22
|
"""
|
|
23
23
|
self.is_locked = False
|
|
24
|
-
self.lockfile = str(Path.cwd() / ("
|
|
24
|
+
self.lockfile = str(Path.cwd() / (f"{file_name}.lock"))
|
|
25
25
|
self.file_name = file_name
|
|
26
26
|
self.timeout = timeout
|
|
27
27
|
self.delay = delay
|
|
@@ -186,8 +186,8 @@ class pxssh (spawn):
|
|
|
186
186
|
if self.force_password:
|
|
187
187
|
ssh_options = ssh_options + ' ' + self.SSH_OPTS
|
|
188
188
|
if port is not None:
|
|
189
|
-
ssh_options = ssh_options + ' -p
|
|
190
|
-
cmd = "ssh
|
|
189
|
+
ssh_options = ssh_options + f' -p {port!s}'
|
|
190
|
+
cmd = f"ssh {ssh_options} -l {username} {server}"
|
|
191
191
|
|
|
192
192
|
# This does not distinguish between a remote server 'password' prompt
|
|
193
193
|
# and a local ssh 'passphrase' prompt (for unlocking a private key).
|
|
@@ -57,7 +57,7 @@ class ACME():
|
|
|
57
57
|
proc = Popen(cmd_list, stdin=stdin, stdout=PIPE, stderr=PIPE)
|
|
58
58
|
out, err = proc.communicate(cmd_input)
|
|
59
59
|
if proc.returncode != 0:
|
|
60
|
-
raise IOError("{
|
|
60
|
+
raise IOError(f"{err_msg}\n{err}")
|
|
61
61
|
return out
|
|
62
62
|
|
|
63
63
|
def _b64(self, b):
|
|
@@ -85,8 +85,7 @@ class ACME():
|
|
|
85
85
|
if depth < 100 and code == 400 and res_data['type'] == 'urn:ietf:params:acme:error:badNonce':
|
|
86
86
|
raise IndexError(res_data) # 允许对无效 nonce 重试 100 次
|
|
87
87
|
if code not in [200, 201, 204]:
|
|
88
|
-
raise ValueError("{
|
|
89
|
-
err_msg, url, data, code, res_data))
|
|
88
|
+
raise ValueError(f"{err_msg}:\nUrl: {url}\nData: {data}\nResponse Code: {code}\nResponse: {res_data}")
|
|
90
89
|
return res_data, code, headers
|
|
91
90
|
|
|
92
91
|
def _s_request(self, url, payload, err_msg, depth=0):
|
|
@@ -96,7 +95,7 @@ class ACME():
|
|
|
96
95
|
protected = {'url': url, 'alg': self.alg, "nonce": new_nonce}
|
|
97
96
|
protected.update({"jwk": self.jwk} if self.acct_headers is None else {"kid": self.acct_headers['Location']})
|
|
98
97
|
protected64 = self._b64(dumps(protected).encode('utf8'))
|
|
99
|
-
protected_input = "{
|
|
98
|
+
protected_input = f"{protected64}.{payload64}".encode('utf8')
|
|
100
99
|
cmd = ['openssl', 'dgst', '-sha256', '-sign', self.account_key]
|
|
101
100
|
out = self._cmd(cmd, stdin=PIPE, cmd_input=protected_input, err_msg='OpenSSL Error')
|
|
102
101
|
data = dumps({
|
|
@@ -146,8 +145,8 @@ class ACME():
|
|
|
146
145
|
out = self._cmd(cmd, err_msg='openssl error')
|
|
147
146
|
pub_pattern = r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)"
|
|
148
147
|
pub_hex, pub_exp = re.search(pub_pattern, out.decode('utf8'), re.MULTILINE | re.DOTALL).groups()
|
|
149
|
-
pub_exp = "{
|
|
150
|
-
pub_exp = "0{
|
|
148
|
+
pub_exp = f"{int(pub_exp):x}"
|
|
149
|
+
pub_exp = f"0{pub_exp}" if len(pub_exp) % 2 else pub_exp
|
|
151
150
|
self.jwk = {
|
|
152
151
|
'e': self._b64(unhexlify(pub_exp.encode('utf-8'))),
|
|
153
152
|
'kty': 'RSA',
|
|
@@ -182,7 +181,7 @@ class ACME():
|
|
|
182
181
|
# 查找域名
|
|
183
182
|
print('Domains CSR parsing...')
|
|
184
183
|
cmd = ['openssl', 'req', '-in', self.csr, '-noout', '-text']
|
|
185
|
-
out = self._cmd(cmd, err_msg="Error loading {
|
|
184
|
+
out = self._cmd(cmd, err_msg=f"Error loading {self.csr}")
|
|
186
185
|
domains = set([])
|
|
187
186
|
common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", out.decode('utf8'))
|
|
188
187
|
if common_name is not None:
|
|
@@ -193,7 +192,7 @@ class ACME():
|
|
|
193
192
|
for san in subject_alt_names.group(1).split(", "):
|
|
194
193
|
if san.startswith("DNS:"):
|
|
195
194
|
domains.add(san[4:])
|
|
196
|
-
print("Found domains: {
|
|
195
|
+
print(f"Found domains: {', '.join(domains)}")
|
|
197
196
|
# print('domains', domains)
|
|
198
197
|
if order == True:
|
|
199
198
|
self.create_new_order(domains)
|
|
@@ -213,32 +212,31 @@ class ACME():
|
|
|
213
212
|
for auth_url in order['authorizations']:
|
|
214
213
|
authorization, _, _ = self._request(auth_url, err_msg='Error getting challenges')
|
|
215
214
|
domain = authorization['identifier']['value']
|
|
216
|
-
print("Domain {
|
|
215
|
+
print(f"Domain {domain} Verifying...")
|
|
217
216
|
|
|
218
217
|
# 找到 http-01 挑战并写入挑战文件
|
|
219
218
|
challenge = [c for c in authorization['challenges'] if c['type'] == "http-01"][0]
|
|
220
219
|
token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token'])
|
|
221
|
-
key_auth = "{
|
|
220
|
+
key_auth = f"{token}.{self.thumbprint}"
|
|
222
221
|
wellknown_path = str(Path(self.acme_check_dir) / token)
|
|
223
222
|
with open(wellknown_path, 'w', encoding='utf-8') as f:
|
|
224
223
|
f.write(key_auth)
|
|
225
224
|
|
|
226
225
|
# 检查 wellknown 文件是否在指定位置
|
|
227
226
|
try:
|
|
228
|
-
wellknown_url = "http://{
|
|
227
|
+
wellknown_url = f"http://{domain}/.well-known/acme-challenge/{token}"
|
|
229
228
|
assert(disable_check or self._request(wellknown_url)[0] == key_auth)
|
|
230
229
|
except (AssertionError, ValueError) as e:
|
|
231
230
|
Path(wellknown_path).unlink()
|
|
232
|
-
raise ValueError("Wrote file to {
|
|
233
|
-
wellknown_path, wellknown_url, e))
|
|
231
|
+
raise ValueError(f"Wrote file to {wellknown_path}, but couldn't download {wellknown_url}: {e}")
|
|
234
232
|
|
|
235
233
|
# 告知挑战已完成
|
|
236
234
|
self._s_request(
|
|
237
|
-
challenge['url'], {}, "Error submitting challenges: {
|
|
238
|
-
authorization = self._poll_until_not(auth_url, ["pending"], "Error checking challenge status for {
|
|
235
|
+
challenge['url'], {}, f"Error submitting challenges: {domain}")
|
|
236
|
+
authorization = self._poll_until_not(auth_url, ["pending"], f"Error checking challenge status for {domain}")
|
|
239
237
|
if authorization['status'] != "valid":
|
|
240
|
-
raise ValueError("Challenge did not pass for {
|
|
241
|
-
print("Domain {
|
|
238
|
+
raise ValueError(f"Challenge did not pass for {domain}: {authorization}")
|
|
239
|
+
print(f"Domain {domain} verified!")
|
|
242
240
|
|
|
243
241
|
# 使用 CSR 完成订单
|
|
244
242
|
print('Certificate signing...')
|
|
@@ -247,7 +245,7 @@ class ACME():
|
|
|
247
245
|
# 轮询订单以监控其完成状态
|
|
248
246
|
order = self._poll_until_not(order_headers['Location'], ['pending', 'processing'], 'Error checking order status')
|
|
249
247
|
if order['status'] != 'valid':
|
|
250
|
-
raise ValueError("Order failed: {
|
|
248
|
+
raise ValueError(f"Order failed: {order}")
|
|
251
249
|
self.certificate = order['certificate']
|
|
252
250
|
|
|
253
251
|
def get_certificate(self, certificate=None):
|
|
@@ -32,8 +32,7 @@ class ECS(object):
|
|
|
32
32
|
def _sign(self, params):
|
|
33
33
|
paramstrings = []
|
|
34
34
|
for k, v in sorted(params.items()):
|
|
35
|
-
paramstrings.append('
|
|
36
|
-
(ECS._urlencode(k), ECS._urlencode(v)))
|
|
35
|
+
paramstrings.append(f'{ECS._urlencode(k)}={ECS._urlencode(v)}')
|
|
37
36
|
datastrings = [
|
|
38
37
|
ECS._urlencode('GET'),
|
|
39
38
|
ECS._urlencode('/'),
|
|
@@ -240,7 +239,7 @@ if __name__ == '__main__':
|
|
|
240
239
|
print()
|
|
241
240
|
|
|
242
241
|
for region in regions['Regions']:
|
|
243
|
-
print(
|
|
242
|
+
print(f"## Zones in {region['RegionCode']}\n")
|
|
244
243
|
zones = ecs.DescribeZones(region['RegionCode'])
|
|
245
244
|
if not zones[0]:
|
|
246
245
|
pp.pprint(zones)
|
|
@@ -250,7 +249,7 @@ if __name__ == '__main__':
|
|
|
250
249
|
print()
|
|
251
250
|
|
|
252
251
|
for zone in zones['Zones']:
|
|
253
|
-
print(
|
|
252
|
+
print(f"## Instances in {zone['ZoneCode']}\n")
|
|
254
253
|
instances = ecs.DescribeInstanceStatus(
|
|
255
254
|
region['RegionCode'], zone['ZoneCode'])[1]
|
|
256
255
|
pp.pprint(instances)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
'''APT 软件源管理模块
|
|
9
9
|
|
|
10
10
|
概念说明:
|
|
11
|
-
-
|
|
11
|
+
- 镜像站(mirror):基础发行版仓库的 URL 地址,切换本质是修改已有 .list 文件中 deb URL 的域名。
|
|
12
12
|
- 软件仓库(repo):完整的 .list 配置文件,可以添加自定义仓库来安装特定软件(如 PHP SURY、NodeSource)。
|
|
13
13
|
'''
|
|
14
14
|
|
|
@@ -102,13 +102,13 @@ def _extract_domain(url):
|
|
|
102
102
|
"""从 URL 中提取域名(scheme://host)"""
|
|
103
103
|
try:
|
|
104
104
|
p = urlparse(url)
|
|
105
|
-
return '
|
|
105
|
+
return f'{p.scheme}://{p.netloc}'
|
|
106
106
|
except Exception:
|
|
107
107
|
return url
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
def get_mirrors():
|
|
111
|
-
"""
|
|
111
|
+
"""获取镜像站列表"""
|
|
112
112
|
sources = _load_sources_config()
|
|
113
113
|
active_url = _get_active_url()
|
|
114
114
|
active_domain = _extract_domain(active_url) if active_url else ''
|
|
@@ -376,7 +376,7 @@ def refresh_cache():
|
|
|
376
376
|
status, output = getstatusoutput('apt update 2>&1')
|
|
377
377
|
if status == 0:
|
|
378
378
|
return {'code': 0, 'msg': 'apt 索引已更新!'}
|
|
379
|
-
return {'code': -1, 'msg': 'apt
|
|
379
|
+
return {'code': -1, 'msg': f'apt 索引更新失败:{output}'}
|
|
380
380
|
|
|
381
381
|
|
|
382
382
|
def get_repo_list():
|
|
@@ -436,10 +436,10 @@ def install_package(name):
|
|
|
436
436
|
return {'code': -1, 'msg': '软件名称不能为空!'}
|
|
437
437
|
if not is_installed():
|
|
438
438
|
return {'code': -1, 'msg': 'apt 未安装!'}
|
|
439
|
-
status, output = getstatusoutput('apt install -y
|
|
439
|
+
status, output = getstatusoutput(f'apt install -y {name} 2>&1')
|
|
440
440
|
if status == 0:
|
|
441
|
-
return {'code': 0, 'msg': '软件
|
|
442
|
-
return {'code': -1, 'msg': '软件
|
|
441
|
+
return {'code': 0, 'msg': f'软件 {name} 安装成功!', 'data': output}
|
|
442
|
+
return {'code': -1, 'msg': f'软件 {name} 安装失败:{output}'}
|
|
443
443
|
|
|
444
444
|
|
|
445
445
|
# ==================================================================
|
|
@@ -475,7 +475,7 @@ def web_handler(context, action):
|
|
|
475
475
|
elif action == 'install':
|
|
476
476
|
context.write(install_package(source))
|
|
477
477
|
|
|
478
|
-
# ---
|
|
478
|
+
# --- 镜像站管理 ---
|
|
479
479
|
elif action == 'mirrors':
|
|
480
480
|
context.write({'code': 0, 'msg': '', 'data': get_mirrors()})
|
|
481
481
|
|
|
@@ -495,11 +495,11 @@ def web_handler(context, action):
|
|
|
495
495
|
return
|
|
496
496
|
sources.append({'name': source_name, 'url': url, 'builtin': False})
|
|
497
497
|
_save_sources_config(sources)
|
|
498
|
-
context.write({'code': 0, 'msg': 'APT
|
|
498
|
+
context.write({'code': 0, 'msg': f'APT 镜像站已添加:{url}'})
|
|
499
499
|
|
|
500
500
|
elif action == 'mirror-del':
|
|
501
501
|
if not source:
|
|
502
|
-
context.write({'code': -1, 'msg': '
|
|
502
|
+
context.write({'code': -1, 'msg': '镜像站名称不能为空!'})
|
|
503
503
|
return
|
|
504
504
|
sources = _load_sources_config()
|
|
505
505
|
found = None
|
|
@@ -508,17 +508,17 @@ def web_handler(context, action):
|
|
|
508
508
|
found = s
|
|
509
509
|
break
|
|
510
510
|
if found is None:
|
|
511
|
-
context.write({'code': -1, 'msg': '
|
|
511
|
+
context.write({'code': -1, 'msg': '镜像站不存在!'})
|
|
512
512
|
return
|
|
513
513
|
if found.get('builtin'):
|
|
514
|
-
context.write({'code': -1, 'msg': '
|
|
514
|
+
context.write({'code': -1, 'msg': '内置镜像站不可删除!'})
|
|
515
515
|
return
|
|
516
516
|
sources = [s for s in sources if s['name'] != source]
|
|
517
517
|
_save_sources_config(sources)
|
|
518
|
-
context.write({'code': 0, 'msg': '
|
|
518
|
+
context.write({'code': 0, 'msg': f'镜像站「{source}」已删除'})
|
|
519
519
|
|
|
520
520
|
elif action == 'switch':
|
|
521
|
-
"""
|
|
521
|
+
"""切换镜像站:替换已有 .list 文件中 deb URL 的域名"""
|
|
522
522
|
url = context.get_argument('url', '').strip()
|
|
523
523
|
source_name = context.get_argument('name', '') or context.get_argument('source', '')
|
|
524
524
|
if not url and not source_name:
|
|
@@ -531,7 +531,7 @@ def web_handler(context, action):
|
|
|
531
531
|
url = s['url']
|
|
532
532
|
break
|
|
533
533
|
if not url:
|
|
534
|
-
context.write({'code': -1, 'msg': '
|
|
534
|
+
context.write({'code': -1, 'msg': '未找到该镜像站的地址!'})
|
|
535
535
|
return
|
|
536
536
|
|
|
537
537
|
new_url = url.rstrip('/')
|
|
@@ -578,7 +578,7 @@ def web_handler(context, action):
|
|
|
578
578
|
pass
|
|
579
579
|
|
|
580
580
|
if modified_count > 0:
|
|
581
|
-
context.write({'code': 0, 'msg': 'APT
|
|
581
|
+
context.write({'code': 0, 'msg': f'APT 镜像站已切换至:{source_name or url}(修改了 {modified_count} 个源文件)'})
|
|
582
582
|
else:
|
|
583
583
|
context.write({'code': -1, 'msg': '没有找到需要切换的源文件'})
|
|
584
584
|
|
|
@@ -598,9 +598,9 @@ def web_handler(context, action):
|
|
|
598
598
|
repo_file = 'sources.list.d/' + repo_file
|
|
599
599
|
|
|
600
600
|
if item_exists(repo_file):
|
|
601
|
-
context.write({'code': -1, 'msg': '
|
|
601
|
+
context.write({'code': -1, 'msg': f'仓库文件「{repo_file}」已存在!'})
|
|
602
602
|
elif add_item(repo_file, {'content': content}) is True:
|
|
603
|
-
context.write({'code': 0, 'msg': '
|
|
603
|
+
context.write({'code': 0, 'msg': f'仓库「{repo_file}」添加成功!'})
|
|
604
604
|
else:
|
|
605
605
|
context.write({'code': -1, 'msg': '仓库添加失败!'})
|
|
606
606
|
|
|
@@ -625,7 +625,7 @@ def web_handler(context, action):
|
|
|
625
625
|
elif not item_exists(source):
|
|
626
626
|
context.write({'code': -1, 'msg': '仓库文件不存在!'})
|
|
627
627
|
elif del_item(source):
|
|
628
|
-
context.write({'code': 0, 'msg': '
|
|
628
|
+
context.write({'code': 0, 'msg': f'仓库「{source}」已删除'})
|
|
629
629
|
else:
|
|
630
630
|
context.write({'code': -1, 'msg': '仓库删除失败!'})
|
|
631
631
|
|
|
@@ -642,7 +642,7 @@ def web_handler(context, action):
|
|
|
642
642
|
content = generate_sources(sources)
|
|
643
643
|
context.write({'code': 0, 'msg': '', 'data': {'content': content}})
|
|
644
644
|
|
|
645
|
-
# ---
|
|
645
|
+
# --- 第三方软件仓库 ---
|
|
646
646
|
elif action == 'third_party':
|
|
647
647
|
context.write(_get_apt_third_party())
|
|
648
648
|
|
|
@@ -655,14 +655,14 @@ def web_handler(context, action):
|
|
|
655
655
|
|
|
656
656
|
|
|
657
657
|
# ==================================================================
|
|
658
|
-
# APT
|
|
658
|
+
# APT 第三方软件仓库
|
|
659
659
|
# ==================================================================
|
|
660
660
|
|
|
661
661
|
_APT_THIRD_PARTY_CACHE = None
|
|
662
662
|
|
|
663
663
|
|
|
664
664
|
def _load_apt_third_party():
|
|
665
|
-
"""
|
|
665
|
+
"""加载第三方软件仓库配置文件"""
|
|
666
666
|
global _APT_THIRD_PARTY_CACHE
|
|
667
667
|
if _APT_THIRD_PARTY_CACHE is not None:
|
|
668
668
|
return _APT_THIRD_PARTY_CACHE
|
|
@@ -689,7 +689,7 @@ def _get_installed_list_files():
|
|
|
689
689
|
|
|
690
690
|
|
|
691
691
|
def _get_apt_third_party():
|
|
692
|
-
"""获取适配 Debian/Ubuntu
|
|
692
|
+
"""获取适配 Debian/Ubuntu 的第三方软件仓库列表"""
|
|
693
693
|
sources = _load_apt_third_party()
|
|
694
694
|
installed_files = _get_installed_list_files()
|
|
695
695
|
|
|
@@ -724,7 +724,7 @@ def _get_apt_third_party():
|
|
|
724
724
|
|
|
725
725
|
|
|
726
726
|
def _install_apt_third_party(source_id):
|
|
727
|
-
"""安装 APT
|
|
727
|
+
"""安装 APT 第三方软件仓库"""
|
|
728
728
|
sources = _load_apt_third_party()
|
|
729
729
|
source = None
|
|
730
730
|
for s in sources:
|
|
@@ -732,11 +732,11 @@ def _install_apt_third_party(source_id):
|
|
|
732
732
|
source = s
|
|
733
733
|
break
|
|
734
734
|
if not source:
|
|
735
|
-
return {'code': -1, 'msg': '
|
|
735
|
+
return {'code': -1, 'msg': '第三方软件仓库不存在!'}
|
|
736
736
|
|
|
737
737
|
platforms = source.get('platform', [])
|
|
738
738
|
if 'debian' not in platforms:
|
|
739
|
-
return {'code': -1, 'msg': '
|
|
739
|
+
return {'code': -1, 'msg': '该第三方软件仓库不支持当前系统平台!'}
|
|
740
740
|
|
|
741
741
|
debian_cfg = source.get('debian', {})
|
|
742
742
|
repo_file = debian_cfg.get('repo_file', source.get('repo_file', ''))
|
|
@@ -744,7 +744,7 @@ def _install_apt_third_party(source_id):
|
|
|
744
744
|
gpgkey_url = debian_cfg.get('gpgkey', source.get('gpgkey', ''))
|
|
745
745
|
|
|
746
746
|
if not repo_file:
|
|
747
|
-
return {'code': -1, 'msg': '
|
|
747
|
+
return {'code': -1, 'msg': '第三方软件仓库配置信息不完整!'}
|
|
748
748
|
|
|
749
749
|
# 对于有现成安装命令的源,使用专用函数
|
|
750
750
|
source_id_lower = source_id.lower()
|
|
@@ -771,16 +771,16 @@ def _install_apt_third_party(source_id):
|
|
|
771
771
|
|
|
772
772
|
# 通用安装:使用 repo_line 写入 .list 文件
|
|
773
773
|
if not repo_line:
|
|
774
|
-
return {'code': -1, 'msg': '
|
|
774
|
+
return {'code': -1, 'msg': '该第三方软件仓库暂无自动安装脚本,请手动添加源配置!'}
|
|
775
775
|
|
|
776
776
|
# 下载 GPG key
|
|
777
777
|
if gpgkey_url:
|
|
778
778
|
keyring_name = source_id.replace('-', '_') + '.gpg'
|
|
779
779
|
keyring_path = '/usr/share/keyrings/' + keyring_name
|
|
780
780
|
status, output = getstatusoutput(
|
|
781
|
-
'curl -fsSL
|
|
781
|
+
f'curl -fsSL {gpgkey_url} | gpg --dearmor -o {keyring_path} 2>&1')
|
|
782
782
|
if status != 0:
|
|
783
|
-
return {'code': -1, 'msg': 'GPG
|
|
783
|
+
return {'code': -1, 'msg': f'GPG 密钥下载失败:{output}'}
|
|
784
784
|
|
|
785
785
|
# 写入 .list 文件
|
|
786
786
|
list_path = str(Path(sources_list_d_path) / repo_file)
|
|
@@ -791,13 +791,13 @@ def _install_apt_third_party(source_id):
|
|
|
791
791
|
with open(list_path, 'w', encoding='utf-8') as f:
|
|
792
792
|
f.write(repo_line + '\n')
|
|
793
793
|
except Exception as e:
|
|
794
|
-
return {'code': -1, 'msg': '
|
|
794
|
+
return {'code': -1, 'msg': f'写入源文件失败:{e!s}'}
|
|
795
795
|
|
|
796
796
|
# apt update
|
|
797
797
|
status, output = getstatusoutput('apt-get update 2>&1')
|
|
798
798
|
if status == 0:
|
|
799
|
-
return {'code': 0, 'msg':
|
|
800
|
-
return {'code': -1, 'msg': 'apt update
|
|
799
|
+
return {'code': 0, 'msg': f"第三方软件仓库「{source['name']}」安装成功!"}
|
|
800
|
+
return {'code': -1, 'msg': f'apt update 失败:{output}'}
|
|
801
801
|
|
|
802
802
|
|
|
803
803
|
def _exec_apt_install_cmds(cmds, repo_name):
|
|
@@ -805,8 +805,8 @@ def _exec_apt_install_cmds(cmds, repo_name):
|
|
|
805
805
|
for cmd in cmds:
|
|
806
806
|
status, output = getstatusoutput(cmd + ' 2>&1')
|
|
807
807
|
if status != 0:
|
|
808
|
-
return {'code': -1, 'msg': '
|
|
809
|
-
return {'code': 0, 'msg': '
|
|
808
|
+
return {'code': -1, 'msg': f'仓库「{repo_name}」安装失败:{output}'}
|
|
809
|
+
return {'code': 0, 'msg': f'仓库「{repo_name}」安装成功!'}
|
|
810
810
|
|
|
811
811
|
|
|
812
812
|
if __name__ == '__main__':
|