From: Jo-Philipp Wich Date: Sun, 17 Aug 2008 17:40:57 +0000 (+0000) Subject: * luci/libs: uvl: add support for external validation commands, various cleanups X-Git-Tag: 0.8.0~383 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=1d08361bea91c11ba2f82f3ab3004c067ebabc85;p=oweals%2Fluci.git * luci/libs: uvl: add support for external validation commands, various cleanups --- diff --git a/libs/uvl/luasrc/uvl.lua b/libs/uvl/luasrc/uvl.lua index d778cfc3a..aa3aeb361 100644 --- a/libs/uvl/luasrc/uvl.lua +++ b/libs/uvl/luasrc/uvl.lua @@ -21,15 +21,16 @@ require("luci.util") require("luci.model.uci") require("luci.uvl.loghelper") require("luci.uvl.datatypes") ---require("luci.uvl.validation") +require("luci.uvl.validation") require("luci.uvl.dependencies") TYPE_SECTION = 0x01 TYPE_VARIABLE = 0x02 TYPE_ENUM = 0x03 -STRICT_UNKNOWN_SECTIONS = true -STRICT_UNKNOWN_OPTIONS = true +STRICT_UNKNOWN_SECTIONS = true +STRICT_UNKNOWN_OPTIONS = true +STRICT_EXTERNAL_VALIDATORS = true local default_schemedir = "/etc/scheme" @@ -242,6 +243,11 @@ function UVL._validate_option( self, option, nodeps ) if not nodeps then return luci.uvl.dependencies.check( self, option ) end + + local ok, err = luci.uvl.validation.check( self, option ) + if not ok and STRICT_EXTERNAL_VALIDATORS then + return false, self.log.validator_error( option, err ) + end end return true, nil @@ -353,6 +359,10 @@ function UVL._read_scheme_parts( self, scheme, schemes ) end end end + + s.dynamic = s.dynamic or false + s.unique = s.unique or false + s.required = s.required or false end end end @@ -402,6 +412,7 @@ function UVL._read_scheme_parts( self, scheme, schemes ) end t.type = t.type or "variable" + t.datatype = t.datatype or "string" t.required = t.required or false end end @@ -485,22 +496,24 @@ end -- Read a validator specification function UVL._read_validator( self, value, validators ) - local validator - - if value and value:match("/") and self.datatypes.file(value) then - validator = value - else - validator = self:_resolve_function( value ) - end + if value then + local validator - if validator then - if not validators then - validators = { validator } - else - table.insert( validators, validator ) + if value:match("^exec:") then + validator = value:gsub("^exec:","") + elseif value:match("^lua:") then + validator = self:_resolve_function( (value:gsub("^lua:","") ) ) end - return validators + if validator then + if not validators then + validators = { validator } + else + table.insert( validators, validator ) + end + + return validators + end end end diff --git a/libs/uvl/luasrc/uvl/dependencies.lua b/libs/uvl/luasrc/uvl/dependencies.lua index 217f29588..ced275e6b 100644 --- a/libs/uvl/luasrc/uvl/dependencies.lua +++ b/libs/uvl/luasrc/uvl/dependencies.lua @@ -16,15 +16,6 @@ $Id$ module( "luci.uvl.dependencies", package.seeall ) -local function _assert( condition, fmt, ... ) - if not condition then - return assert( nil, string.format( fmt, ... ) ) - else - return condition - end -end - - function _parse_reference( r, c, s, o ) local ref = { } local vars = { diff --git a/libs/uvl/luasrc/uvl/loghelper.lua b/libs/uvl/luasrc/uvl/loghelper.lua index 9ec57f132..001664e13 100644 --- a/libs/uvl/luasrc/uvl/loghelper.lua +++ b/libs/uvl/luasrc/uvl/loghelper.lua @@ -30,6 +30,13 @@ function section_error( section, message ) ) end +function validator_error( option, message ) + return string.format( + 'External validator in option "%s" failed:\n%s', + option:cid(), message or "Unknown error" + ) +end + function dump_dependency( dep, ref, v, e ) local str = nil @@ -46,7 +53,7 @@ function dump_dependency( dep, ref, v, e ) str = string.format( '%s) failed:\n\t%s', - str, e or string.format( + str, e and e:gsub("\n","\n\t") or string.format( 'Option "%s" %s', table.concat( ref, "." ), ( type(v) == "boolean" diff --git a/libs/uvl/luasrc/uvl/validation.lua b/libs/uvl/luasrc/uvl/validation.lua new file mode 100644 index 000000000..39f152753 --- /dev/null +++ b/libs/uvl/luasrc/uvl/validation.lua @@ -0,0 +1,65 @@ +--[[ + +UCI Validation Layer - Validation helper +(c) 2008 Jo-Philipp Wich +(c) 2008 Steven Barth + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ + +]]-- + +module( "luci.uvl.validation", package.seeall ) + +require("luci.fs") +require("luci.sys") + + +function _exec( bin, args ) + local cmd, output = "", nil + + for _, v in ipairs({ bin, unpack(args) }) do + cmd = cmd .. string.format("%q ",v):gsub("([%$`])","\\%1") + end + + local tmpfile = "/tmp/uvl" .. luci.sys.uniqueid(8) + local retval = os.execute( cmd .. " 1>" .. tmpfile .. " 2>" .. tmpfile ) + + if luci.fs.access(tmpfile) then + output = luci.fs.readfile(tmpfile) + luci.fs.unlink(tmpfile) + end + + return retval, output +end + +function check( self, object ) + local item = object:option() + + if item.validators then + for _, val in ipairs(item.validators) do + local ok, err = false, nil + local args = { + item.type, unpack(object.cref), item.datatype, object:value() + } + + if type(val) == "function" then + ok, err = val(unpack(args)) + else + ok, err = _exec( val, args ) + ok = ( ok == 0 ) + end + + if not ok then + return false, err + end + end + end + + return true, nil +end