From 4b82433c8a6149f14e24bdca209bfcf54cedbaa3 Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Tue, 13 May 2008 20:02:56 +0000 Subject: Rewrote syslog to use components and remove view-specific code from controller. Also made sure not to write to conf file unless all variables pass validation. git-svn-id: svn://svn.alpinelinux.org/acf/alpine-baselayout/trunk@1116 ab2d0c66-481e-0410-8bed-d214d4d58bed --- syslog-model.lua | 262 +++++++++++++++++++++++-------------------------------- 1 file changed, 111 insertions(+), 151 deletions(-) (limited to 'syslog-model.lua') diff --git a/syslog-model.lua b/syslog-model.lua index c5e1108..a77986b 100644 --- a/syslog-model.lua +++ b/syslog-model.lua @@ -9,10 +9,9 @@ require("validator") local configfile = "/etc/conf.d/syslog" local processname = "syslog" -local config = {} local function get_version() - local cmd = "/sbin/apk_version -v -s busybox | cut -d ' ' -f 1" + local cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin apk_version -v -s busybox | cut -d ' ' -f 1" local cmd_output = io.popen( cmd ) local cmd_output_result = cmd_output:read("*a") or "" cmd_output:close() @@ -22,49 +21,85 @@ end local function getloglevels() local loglevels = {} for i=1,8 do - table.insert(loglevels,i) + table.insert(loglevels,tostring(i)) end return loglevels end + +local writeconfig = function (config) + -- Set variables + local variable = "SYSLOGD_OPTS" + local variabletranslator = { + logfile = "-O", + loglevel = "-l", + smallerlogs = "-S", + maxsize = "-s", + numrotate = "-b", + localandnetworklog = "-L", + remotelogging = "-R", + } + + local configdata = {} + + for name, entry in pairs(variabletranslator) do + if config.value[name] and config.value[name].type == "boolean" then + if config.value[name].value then configdata[entry] = "" end + elseif config.value[name] and config.value[name].value and #config.value[name].value > 0 then + configdata[entry] = config.value[name].value + else + configdata[entry] = nil + end + end + + local cmdresult, cmdmessage, cmderror = getopts.setoptsinfile(configfile,"",variable,'"' .. getopts.table_to_opts(configdata) .. '"') + return cmdmessage, cmderror +end + -- ################################################################################ -- PUBLIC FUNCTIONS --- action should be a CFE function startstop_service ( self, action ) - local cmd = action.value - local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol(processname, cmd) - action.descr=cmdmessage - action.errtxt=cmderror - -- Reporting back (true|false, the original acition) - return cmdresult,action - + local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol(processname, action) + return cfe({ type="boolean", value=cmdresult, descr=cmdmessage, errtxt=cmderror, label=action.." result" }) end -function getstatus() - local opts = getconfig() - local status = {} - status.version = cfe({ name = "version", +function getversion() + return cfe({ label="Program version", value=get_version(), }) - status.status = cfe({ name="status", +end + +function getstatus() + local status = cfe({ label="Program status", value=procps.pidof("syslogd"), }) - if (opts["remotelogging"]) and not ((opts["remotelogging"]["value"] ~= "") and not (opts["localandnetworklog"]["value"])) then - status.logfile = cfe({ name="logfile", + if (#status.value > 0) then + status.value = "Enabled" + else + status.value = "Disabled" + end + return status +end + +function getlogging() + local status = {} + local opts = getconfig() + if (opts.value.remotelogging.value == "") or (opts.value.localandnetworklog.value) then + status.logfile = cfe({ label="Locally logging to", - value=opts["logfile"]["value"], + value=opts.value.logfile.value, }) end - if (opts["SYSLOGD_OPTS"]) and (opts["SYSLOGD_OPTS"]["-R"]) and (opts["SYSLOGD_OPTS"]["-R"] ~= "") then - status.remote = cfe({ name="remotelogging", + if (opts.value.remotelogging.value ~= "") then + status.remote = cfe({ label="Remote logging to", - value=opts["SYSLOGD_OPTS"]["-R"], + value=opts.value.remotelogging.value, }) end - return status + return cfe({ type="group", value=status }) end function get_filedetails() @@ -73,200 +108,125 @@ function get_filedetails() local config = getconfig(path) local file = {} file["filename"] = cfe({ - name="filename", label="File name", value=path, }) file["filesize"] = cfe({ - name="filesize", label="File size", - value=filedetails.size or 0, + value=filedetails.size or "0", }) file["mtime"] = cfe({ - name="mtime", label="File date", value=filedetails.mtime or "---", }) file["filecontent"] = cfe({ type="longtext", - name="filecontent", label="File content", value=fs.read_file(path), }) - file["sumerrors"] = config.sumerrors - - return file + return cfe({ type="group", value=file, label="Config file details" }) end + function getconfig() local config = {} if (fs.is_file(configfile)) then configcontent = getopts.getoptsfromfile(configfile, "", "SYSLOGD_OPTS", true) or {} else - config["configfile"] = "Config file '".. configfile .. "' is missing!" + config["errtxt"] = "Config file '".. configfile .. "' is missing!" end -- Next section selects which configurations we should show to the user config["logfile"] = cfe({ - name="logfile", label = "Log to given file", + descr = "File must be in /var/log directory", value = configcontent["-O"] or "/var/log/messages", }) config["loglevel"] = cfe({ - name="loglevel", label = "Set local log level", - value = tonumber(configcontent["-l"]) or 8, + value = configcontent["-l"] or "8", type = "select", option = getloglevels(), descr = "1=Quiet, ... , " .. table.maxn(getloglevels()) .. "=Debug", }) config["smallerlogs"] = cfe({ - name="smallerlogs", label = "Smaller logging output", - checked = configcontent["-S"], - value = "smallerlogs", - type = "checkbox", + value = (configcontent["-S"] == ""), + type = "boolean", }) config["maxsize"] = cfe ({ - name="maxsize", label = "Max size (KB) before rotate", descr = "Default=200KB, 0=off", - value = configcontent["-s"], + value = configcontent["-s"] or "", }) - config["numrotate"] = cfe ({ name="numrotate", + config["numrotate"] = cfe ({ label = "Number of rotated logs to keep", descr = "Default=1, max=99, 0=purge", - value = configcontent["-b"], + value = configcontent["-b"] or "", }) config["localandnetworklog"] = cfe ({ - name="localandnetworklog", label = "Log locally and via network", - checked = configcontent["-L"], - value = "localandnetworklog", - type = "checkbox", - descr = "Default is network only if -R", + value = (configcontent["-L"] == ""), + type = "boolean", + descr = "Default is network only if host[:PORT] is defined", }) config["remotelogging"] = cfe ({ - name="remotelogging", label = "Log to IP or hostname on PORT", descr = "host[:PORT] - Default PORT=514/UDP", - value = configcontent["-R"], + value = configcontent["-R"] or "", }) - -- Next section is to print errormessages when configs are wrong - if (configcontent["-l"]) and - ((tonumber(configcontent["-l"]) == nil) or (tonumber(configcontent["-l"]) > 8)) then - config["loglevel"]["errtxt"] = "Log value is out of range!\nCurrent value in config is '" .. - configcontent["-l"] .. - "' - This is invalid!\nPlease select one of the above and save your changes." - table.insert(config["loglevel"]["option"], tonumber(configcontent["-l"])) - end + return cfe({ type="group", value=config, label="Configuration" }) +end - if (configcontent["-L"] ~= nil) and ((configcontent["-R"] == nil) or (configcontent["-R"] == "")) then - config["localandnetworklog"]["errtxt"] = "Logging to local and network (-L) is not possible unless you define a host (-R) for remote logging or remove this option." +function updateconfig (clientdata) + local config = getconfig() + local success = true + for name in pairs(config.value) do + if config.value[name].type == "boolean" then + config.value[name].value = (clientdata[name] == "true") + elseif clientdata[name] then + config.value[name].value = clientdata[name] + end end - -- Sum all errors into one cfe - local sumerrors = "" - for k,v in pairs(config) do - if (config[k]["errtxt"]) then - sumerrors = sumerrors .. config[k]["errtxt"] .. "\n" - end + -- Validate entries and create error strings + if not validator.is_valid_filename(config.value.logfile.value, "/var/log") then + config.value.logfile.errtxt = "Not a valid file name in /var/log" + success = false end - if (sumerrors ~= "") then - config["sumerrors"] = cfe ({ - name="sumerrors", - label = "Configuration errors", - errtxt = sumerrors, - }) + if not validator.is_integer_in_range(config.value.loglevel.value, 1, 8) then + config.value.loglevel.errtxt = "Out of range!" + success = false end - - return config -end - --- IMPORTANT! This function is a exception! It's not fed with CFE's --- Parameter should be one of the ones defined in the variable 'variabletranslator'. --- value should be whatever the new value should be. -function setconfigs(self,parameter,value) - -- Set variables - local variable = "SYSLOGD_OPTS" - local variabletranslator = ({ - logfile = "-O", - loglevel = "-l", - smallerlogs = "-S", - maxsize = "-s", - numrotate = "-b", - localandnetworklog = "-L", - remotelogging = "-R", - }) - cmdparameter = variabletranslator[parameter] - - -- Report a error if someone tryes to use a invalid parameter - if not (cmdparameter) then - local availablevariables = "" - for k,v in pairs(variabletranslator) do - availablevariables = k .. ", " .. availablevariables - end - parameter = parameter or "" - return false, cfe({ - name="syslog.model.setconfigs()", - errtxt="'" .. parameter .. "' is not a valid parameter!\nValid options are: " .. availablevariables, - }) + if config.value.maxsize.value ~= "" and not validator.is_integer(config.value.maxsize.value) then + config.value.maxsize.errtxt = "Must be an integer" + success = false end - - --TODO: Validate so that user cant add values with '-' (could cause major breakage next time you do getopts) - - -- This config-file only accepts one type of parameters (report error if someone uses wrong parameter) - if not (string.find(cmdparameter, "-%a$")) then - return false, cfe({ - name="syslog.model.setconfigs()", - errtxt="Parameter must be formated '-a' (where a is one upper/lowercase letter [a-z])", - }) + if config.value.numrotate.value ~= "" and not validator.is_integer_in_range(config.value.numrotate.value, 0, 99) then + config.value.numrotate.errtxt = "Out of range!" + success = false end - - -- Validate userinput (if valid path/filename) - if (value) and (cmdparameter == "-O") then - local cmdresult, cmdmessage = validator.is_valid_filename(value, "/var/log" ) - if not (cmdresult) then - return false, cfe({ - name="syslog.model.setconfigs()", - errtxt=cmdmessage, - }) - end + if config.value.localandnetworklog.value == true and config.value.remotelogging.value == "" then + config.value.localandnetworklog.errtxt = "Logging to local and network is not possible unless you define a host for remote logging" + success = false end - - -- Validate userinput (Has the user entered a valid hostname and/or port) - if (value) and (cmdparameter == "-R") then - local hostport = format.string_to_table(value, ":") - local host = hostport[1] - local port = hostport[2] - if (port) and not (validator.is_port(port)) then - return false, cfe({ - name="syslog.model.setconfigs.getopts.setoptsinfile()", - errtxt="You entered '" .. tostring(port) .. "' as port - This is not valid!", - }) - end + local hostport = format.string_to_table(config.value.remotelogging.value, ":") + if hostport[2] and not (validator.is_port(hostport[2])) then + config.value.remotelogging.errtxt = "Not a valid port" + success = false end - -- Set/Unset checkbox variables - if (value) and ((cmdparameter == "-S") or (cmdparameter == "-L")) then value = "" end - - local cmdresult, cmdmessage, cmderror = getopts.setoptsinfile(configfile,"",variable,cmdparameter,true,value) - if (cmderror) then - return false, cfe({ - name="syslog.model.setconfigs.getopts.setoptsinfile()", - errtxt=cmderror, - }) + if success == true then + config.descr, config.errtxt = writeconfig(config) + else + config.errtxt = "Failed to save config!" end - return true, cfe({ - name="syslog.model.setconfigs()", - value=cmdmessage, - }) + + return config end --- modifications should be a CFE function update_filecontent (self, modifications) local path = configfile - local file_result,err = fs.write_file(path, format.dostounix(modifications)) - return file_result, err + fs.write_file(path, format.dostounix(modifications)) end -- cgit v1.2.3