mirror of
				https://github.com/kenzok8/openwrt-packages.git
				synced 2025-10-30 07:50:37 +08:00 
			
		
		
		
	update 2024-07-02 20:10:53
This commit is contained in:
		| @ -97,7 +97,7 @@ | ||||
|  | ||||
|     {"installed":false} | ||||
|    ``` | ||||
| 7. 任务状态(日志) | ||||
| 7. 任务状态(日志),已废弃,使用luci-lib-taskd提供的封装 | ||||
|    ``` | ||||
|    GET /cgi-bin/luci/admin/store/log | ||||
|  | ||||
|  | ||||
| @ -11,7 +11,7 @@ LUCI_DEPENDS:=+curl +opkg +luci-base +tar +coreutils +coreutils-stat +libuci-lua | ||||
| LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.19) | ||||
| LUCI_PKGARCH:=all | ||||
|  | ||||
| PKG_VERSION:=0.1.21-0 | ||||
| PKG_VERSION:=0.1.23-0 | ||||
| # PKG_RELEASE MUST be empty for luci.mk | ||||
| PKG_RELEASE:= | ||||
|  | ||||
|  | ||||
| @ -29,13 +29,22 @@ function index() | ||||
|     entry({"admin", "store", "get_block_devices"}, call("get_block_devices")) | ||||
|  | ||||
|     entry({"admin", "store", "configured"}, call("configured")) | ||||
|     entry({"admin", "store", "entrysh"}, post("entrysh")) | ||||
|  | ||||
|     for _, action in ipairs({"update", "install", "upgrade", "remove"}) do | ||||
|     -- docker | ||||
|     entry({"admin", "store", "docker_check_dir"}, call("docker_check_dir")) | ||||
|     entry({"admin", "store", "docker_check_migrate"}, call("docker_check_migrate")) | ||||
|     entry({"admin", "store", "docker_migrate"}, post("docker_migrate")) | ||||
|  | ||||
|     -- package | ||||
|     for _, action in ipairs({"update", "install", "upgrade", "remove", "autoconf"}) do | ||||
|         store_api(action, true) | ||||
|     end | ||||
|     for _, action in ipairs({"status", "installed"}) do | ||||
|         store_api(action, false) | ||||
|     end | ||||
|  | ||||
|     -- backup | ||||
|     if nixio.fs.access("/usr/libexec/istore/backup") then | ||||
|         entry({"admin", "store", "get_support_backup_features"}, call("get_support_backup_features")) | ||||
|         entry({"admin", "store", "light_backup"}, post("light_backup")) | ||||
| @ -294,8 +303,8 @@ function store_action(param) | ||||
|         end | ||||
|         local metapkg = pkg and (metapkgpre .. pkg) or "" | ||||
|         if action == "update" or pkg then | ||||
|             if action == "update" or action == "install" then | ||||
|                 if action == "install" and "1" == luci.http.formvalue("autoconf") then | ||||
|             if action == "update" or action == "install" or action == "autoconf" then | ||||
|                 if (action == "install" and "1" == luci.http.formvalue("autoconf")) or action == "autoconf" then | ||||
|                     local autoenv = "AUTOCONF=" .. pkg | ||||
|                     local autopath = luci.http.formvalue("path") | ||||
|                     local autoenable = luci.http.formvalue("enable") | ||||
| @ -408,6 +417,77 @@ function configured() | ||||
|     luci.http.write_json({code=200, configured=configured}) | ||||
| end | ||||
|  | ||||
| function entrysh() | ||||
|     local package = luci.http.formvalue("package") | ||||
|     local hostname = luci.http.formvalue("hostname") | ||||
|     if hostname == nil or hostname == "" or not validate_pkgname(package) then | ||||
|         luci.http.status(400, "Bad Request") | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     local result | ||||
|     local entryfile = "/usr/libexec/istoree/" .. package .. ".sh" | ||||
|     if nixio.fs.access(entryfile) then | ||||
|         local o = luci.util.exec(entryfile .. " status " .. luci.util.shellquote(hostname)) | ||||
|         if o == nil or o == "" then | ||||
|             result = {code=500, msg="entrysh execute failed"} | ||||
|         else | ||||
|             local jsonc = require "luci.jsonc" | ||||
|             local json_parse = jsonc.parse | ||||
|             local status = json_parse(o) | ||||
|             if status == nil then | ||||
|                 result = {code=500, msg="json parse failed: " .. o} | ||||
|             else | ||||
|                 result = {code=200, status=status} | ||||
|             end | ||||
|         end | ||||
|     else | ||||
|         result = {code=404, msg="entrysh of this package not found"} | ||||
|     end | ||||
|     luci.http.prepare_content("application/json") | ||||
|     luci.http.write_json(result) | ||||
| end | ||||
|  | ||||
| function docker_check_dir() | ||||
|     local docker_on_system = luci.sys.call("/usr/libexec/istore/docker check_dir >/dev/null 2>&1") ~= 0 | ||||
|     luci.http.prepare_content("application/json") | ||||
|     luci.http.write_json({code=200, docker_on_system=docker_on_system}) | ||||
| end | ||||
|  | ||||
| function docker_check_migrate() | ||||
|     local path = luci.http.formvalue("path") | ||||
|     if path == nil or path == "" then | ||||
|         luci.http.status(400, "Bad Request") | ||||
|         return | ||||
|     end | ||||
|     local r,o,e = is_exec("/usr/libexec/istore/docker migrate_check " .. luci.util.shellquote(path)) | ||||
|     local result = "good" | ||||
|     if r == 1 then | ||||
|         result = "bad" | ||||
|     elseif r == 2 then | ||||
|         result = "existed" | ||||
|     end | ||||
|     luci.http.prepare_content("application/json") | ||||
|     luci.http.write_json({code=200, result=result, error=e}) | ||||
| end | ||||
|  | ||||
| function docker_migrate() | ||||
|     local path = luci.http.formvalue("path") | ||||
|     if path == nil or path == "" then | ||||
|         luci.http.status(400, "Bad Request") | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     local action = "migrate" | ||||
|     local overwrite = luci.http.formvalue("overwrite") | ||||
|     if overwrite == "chdir" then | ||||
|         action = "change_dir" | ||||
|     end | ||||
|     local r,o,e = is_exec("/usr/libexec/istore/docker " .. action .. " " .. luci.util.shellquote(path), true) | ||||
|     luci.http.prepare_content("application/json") | ||||
|     luci.http.write_json({code=r, stdout=o, stderr=e}) | ||||
| end | ||||
|  | ||||
| local function split(str,reps) | ||||
|     local resultStrList = {} | ||||
|     string.gsub(str,'[^'..reps..']+',function (w) | ||||
|  | ||||
| @ -247,6 +247,9 @@ case $action in | ||||
|         check_space | ||||
|         wrapped_in_update opkg_wrap_mirrors install "$@" && try_autoconf | ||||
|     ;; | ||||
|     "autoconf") | ||||
|         try_autoconf | ||||
|     ;; | ||||
|     "upgrade") | ||||
|         new_upgrade "$@" | ||||
|     ;; | ||||
|  | ||||
							
								
								
									
										114
									
								
								luci-app-store/root/usr/libexec/istore/docker
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										114
									
								
								luci-app-store/root/usr/libexec/istore/docker
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,114 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| handle_part() { | ||||
|     case "$MOUNT" in | ||||
|         "/overlay") | ||||
|             return 1 | ||||
|         ;; | ||||
|     esac | ||||
|     return 0 | ||||
| } | ||||
|  | ||||
| check_dir() { | ||||
|     local data_root=$(uci -q get dockerd.globals.data_root) | ||||
|     [ -n "$data_root" ] || return 0 | ||||
|     local block_dev=$(findmnt -T "$data_root" -v -o SOURCE | sed -n 2p) | ||||
|     [ -n "$block_dev" ] || return 0 | ||||
|     [ "overlayfs:/overlay" = "$block_dev" ] && return 1 | ||||
|     local line=$(block info "$block_dev" 2>/dev/null) | ||||
|     [ -n "$line" ] || return 0 | ||||
|     eval "${line##*: } handle_part ${line%%: *}" | ||||
| } | ||||
|  | ||||
| migrate_check(){ | ||||
|     local dest="$1" | ||||
|     [ -n "$dest" ] || { | ||||
|         echo "dest dir not specified!" >&2 | ||||
|         return 1 | ||||
|     } | ||||
|     local data_root="$2" | ||||
|     [ -n "$data_root" ] || data_root=$(uci -q get dockerd.globals.data_root) | ||||
|     [ -n "$data_root" ] || { | ||||
|         echo "get docker data_root failed!" >&2 | ||||
|         return 1 | ||||
|     } | ||||
|  | ||||
|     [ "$data_root" = "/" ] || data_root="${data_root%%/}" | ||||
|     [ "$dest" = "/" ] || dest="${dest%%/}" | ||||
|  | ||||
|     [ "$data_root" = "$dest" ] && { | ||||
|         echo "dest dir is the same as data_root!" >&2 | ||||
|         return 1 | ||||
|     } | ||||
|  | ||||
|     [ 1 = "$FORCE" ] && return 0 | ||||
|     [ -e "$dest" ] || return 0 | ||||
|     [ -d "$dest" ] || { | ||||
|         echo "$dest is existed and it's not a dir, use FORCE=1 to overwrite it" >&2 | ||||
|         return 2 | ||||
|     } | ||||
|     [ 0 = "$(ls -A "$dest" | head -1 | wc -l)" ] || { | ||||
|         echo "$dest is existed and it's not empty, use FORCE=1 to overwrite it" >&2 | ||||
|         return 2 | ||||
|     } | ||||
|     return 0 | ||||
| } | ||||
|  | ||||
| migrate() { | ||||
|     local dest="$1" | ||||
|     local data_root=$(uci -q get dockerd.globals.data_root) | ||||
|     [ -n "$data_root" ] || { | ||||
|         echo "get docker data_root failed!" >&2 | ||||
|         return 1 | ||||
|     } | ||||
|     [ "$data_root" = "/" ] || data_root="${data_root%%/}" | ||||
|     [ "$dest" = "/" ] || dest="${dest%%/}" | ||||
|  | ||||
|     FORCE=1 migrate_check "$dest" "$data_root" | ||||
|     local check_result=$? | ||||
|     [ 0 = $check_result ] || return $check_result | ||||
|  | ||||
|     if [ "$UCI_ONLY" != 1 ]; then | ||||
|         rm -rf "$dest" | ||||
|         mkdir -p "$dest" | ||||
|         echo "Copy $data_root to $dest ..." | ||||
|         cp -a "$data_root/." "$dest/" || return 1 | ||||
|     fi | ||||
|  | ||||
|     echo "Change dockerd data_root to $dest and restart" | ||||
|     uci set dockerd.globals.data_root="$dest" | ||||
|     uci commit dockerd | ||||
|     /etc/init.d/dockerd restart | ||||
|  | ||||
|     echo "Done" | ||||
| } | ||||
|  | ||||
| action=${1} | ||||
| shift | ||||
|  | ||||
| usage() { | ||||
|     echo "usage: $1 sub-command [arguments...]" | ||||
|     echo "where sub-command is one of:" | ||||
|     echo "      check_dir                    Check docker data_root is on extrnal disk" | ||||
|     echo "      migrate_check {target_dir}   Check target_dir is valid for migration, return 2 if target_dir existed and not empty" | ||||
|     echo "      migrate {target_dir}         Migrate docker data_root to target_dir" | ||||
|     echo "      change_dir {target_dir}      Migrate docker data_root to target_dir but change dir only (no data copy)" | ||||
| } | ||||
|  | ||||
| case $action in | ||||
|     "check_dir") | ||||
|         check_dir | ||||
|     ;; | ||||
|     "migrate") | ||||
|         migrate "$@" | ||||
|     ;; | ||||
|     "migrate_check") | ||||
|         migrate_check "$@" | ||||
|     ;; | ||||
|     "change_dir") | ||||
|         UCI_ONLY=1 migrate "$@" | ||||
|     ;; | ||||
|     *) | ||||
|         usage "$0" | ||||
|     ;; | ||||
| esac | ||||
| @ -28,7 +28,7 @@ paths: | ||||
|     post: | ||||
|       tags: | ||||
|         - install | ||||
|       summary: 安装插件 | ||||
|       summary: 安装插件。安装过程中使用taskd接口获取日志 | ||||
|       parameters: | ||||
|         - in: "query" | ||||
|           name: "token" | ||||
| @ -55,6 +55,33 @@ paths: | ||||
|           description: OK | ||||
|           schema: | ||||
|             $ref: "#/definitions/ResponseStore" | ||||
|   /cgi-bin/luci/admin/store/autoconf: | ||||
|     post: | ||||
|       tags: | ||||
|         - install | ||||
|       summary: 自动配置插件 | ||||
|       parameters: | ||||
|         - in: "query" | ||||
|           name: "token" | ||||
|           type: string | ||||
|           required: true | ||||
|         - in: "query" | ||||
|           name: "package" | ||||
|           type: string | ||||
|           required: true | ||||
|         - in: "query" | ||||
|           name: "path" | ||||
|           type: string | ||||
|           description: "可选参数" | ||||
|         - in: "query" | ||||
|           name: "enable" | ||||
|           type: string | ||||
|           description: "可选参数" | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           schema: | ||||
|             $ref: "#/definitions/ResponseStore" | ||||
|   /cgi-bin/luci/admin/store/remove: | ||||
|     post: | ||||
|       tags: | ||||
| @ -148,7 +175,7 @@ paths: | ||||
|     get: | ||||
|       tags: | ||||
|         - log | ||||
|       summary: 任务日志 | ||||
|       summary: 任务日志,已废弃 | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
| @ -194,11 +221,94 @@ paths: | ||||
|       tags: | ||||
|         - configured | ||||
|       summary: 检查插件是否已经配置过 | ||||
|       parameters: | ||||
|         - in: "query" | ||||
|           name: "uci" | ||||
|           type: string | ||||
|           required: true | ||||
|           description: "要检查的uci配置文件名称" | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           schema: | ||||
|             $ref: "#/definitions/ResponseStoreConfigured" | ||||
|   /cgi-bin/luci/admin/store/entrysh: | ||||
|     post: | ||||
|       tags: | ||||
|         - entrysh | ||||
|       summary: 查询插件运行状态,主要为了获取入口信息。 | ||||
|       description: 调用前应该检查meta数据中autoconf数组包含entrysh,注意如果是安装插件则检查服务器端的autoconf,如果是调用已安装插件则检查路由器端的autoconf。 | ||||
|       parameters: | ||||
|         - in: "query" | ||||
|           name: "token" | ||||
|           type: string | ||||
|           required: true | ||||
|         - in: "query" | ||||
|           name: "package" | ||||
|           type: string | ||||
|           required: true | ||||
|           description: "包名,例如aria2" | ||||
|         - in: "query" | ||||
|           name: "hostname" | ||||
|           type: string | ||||
|           required: true | ||||
|           description: "主机名,不包含端口。前端应该使用location.hostname获取" | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           schema: | ||||
|             $ref: "#/definitions/ResponseStoreEntrysh" | ||||
|   /cgi-bin/luci/admin/store/docker_check_dir: | ||||
|     get: | ||||
|       tags: | ||||
|         - docker_check_dir | ||||
|       summary: 检查docker目录是否在系统盘 | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           schema: | ||||
|             $ref: "#/definitions/ResponseDockerCheckDir" | ||||
|   /cgi-bin/luci/admin/store/docker_check_migrate: | ||||
|     get: | ||||
|       tags: | ||||
|         - docker_check_migrate | ||||
|       summary: 检查docker迁移目标目录是否有效 | ||||
|       parameters: | ||||
|         - in: "query" | ||||
|           name: "path" | ||||
|           type: string | ||||
|           required: true | ||||
|           description: "完整目标路径" | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           schema: | ||||
|             $ref: "#/definitions/ResponseDockerCheckMigrate" | ||||
|   /cgi-bin/luci/admin/store/docker_migrate: | ||||
|     post: | ||||
|       tags: | ||||
|         - docker_migrate | ||||
|       summary: docker迁移到目标目录,异步 | ||||
|       description: 当返回code为0的时候,可以使用taskd接口展示日志,跟安装插件时一样 | ||||
|       parameters: | ||||
|         - in: "query" | ||||
|           name: "token" | ||||
|           type: string | ||||
|           required: true | ||||
|         - in: "query" | ||||
|           name: "path" | ||||
|           type: string | ||||
|           required: true | ||||
|           description: "完整目标路径" | ||||
|         - in: "query" | ||||
|           name: "overwrite" | ||||
|           type: string | ||||
|           description: "如果docker_check_migrate返回的result是existed,使用此参数指定解决方案:‘true’表示覆盖目标目录;‘chdir’表示只修改路径不复制文件" | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           schema: | ||||
|             $ref: "#/definitions/ResponseStore" | ||||
|    | ||||
| definitions: | ||||
|   ResponseStoreToken: | ||||
| @ -324,4 +434,54 @@ definitions: | ||||
|         description: "为200时" | ||||
|       configured: | ||||
|         type: boolean | ||||
|   ResponseDockerCheckDir: | ||||
|     type: object | ||||
|     properties: | ||||
|       code: | ||||
|         type: integer | ||||
|         description: "为200时" | ||||
|       docker_on_system: | ||||
|         type: boolean | ||||
|         description: "docker数据在系统盘" | ||||
|   ResponseDockerCheckMigrate: | ||||
|     type: object | ||||
|     properties: | ||||
|       code: | ||||
|         type: integer | ||||
|         description: "为200时" | ||||
|       result: | ||||
|         type: string | ||||
|         description: "检查结果。可能值‘good’,‘bad’,‘existed’" | ||||
|       error: | ||||
|         type: string | ||||
|         description: "当result为bad时,此处返回错误日志" | ||||
|   ResponseStoreEntrysh: | ||||
|     type: object | ||||
|     properties: | ||||
|       code: | ||||
|         type: integer | ||||
|         description: "为200时" | ||||
|       msg: | ||||
|         type: string | ||||
|         description: "code不为200时显示错误信息" | ||||
|       status: | ||||
|         type: object | ||||
|         description: "状态和入口信息,不同插件可能有些不一样,仅列出常用公共参数" | ||||
|         properties: | ||||
|           app: | ||||
|             type: string | ||||
|             description: "插件名称,跟请求的包名一致" | ||||
|           docker: | ||||
|             type: boolean | ||||
|             description: "如果是docker插件" | ||||
|           running: | ||||
|             type: boolean | ||||
|             description: "是否运行中" | ||||
|           deployed: | ||||
|             type: boolean | ||||
|             description: "如果是docker插件且未运行,则是否已经部署" | ||||
|           web: | ||||
|             type: string | ||||
|             description: "web端跳转url" | ||||
|    | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 actions-user
					actions-user