--[[ LuCI - Lua Configuration Interface Copyright 2021 jjm2473 ]]-- require "luci.util" module("luci.controller.admin.ota",package.seeall) function index() if nixio.fs.access("/rom/bin/ota") then entry({"admin", "system", "ota"}, call("action_ota"), _("OTA"), 69) entry({"admin", "system", "ota", "check"}, post("action_check")) entry({"admin", "system", "ota", "download"}, post("action_download")) entry({"admin", "system", "ota", "progress"}, call("action_progress")) entry({"admin", "system", "ota", "cancel"}, post("action_cancel")) end end local function ota_exec(cmd) local nixio = require "nixio" local os = require "os" local fs = require "nixio.fs" local rshift = nixio.bit.rshift local oflags = nixio.open_flags("wronly", "creat") local lock, code, msg = nixio.open("/var/lock/ota_api.lock", oflags) if not lock then return 255, "", "Open stdio lock failed: " .. msg end -- Acquire lock local stat, code, msg = lock:lock("tlock") if not stat then lock:close() return 255, "", "Lock stdio failed: " .. msg end local r = os.execute(cmd .. " >/var/log/ota.stdout 2>/var/log/ota.stderr") local e = fs.readfile("/var/log/ota.stderr") local o = fs.readfile("/var/log/ota.stdout") fs.unlink("/var/log/ota.stderr") fs.unlink("/var/log/ota.stdout") lock:lock("ulock") lock:close() e = e or "" if r == 256 and e == "" then e = "os.execute failed, is /var/log full or not existed?" end return rshift(r, 8), o or "", e or "" end local function image_supported(image) return (os.execute("sysupgrade -T %q >/dev/null" % image) == 0) end function action_ota() local image_tmp = "/tmp/firmware.img" local http = require "luci.http" if http.formvalue("apply") == "1" then if not image_supported(image_tmp) then luci.template.render("admin_system/ota", {image_invalid = true}) return end local keep = (http.formvalue("keep") == "1") and "" or "-n" luci.template.render("admin_system/ota_flashing", { title = luci.i18n.translate("Flashing…"), msg = luci.i18n.translate("The system is flashing now.
DO NOT POWER OFF THE DEVICE!
Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings."), addr = (#keep > 0) and "10.0.0.1" or nil }) fork_exec("sleep 1; killall dropbear uhttpd nginx; sleep 1; sync; /sbin/sysupgrade %s %q" %{ keep, image_tmp }) else luci.template.render("admin_system/ota") end end function action_check() local r,o,e = ota_exec("ota check") local ret = { code = 500, msg = "Unknown" } if r == 0 then ret.code = 0 ret.msg = o elseif r == 1 then ret.code = 1 ret.msg = "Already the latest firmware" else ret.code = 500 ret.msg = e end luci.http.prepare_content("application/json") luci.http.write_json(ret) end function action_download() local r,o,e = ota_exec("ota download") local ret = { code = 500, msg = "Unknown" } if r == 0 then ret.code = 0 ret.msg = "" else ret.code = 500 ret.msg = e end luci.http.prepare_content("application/json") luci.http.write_json(ret) end function action_progress() local r,o,e = ota_exec("ota progress") local ret = { code = 500, msg = "Unknown" } if r == 0 then ret.code = 0 ret.msg = "done" elseif r == 1 or r == 2 then ret.code = r ret.msg = o else ret.code = 500 ret.msg = e end luci.http.prepare_content("application/json") luci.http.write_json(ret) end function action_cancel() local r,o,e = ota_exec("ota cancel") local ret = { code = 500, msg = "Unknown" } if r == 0 then ret.code = 0 ret.msg = "ok" else ret.code = 500 ret.msg = e end luci.http.prepare_content("application/json") luci.http.write_json(ret) end function fork_exec(command) local pid = nixio.fork() if pid > 0 then return elseif pid == 0 then -- change to root dir nixio.chdir("/") -- patch stdin, out, err to /dev/null local null = nixio.open("/dev/null", "w+") if null then nixio.dup(null, nixio.stderr) nixio.dup(null, nixio.stdout) nixio.dup(null, nixio.stdin) if null:fileno() > 2 then null:close() end end -- replace with target command nixio.exec("/bin/sh", "-c", command) end end