0
0
mirror of https://github.com/Doodle3D/doodle3d-firmware.git synced 2024-12-22 19:13:49 +01:00

Better error reporting, always using state, making version argument optional

This commit is contained in:
peteruithoven 2013-10-22 03:30:23 +02:00
parent d069dafb5c
commit c3bb0359bf
2 changed files with 83 additions and 50 deletions

View File

@ -14,27 +14,31 @@ local M = {
function M.status(request, response) function M.status(request, response)
updater.setLogger(log) updater.setLogger(log)
updater.setUseCache(false) updater.setUseCache(false)
local status,msg = updater.getStatus() local success,status,msg = updater.getStatus()
if not status then
--response:addData('current_version', status.currentVersion)
response:addData('current_version', updater.formatVersion(status.currentVersion))
response:addData('state_code', status.stateCode)
response:addData('state_text', status.stateText)
if not success then
response:setFail(msg) response:setFail(msg)
return return
end end
local canUpdate = updater.compareVersions(status.newestVersion, status.currentVersion) > 0 local canUpdate = updater.compareVersions(status.newestVersion, status.currentVersion) > 0
response:addData('current_version', updater.formatVersion(status.currentVersion))
response:addData('newest_version', updater.formatVersion(status.newestVersion))
--response:addData('current_version', status.currentVersion)
--response:addData('newest_version', status.newestVersion) --response:addData('newest_version', status.newestVersion)
response:addData('newest_version', updater.formatVersion(status.newestVersion))
response:addData('can_update', canUpdate) response:addData('can_update', canUpdate)
response:addData('state_code', status.stateCode)
response:addData('state_text', status.stateText)
if status.progress then response:addData('progress', status.progress) end if status.progress then response:addData('progress', status.progress) end
if status.imageSize then response:addData('image_size', status.imageSize) end if status.imageSize then response:addData('image_size', status.imageSize) end
response:setSuccess() response:setSuccess()
end end
-- requires: version(string) (major.minor.patch) -- accepts: version(string) (major.minor.patch)
-- accepts: clear_gcode(bool, defaults to true) (this is to lower the chance on out-of-memory crashes, but still allows overriding this behaviour) -- accepts: clear_gcode(bool, defaults to true) (this is to lower the chance on out-of-memory crashes, but still allows overriding this behaviour)
-- accepts: clear_images(bool, defaults to true) (same rationale as with clear_gcode) -- accepts: clear_images(bool, defaults to true) (same rationale as with clear_gcode)
-- note: call this with a long timeout - downloading may take a while (e.g. ~3.3MB with slow internet...) -- note: call this with a long timeout - downloading may take a while (e.g. ~3.3MB with slow internet...)
@ -45,17 +49,27 @@ function M.download_POST(request, response)
if argClearGcode == nil then argClearGcode = true end if argClearGcode == nil then argClearGcode = true end
if argClearImages == nil then argClearImages = true end if argClearImages == nil then argClearImages = true end
if not argVersion then
response:setError("missing version argument")
return
end
updater.setLogger(log) updater.setLogger(log)
updater.setState(updater.STATE.DOWNLOADING,"")
local vEnt, rv, msg local vEnt, rv, msg
if not argVersion then
local success,status,msg = updater.getStatus()
if not success then
updater.setState(updater.STATE.DOWNLOAD_FAILED, msg)
response:setFail(msg)
return
else
argVersion = updater.formatVersion(status.newestVersion)
end
end
if argClearImages then if argClearImages then
rv,msg = updater.clear() rv,msg = updater.clear()
if not rv then if not rv then
updater.setState(updater.STATE.DOWNLOAD_FAILED, msg)
response:setFail(msg) response:setFail(msg)
return return
end end
@ -66,6 +80,7 @@ function M.download_POST(request, response)
local rv,msg = printer:clearGcode() local rv,msg = printer:clearGcode()
if not rv then if not rv then
updater.setState(updater.STATE.DOWNLOAD_FAILED, msg)
response:setError(msg) response:setError(msg)
return return
end end
@ -73,15 +88,18 @@ function M.download_POST(request, response)
vEnt,msg = updater.findVersion(argVersion) vEnt,msg = updater.findVersion(argVersion)
if vEnt == nil then if vEnt == nil then
updater.setState(updater.STATE.DOWNLOAD_FAILED, "error searching version index (" .. msg .. ")")
response:setFail("error searching version index (" .. msg .. ")") response:setFail("error searching version index (" .. msg .. ")")
return return
elseif vEnt == false then elseif vEnt == false then
updater.setState(updater.STATE.DOWNLOAD_FAILED, "no such version")
response:setFail("no such version") response:setFail("no such version")
return return
end end
rv,msg = updater.downloadImageFile(vEnt) rv,msg = updater.downloadImageFile(vEnt)
if not rv then if not rv then
updater.setState(updater.STATE.DOWNLOAD_FAILED, msg)
response:setFail(msg) response:setFail(msg)
return return
end end
@ -94,24 +112,38 @@ function M.install_POST(request, response)
local argVersion = request:get("version") local argVersion = request:get("version")
updater.setLogger(log) updater.setLogger(log)
log:info("API:update/install")
updater.setState(updater.STATE.INSTALLING,"")
if not argVersion then if not argVersion then
response:setError("missing version argument") local success,status,msg = updater.getStatus()
if not success then
updater.setState(updater.STATE.INSTALL_FAILED, msg)
response:setFail(msg)
return return
else
argVersion = updater.formatVersion(status.newestVersion)
end
end end
vEnt,msg = updater.findVersion(argVersion) vEnt,msg = updater.findVersion(argVersion)
if vEnt == nil then if vEnt == nil then
updater.setState(updater.STATE.INSTALL_FAILED, "error searching version index (" .. msg .. ")")
response:setFail("error searching version index (" .. msg .. ")") response:setFail("error searching version index (" .. msg .. ")")
return return
elseif vEnt == false then elseif vEnt == false then
updater.setState(updater.STATE.INSTALL_FAILED, "no such version")
response:setFail("no such version") response:setFail("no such version")
return return
end end
local rv,msg = updater.flashImageVersion(vEnt) local rv,msg = updater.flashImageVersion(vEnt)
if not rv then response:setFail("installation failed (" .. msg .. ")") if not rv then
else response:setSuccess() updater.setState(updater.STATE.INSTALL_FAILED, "installation failed (" .. msg .. ")")
response:setFail("installation failed (" .. msg .. ")")
else
response:setSuccess()
end end
end end

View File

@ -113,23 +113,6 @@ local function getState()
return code,msg return code,msg
end end
-- NOTE: make sure the cache directory exists before calling this function or it will fail.
-- NOTE: this function _can_ fail but we don't expect this to happen so the return value is ignored for now
local function setState(code, msg)
local s = code .. '|' .. msg
D("set update state: " .. M.STATE_NAMES[code] .. " ('" .. s .. "')")
local file,msg = io.open(M.CACHE_PATH .. '/' .. M.STATE_FILE, 'w')
if not file then
E("error: could not open state file for writing (" .. msg .. ")")
return false
end
file:write(s)
file:close()
return true
end
-- trim whitespace from both ends of string (from http://snippets.luacode.org/?p=snippets/trim_whitespace_from_string_76) -- trim whitespace from both ends of string (from http://snippets.luacode.org/?p=snippets/trim_whitespace_from_string_76)
local function trim(s) local function trim(s)
if type(s) ~= 'string' then return s end if type(s) ~= 'string' then return s end
@ -267,17 +250,19 @@ function M.getStatus()
local unknownVersion = { major = 0, minor = 0, patch = 0 } local unknownVersion = { major = 0, minor = 0, patch = 0 }
local result = {} local result = {}
result.currentVersion = M.getCurrentVersion()
result.stateCode, result.stateText = getState()
result.stateCode = tonumber(result.stateCode)
local verTable,msg = M.getAvailableVersions() local verTable,msg = M.getAvailableVersions()
if not verTable then if not verTable then
D("could not obtain available versions (" .. msg .. ")") D("could not obtain available versions (" .. msg .. ")")
-- TODO: set an error state in result to signify we probably do not have internet access? -- TODO: set an error state in result to signify we probably do not have internet access?
return false, result, msg
end end
local newest = verTable and verTable[#verTable] local newest = verTable and verTable[#verTable]
result.currentVersion = M.getCurrentVersion()
result.newestVersion = newest and newest.version or unknownVersion result.newestVersion = newest and newest.version or unknownVersion
result.stateCode, result.stateText = getState()
result.stateCode = tonumber(result.stateCode)
if result.stateCode == M.STATE.DOWNLOADING then if result.stateCode == M.STATE.DOWNLOADING then
result.progress = fileSize(M.CACHE_PATH .. '/' .. newest.sysupgradeFilename) result.progress = fileSize(M.CACHE_PATH .. '/' .. newest.sysupgradeFilename)
@ -285,7 +270,7 @@ function M.getStatus()
result.imageSize = newest.sysupgradeFileSize result.imageSize = newest.sysupgradeFileSize
end end
return result return true, result
end end
-- Turns a plain-text version into a table. -- Turns a plain-text version into a table.
@ -454,24 +439,24 @@ function M.downloadImageFile(versionEntry, devType, isFactory)
local rv = 0 local rv = 0
if doDownload then if doDownload then
setState(M.STATE.DOWNLOADING, "Downloading image (" .. filename .. ")") M.setState(M.STATE.DOWNLOADING, "Downloading image (" .. filename .. ")")
rv = downloadFile(baseUrl .. '/images/' .. filename, M.CACHE_PATH, filename) rv = downloadFile(baseUrl .. '/images/' .. filename, M.CACHE_PATH, filename)
end end
if rv == 0 then if rv == 0 then
if M.checkValidImage(versionEntry, devType, isFactory) then if M.checkValidImage(versionEntry, devType, isFactory) then
setState(M.STATE.IMAGE_READY, "Image downloaded, ready to install (image name: " .. filename .. ")") M.setState(M.STATE.IMAGE_READY, "Image downloaded, ready to install (image name: " .. filename .. ")")
return true return true
else else
removeFile(M.CACHE_PATH .. '/' .. filename) removeFile(M.CACHE_PATH .. '/' .. filename)
local ws = "Image download failed (invalid image)" local ws = "Image download failed (invalid image)"
setState(M.STATE_DOWNLOAD_FAILED, ws) M.setState(M.STATE.DOWNLOAD_FAILED, ws)
return nil,ws return nil,ws
end end
else else
local ws = wgetStatusToString(rv) local ws = wgetStatusToString(rv)
removeFile(M.CACHE_PATH .. '/' .. filename) removeFile(M.CACHE_PATH .. '/' .. filename)
setState(M.STATE.DOWNLOAD_FAILED, "Image download failed (wget error: " .. ws .. ")") M.setState(M.STATE.DOWNLOAD_FAILED, "Image download failed (wget error: " .. ws .. ")")
return nil,ws return nil,ws
end end
end end
@ -480,6 +465,7 @@ end
-- noRetain, devType and isFactory are optional -- noRetain, devType and isFactory are optional
-- returns true or nil + wget return value -- returns true or nil + wget return value
function M.flashImageVersion(versionEntry, noRetain, devType, isFactory) function M.flashImageVersion(versionEntry, noRetain, devType, isFactory)
log:info("flashImageVersion")
local imgName = M.constructImageFilename(versionEntry.version, devType, isFactory) local imgName = M.constructImageFilename(versionEntry.version, devType, isFactory)
local cmd = noRetain and 'sysupgrade -n ' or 'sysupgrade ' local cmd = noRetain and 'sysupgrade -n ' or 'sysupgrade '
cmd = cmd .. M.CACHE_PATH .. '/' .. imgName cmd = cmd .. M.CACHE_PATH .. '/' .. imgName
@ -491,15 +477,15 @@ function M.flashImageVersion(versionEntry, noRetain, devType, isFactory)
return nil,"no valid image for requested version present" return nil,"no valid image for requested version present"
end end
setState(M.STATE.INSTALLING, "Installing new image (" .. imgName .. ")") -- yes this is rather pointless M.setState(M.STATE.INSTALLING, "Installing new image (" .. imgName .. ")") -- yes this is rather pointless
local rv = runCommand(cmd) -- if everything goes to plan, this will not return local rv = runCommand(cmd) -- if everything goes to plan, this will not return
if rv == 0 then if rv == 0 then
setState(M.STATE.INSTALLED, "Image installed") M.setState(M.STATE.INSTALLED, "Image installed")
else else
-- NOTE: if cmdrv == 127, this means the command was not found -- NOTE: if cmdrv == 127, this means the command was not found
local cmdrv,sysrv = splitExitStatus(rv) local cmdrv,sysrv = splitExitStatus(rv)
setState(M.STATE.INSTALL_FAILED, "Image installation failed (sysupgrade returned " .. cmdrv .. ", execution status: " .. sysrv .. ")") M.setState(M.STATE.INSTALL_FAILED, "Image installation failed (sysupgrade returned " .. cmdrv .. ", execution status: " .. sysrv .. ")")
end end
return (rv == 0) and true or nil,rv return (rv == 0) and true or nil,rv
@ -511,12 +497,27 @@ function M.clear()
if not ccRv then return nil,ccMsg end if not ccRv then return nil,ccMsg end
D("Removing " .. M.CACHE_PATH .. "/doodle3d-wifibox-*.bin") D("Removing " .. M.CACHE_PATH .. "/doodle3d-wifibox-*.bin")
setState(M.STATE.NONE, "") M.setState(M.STATE.NONE, "")
local rv = os.execute('rm -f ' .. M.CACHE_PATH .. '/doodle3d-wifibox-*.bin') local rv = os.execute('rm -f ' .. M.CACHE_PATH .. '/doodle3d-wifibox-*.bin')
return (rv == 0) and true or nil,"could not remove image files" return (rv == 0) and true or nil,"could not remove image files"
end end
-- NOTE: make sure the cache directory exists before calling this function or it will fail.
-- NOTE: this function _can_ fail but we don't expect this to happen so the return value is ignored for now
function M.setState(code, msg)
local s = code .. '|' .. msg
D("set update state: " .. M.STATE_NAMES[code] .. " ('" .. s .. "')")
local file,msg = io.open(M.CACHE_PATH .. '/' .. M.STATE_FILE, 'w')
if not file then
E("error: could not open state file for writing (" .. msg .. ")")
return false
end
file:write(s)
file:close()
return true
end