doodle3d-firmware/src/rest/api/api_info.lua

211 lines
8.0 KiB
Lua

--
-- This file is part of the Doodle3D project (http://doodle3d.com).
--
-- @copyright 2013, Doodle3D
-- @license This software is licensed under the terms of the GNU GPL v2 or later.
-- See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
local lfs = require('lfs')
local log = require('util.logger')
local utils = require('util.utils')
local accessManager = require('util.access')
local printDriver = require('print3d')
local printerUtils = require('util.printer')
local printerAPI = require('rest.api.api_printer')
local wifi = require('network.wlanconfig')
local settings = require('util.settings')
local MOD_ABBR = "AINF"
local TMP_DIR = '/tmp'
local LOG_COLLECT_DIRNAME = 'wifibox-logs'
local LOG_COLLECT_DIR = TMP_DIR .. '/' .. LOG_COLLECT_DIRNAME
local DEFAULT_WIFIBOX_LOG_FILENAME = 'wifibox.log'
local DEFAULT_WIFIBOX_LOG_FILE = TMP_DIR .. '/' .. DEFAULT_WIFIBOX_LOG_FILENAME
local WIFIBOX_STDOUT_LOG_FILENAME = 'wifibox.stdout.log'
local WIFIBOX_STDOUT_LOG_FILE = TMP_DIR .. '/' .. WIFIBOX_STDOUT_LOG_FILENAME
local WIFIBOX_VERSION_FILENAME = 'wifibox-version'
local WIFIBOX_VERSION_FILE = '/etc/' .. WIFIBOX_VERSION_FILENAME
local ROTATED_LOGS_DIRNAME = 'wifibox-rotated'
local ROTATED_LOGS_DIR = TMP_DIR .. '/' .. ROTATED_LOGS_DIRNAME
local SYSLOG_FILENAME = 'syslog'
local PROCESS_LIST_FILENAME = 'processes'
local MEMINFO_FILENAME = 'meminfo'
local MOUNTS_FILENAME = 'mounts'
local DISKFREE_FILENAME = 'diskfree'
local UCI_CONFIG_FILES_TO_SAVE = { 'dhcp', 'firewall', 'network', 'system', 'wifibox', 'wireless' }
local USB_DIRTREE_COMMAND = "ls -R /sys/devices/platform/ehci-platform/usb1 | grep \":$\" | sed -e 's/:$//' -e 's/[^-][^\\/]*\\//--/g' -e 's/^/ /' -e 's/-/|/'"
local USB_DIRTREE_FILENAME = 'sys_devices_platform_ehci-platform_usb1.tree'
local PRINT3D_BASEPATH = '/tmp'
local PRINT3D_LOG_FILENAME_PREFIX = 'print3d.'
local PRINT3D_LOG_FILENAME_SUFFIX = '.log'
local LOG_COLLECT_ARCHIVE_FILENAME = LOG_COLLECT_DIRNAME .. '.tgz'
local LOG_COLLECT_ARCHIVE_FILE = TMP_DIR .. '/' .. LOG_COLLECT_ARCHIVE_FILENAME
local function redirectedExecute(cmd)
return os.execute(cmd .. " > /dev/null 2>&1")
end
local M = {
isApi = true
}
-- returns wifiboxid (since version 0.10.2)
function M._global(request, response)
response:setSuccess()
local wifiboxid = wifi.getSubstitutedSsid(settings.get('network.cl.wifiboxid'))
response:addData('wifiboxid', wifiboxid)
end
-- TODO: redirect stdout+stderr; handle errors
function M.logfiles(request, response)
local rv,sig,code,msg = nil,nil,nil,nil
rv,msg = lfs.mkdir(LOG_COLLECT_DIR)
rv,msg = lfs.chdir(TMP_DIR)
local wifiboxLogFilePath = log:getLogFilePath()
local wifiboxLogFileName = wifiboxLogFilePath and wifiboxLogFilePath:match('.*/(.*)')
--[[ create temporary files ]]--
-- copy wifibox API-script (firmware) log
lfs.link(wifiboxLogFilePath, LOG_COLLECT_DIR .. '/' .. wifiboxLogFileName)
-- copy d3dapi script stdout/stderr (fallback) log
lfs.link(WIFIBOX_STDOUT_LOG_FILE, LOG_COLLECT_DIR .. '/' .. WIFIBOX_STDOUT_LOG_FILENAME)
-- collect and copy print3d server logs
for file in lfs.dir(PRINT3D_BASEPATH) do
if file:find(PRINT3D_LOG_FILENAME_PREFIX) == 1 and file:find(PRINT3D_LOG_FILENAME_SUFFIX) ~= nil then
local srcLogFile = PRINT3D_BASEPATH .. '/' .. file
local tgtLogFile = LOG_COLLECT_DIR .. '/' .. file
lfs.link(srcLogFile, tgtLogFile)
end
end
-- copy rotated firmware and print3d logs
rv,msg = lfs.mkdir(LOG_COLLECT_DIR .. '/' .. ROTATED_LOGS_DIRNAME)
for file in lfs.dir(ROTATED_LOGS_DIR) do
local srcLogFile = ROTATED_LOGS_DIR .. '/' .. file
local tgtLogFile = LOG_COLLECT_DIR .. '/' .. ROTATED_LOGS_DIRNAME .. '/' .. file
lfs.link(srcLogFile, tgtLogFile)
end
-- capture syslog
rv,sig,code = os.execute('logread > ' .. LOG_COLLECT_DIR .. '/' .. SYSLOG_FILENAME)
-- capture running processes
rv,sig,code = os.execute('ps -w > ' .. LOG_COLLECT_DIR .. '/' .. PROCESS_LIST_FILENAME)
-- capture info on RAM memory
rv,sig,code = os.execute('cat /proc/meminfo > ' .. LOG_COLLECT_DIR .. '/' .. MEMINFO_FILENAME)
-- capture info on mounted file systems
rv,sig,code = os.execute('mount > ' .. LOG_COLLECT_DIR .. '/' .. MOUNTS_FILENAME)
-- capture info on free disk space
rv,sig,code = os.execute('df -h > ' .. LOG_COLLECT_DIR .. '/' .. DISKFREE_FILENAME)
-- list directory structure for primary USB controller
rv,sig,code = os.execute(USB_DIRTREE_COMMAND .. ' > ' .. LOG_COLLECT_DIR .. '/' .. USB_DIRTREE_FILENAME)
rv,sig,code = redirectedExecute('cp ' .. WIFIBOX_VERSION_FILE .. ' ' .. LOG_COLLECT_DIR)
-- copy relevant openwrt configuration files
-- Note: we cannot link them because that would require the link to span over filesystems
rv,msg = lfs.mkdir(LOG_COLLECT_DIR .. '/config')
for _,v in pairs(UCI_CONFIG_FILES_TO_SAVE) do
local srcFile = '/etc/config/' .. v
local tgtFile = LOG_COLLECT_DIR .. '/config/' .. v
if v ~= 'wireless' then
rv,sig,code = redirectedExecute('cp ' .. srcFile .. ' ' .. tgtFile)
else
-- replace WiFi passwords with '...'
rv,sig,code = os.execute("sed \"s/option key '.*'/option key '...'/g\" " .. srcFile .. " > " .. tgtFile)
end
end
-- create tar.gz archive of the files/data we collected
rv,sig,code = redirectedExecute('tar czf ' .. LOG_COLLECT_ARCHIVE_FILE .. ' ' .. LOG_COLLECT_DIRNAME) --returns 0 success, 1 error
--[[ add response content ]]--
rv,msg = response:setBinaryFileData(LOG_COLLECT_ARCHIVE_FILE, LOG_COLLECT_ARCHIVE_FILENAME, 'application/x-compressed')
if not rv then
response:setError("could not set binary data from file '" .. LOG_COLLECT_ARCHIVE_FILE .. "' (" .. msg .. ")")
else
response:setSuccess()
end
--[[ remove temporary files ]]--
for file in lfs.dir(LOG_COLLECT_DIR) do
if file:find(PRINT3D_LOG_FILENAME_PREFIX) == 1 and file:find(PRINT3D_LOG_FILENAME_SUFFIX) ~= nil then
local tgtLogFile = LOG_COLLECT_DIR .. '/' .. file
rv,sig,code = redirectedExecute('rm ' .. tgtLogFile)
end
end
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/config/*')
rv,msg = lfs.rmdir(LOG_COLLECT_DIR .. '/config')
-- Note: this assumes the rotated logs directory does not contain subdirectories
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. ROTATED_LOGS_DIRNAME .. '/*')
rv,msg = lfs.rmdir(LOG_COLLECT_DIR .. '/' .. ROTATED_LOGS_DIRNAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. WIFIBOX_VERSION_FILENAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. USB_DIRTREE_FILENAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. DISKFREE_FILENAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. MOUNTS_FILENAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. MEMINFO_FILENAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. PROCESS_LIST_FILENAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. SYSLOG_FILENAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. WIFIBOX_STDOUT_LOG_FILENAME)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_DIR .. '/' .. wifiboxLogFileName)
rv,msg = lfs.rmdir(LOG_COLLECT_DIR)
rv,sig,code = redirectedExecute('rm ' .. LOG_COLLECT_ARCHIVE_FILE)
end
function M.access(request, response)
--log:info(MOD_ABBR, " remoteAddress: |"..utils.dump(request.remoteAddress).."|");
--log:info(MOD_ABBR, " controller: |"..utils.dump(accessManager.getController()).."|");
local hasControl = accessManager.hasControl(request.remoteAddress)
-- if hasControl then log:info(MOD_ABBR, " hasControl: true")
-- else log:info(MOD_ABBR, " hasControl: false") end
response:setSuccess()
response:addData('has_control', hasControl)
return
end
function M.status(request, response)
local rv, state = printerAPI.state(request, response)
if(rv == false) then return end
if state ~= "disconnected" and state ~= "connecting" then
rv = printerAPI.temperature(request, response)
if(rv == false) then return end
rv = printerAPI.progress(request, response)
if(rv == false) then return end
rv = M.access(request, response)
if(rv == false) then return end
end
end
return M