#!/opt/lnxall_app/bin/lua -- created by jiaqiang.ye@lnxall.com -- Simple command-line utility for EMS2.0 packapp -- 2024/08/30 local posix = require "posix" local invoker = require "invoker" local gfmt = string.format -- global variables local g_packdir = '/root/.packapp' local g_packapp = '/root/.packapp.tar.gz' local g_packapp_h, g_ipaddr_h = nil, "127.0.0.1" local g_ipaddr, g_gwsn, g_cmd = nil, nil, nil local g_sshcmd = { "sshpass", "-p", "lnxall123", "ssh", '-oStrictHostKeyChecking=no', '-oUserKnownHostsFile=/dev/null', } local function validate_args(arg0, arg1, arg2, arg3) g_ipaddr, g_gwsn, g_cmd = arg1, arg2, arg3 if type(g_ipaddr) ~= "string" then g_ipaddr = 'unknown' end if not invoker.isipv4(g_ipaddr) then io.stderr:write(gfmt("ERROR: invalid IPv4 address specified: %s\n", g_ipaddr)) io.stderr:flush() return false end if type(g_gwsn) ~= "string" then g_gwsn = "" end if #g_gwsn == 0 then io.stderr:write(gfmt("ERROR: invalid Gateway SN specified: %s\n", g_gwsn)) io.stderr:flush() return false end if g_cmd ~= "start" and g_cmd ~= "stop" and g_cmd ~= "query" then if type(g_cmd) ~= "string" then g_cmd = "" end io.stderr:write(gfmt("ERROR: invalid command for packapp: %s\n", g_cmd)) io.stderr:flush() return false end if type(arg0) == "string" then arg0 = invoker.realpath(arg0) end if type(arg0) == "string" then arg0 = string.match(arg0, "^(.+)/") end if type(arg0) ~= "string" or posix.access(arg0) ~= 0 then io.stderr:write("ERROR: packapp script not found.\n") io.stderr:flush() return false end g_packapp_h = gfmt("%s/packapp.tar.gz", arg0) -- initialize environment variables posix.setenv("EMS_IP") posix.setenv("SSH_CLIENT") posix.setenv("SSH_CONNECTION") invoker.invoke(invoker.NOSTDIO, "mkdir", "-p", "/opt/elect_resources/resources/app/web/dist/exdata") return true end local function shell_cmd(flag, cmdline) if type(flag) ~= "number" then flag = invoker.NOSTDIO + invoker.OUTPUT end local ok, out = invoker.invoke(flag, "/bin/sh", "-c", cmdline) return ok, out end local function scp_cmd(flag, cmdlist) if #cmdlist ~= 0x2 then io.stdout:write("ERROR: invalid number of argument for scp.\n") io.stdout:flush() return nil end local list, nl = {}, 1 while type(g_sshcmd[nl]) == "string" do if g_sshcmd[nl] == "ssh" then list[nl] = "scp" else list[nl] = g_sshcmd[nl] end nl = nl + 1 end list[nl] = "-r"; nl = nl + 1 list[nl] = cmdlist[1]; nl = nl + 1 list[nl] = gfmt("root@%s:%s", g_ipaddr, cmdlist[2]) if type(flag) ~= "number" then flag = invoker.NOSTDIO + invoker.OUTPUT end local ok, out = invoker.invoke(flag, list) return ok, out end local function ssh_cmd(flag, cmdlist) local list, nl = {}, 1 while type(g_sshcmd[nl]) == "string" do list[nl] = g_sshcmd[nl] nl = nl + 1 end list[nl] = "root@" .. g_ipaddr nl = nl + 1 for _, cmd in ipairs(cmdlist) do list[nl] = cmd nl = nl + 1 end if type(flag) ~= "number" then flag = invoker.NOSTDIO + invoker.OUTPUT end local ok, out = invoker.invoke(flag, list) return ok, out end local function check_packapp() if not invoker.tcpcheck(g_ipaddr, 22, 2500) then io.stderr:write(gfmt("ERROR: gateway %s not online: %s\n", g_ipaddr, g_gwsn)) io.stderr:flush() os.exit(2) end local md50, md51 = nil, nil local okay, output = invoker.invoke(invoker.NOSTDIO + invoker.OUTPUT, "md5sum", g_packapp_h) if okay == 0 and type(output) == "string" then md50 = string.match(output, "^([%d%x]+)") end if type(md50) ~= "string" or #md50 ~= 32 then io.stderr:write(gfmt("ERROR: cannot get md5sum for %s\n", g_packapp_h)) io.stderr:flush() os.exit(3) end local tried = false if g_ipaddr == g_ipaddr_h then while true do okay, output = shell_cmd(invoker.OUTPUT, gfmt("md5sum %s", g_packapp)) if okay ~= 0 then output = "" end md51 = string.match(output, "^([%d%x]+)") if (md51 == md50 or tried) and posix.access(g_packdir) == 0 then break end tried = true invoker.invoke(invoker.NOSTDIO, "/bin/sh", "-c", gfmt("rm -rf %s %s", g_packdir, g_packapp)) invoker.invoke(invoker.NOSTDIO, "cp", "-f", g_packapp_h, g_packapp) invoker.invoke(invoker.NOSTDIO, "/bin/sh", "-c", string.format("cd /root && tar -zxf %s", g_packapp)) end if md51 ~= md50 then io.stderr:write(gfmt("ERROR: cannot copy packapp to %s, %s\n", g_gwsn, g_ipaddr)) io.stderr:flush() os.exit(4) end return true end while true do okay, output = ssh_cmd(nil, { [1] = gfmt("md5sum %s", g_packapp) }) if okay ~= 0 then output = "" end md51 = string.match(output, "^([%d%x]+)") if md51 == md50 or tried then break end tried = true ssh_cmd(nil, { [1] = gfmt("rm -rf %s %s", g_packapp, g_packdir ) }) if scp_cmd(invoker.NOSTDIO, { [1] = g_packapp_h, [2] = g_packapp }) == 0 then ssh_cmd(nil, { [1] = gfmt("cd /root && tar -zxf %s", g_packapp) }) end end if md51 ~= md50 then io.stderr:write(gfmt("ERROR: cannot copy packapp to %s, %s\n", g_gwsn, g_ipaddr)) io.stderr:flush() os.exit(5) end return true end local function mainfunc_op() local cmd = nil if g_cmd == "start" then cmd = gfmt("%s/cmd_start.sh %s", g_packdir, g_gwsn) elseif g_cmd == "stop" then cmd = gfmt("%s/cmd_stop.sh %s", g_packdir, g_gwsn) elseif g_cmd == "query" then cmd = gfmt("%s/cmd_query.sh %s", g_packdir, g_gwsn) else io.stderr:write(gfmt("ERROR: invalid command: %s\n", g_cmd)) io.stderr:flush() os.exit(5) end local okay, output = nil, nil if g_ipaddr == g_ipaddr_h then posix.setenv("EMS_IP", g_ipaddr_h) okay, output = shell_cmd(nil, cmd) else okay, output = ssh_cmd(nil, { [1] = cmd }) end if type(okay) ~= "number" or okay ~= 0 then if type(okay) ~= "number" then okay = 90 end if type(output) == "string" then io.stdout:write(output) else io.stdout:write(gfmt("ERROR: command '%s' has failed with: %d\n", g_cmd, okay)) end io.stdout:flush() os.exit(okay) end if type(output) ~= "string" or #output == 0 then output = gfmt("INFO: command %s executed successfully, without output.", g_cmd) end io.stdout:write(output) io.stdout:flush() os.exit(0) end if not validate_args(arg[0], arg[1], arg[2], arg[3]) then os.exit(1) end check_packapp() mainfunc_op()