From d7b95a555baac0a815bfb8975648f7435c4a0754 Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Sat, 16 Aug 2008 20:18:14 +0000 Subject: [PATCH] Added process control page Minor improvements --- i18n/english/luasrc/i18n/admin-core.en.lua | 14 +++++- i18n/german/luasrc/i18n/admin-core.de.lua | 13 ++++- libs/cbi/luasrc/cbi.lua | 43 +++++++++++++---- libs/cbi/luasrc/view/cbi/button.htm | 17 +++++++ libs/cbi/luasrc/view/cbi/cell_valuefooter.htm | 6 ++- libs/cbi/luasrc/view/cbi/full_valuefooter.htm | 8 ++-- libs/sys/luasrc/sys.lua | 47 +++++++++++++++++++ .../luasrc/controller/admin/system.lua | 3 +- .../model/cbi/admin_system/processes.lua | 44 +++++++++++++++++ 9 files changed, 180 insertions(+), 15 deletions(-) create mode 100644 libs/cbi/luasrc/view/cbi/button.htm create mode 100644 modules/admin-full/luasrc/model/cbi/admin_system/processes.lua diff --git a/i18n/english/luasrc/i18n/admin-core.en.lua b/i18n/english/luasrc/i18n/admin-core.en.lua index ec03aface..0ab6f995a 100644 --- a/i18n/english/luasrc/i18n/admin-core.en.lua +++ b/i18n/english/luasrc/i18n/admin-core.en.lua @@ -34,7 +34,8 @@ routes_metric = [[Metric]] a_s_desc = [[Here you can configure the basic aspects of your device like its hostname or the timezone.]] a_s_packages = [[Software]] a_s_changepw = [[Admin Password]] -a_s_p_ipkg = [[IPKG-Configuration]] +--a_s_p_ipkg = [[IPKG-Configuration]] +a_s_p_ipkg = [[IPKG-Configuration]] a_s_sshkeys = [[SSH-Keys]] a_s_fstab = [[Mount Points]] a_s_flash = [[Flash Firmware]] @@ -260,3 +261,14 @@ network_interface_err = [[Errors]] network_interface_err_desc = [[TX / RX]] network_interface_fwzone = [[Create / Assign firewall-zone]] network_interface_fwzone_desc = [[This interface does not belong to any firewall zone yet.]] + +process_head = "Processes" +process_descr = "This list gives an overview over currently running system processes and their status." +process_pid = "PID" +process_owner = "Owner" +process_command = "Command" +process_cpu = "CPU usage (%)" +process_mem = "Memory usage (%)" +process_hup = "Hang Up" +process_term = "Terminate" +process_kill = "Kill" \ No newline at end of file diff --git a/i18n/german/luasrc/i18n/admin-core.de.lua b/i18n/german/luasrc/i18n/admin-core.de.lua index a6a652de7..e5e01a4a5 100644 --- a/i18n/german/luasrc/i18n/admin-core.de.lua +++ b/i18n/german/luasrc/i18n/admin-core.de.lua @@ -335,4 +335,15 @@ network_interface_err = "Fehler" network_interface_err_desc = "TX / RX" network_interface_fwzone = "Firewallzone anlegen / zuweisen" -network_interface_fwzone_desc = "Diese Schnittstelle gehört bis jetzt zu keiner Firewallzone." \ No newline at end of file +network_interface_fwzone_desc = "Diese Schnittstelle gehört bis jetzt zu keiner Firewallzone." + +process_head = "Prozesse" +process_descr = "Diese Tabelle gibt eine Übersicht über aktuell laufende Systemprozeese und deren Status." +process_pid = "PID" +process_owner = "Besitzer" +process_command = "Befehl" +process_cpu = "CPU-Nutzung (%)" +process_mem = "Speichernutzung (%)" +process_hup = "Auflegen" +process_term = "Beenden" +process_kill = "Töten" \ No newline at end of file diff --git a/libs/cbi/luasrc/cbi.lua b/libs/cbi/luasrc/cbi.lua index 7e2f53c80..bf4bfb80c 100644 --- a/libs/cbi/luasrc/cbi.lua +++ b/libs/cbi/luasrc/cbi.lua @@ -287,7 +287,7 @@ function SimpleForm.parse(self, ...) or valid and 1 or -1 - self.dorender = self:handle(state, self.data) ~= false + self.dorender = not self.handle or self:handle(state, self.data) ~= false end function SimpleForm.render(self, ...) @@ -487,7 +487,11 @@ function Table.__init__(self, form, data, ...) self.data = data function datasource.get(self, section, option) - return data[section][option] + return data[section] and data[section][option] + end + + function datasource.del(...) + return true end AbstractSection.__init__(self, datasource, "table", ...) @@ -496,10 +500,18 @@ function Table.__init__(self, form, data, ...) self.anonymous = true end +function Table.parse(self) + for i, k in ipairs(self:cfgsections()) do + if luci.http.formvalue("cbi.submit") then + Node.parse(self, k) + end + end +end + function Table.cfgsections(self) local sections = {} - for i, v in pairs(self.data) do + for i, v in luci.util.kspairs(self.data) do table.insert(sections, i) end @@ -685,6 +697,7 @@ function AbstractValue.__init__(self, map, option, ...) self.config = map.config self.tag_invalid = {} self.tag_missing = {} + self.tag_error = {} self.deps = {} self.track_missing = false @@ -700,6 +713,11 @@ function AbstractValue.depends(self, field, value) table.insert(self.deps, {field=field, value=value}) end +-- Generates the unique CBID +function AbstractValue.cbid(self, section) + return "cbid."..self.map.config.."."..section.."."..self.option +end + -- Return whether this object should be created function AbstractValue.formcreated(self, section) local key = "cbi.opt."..self.config.."."..section @@ -708,8 +726,7 @@ end -- Returns the formvalue for this object function AbstractValue.formvalue(self, section) - local key = "cbid."..self.map.config.."."..section.."."..self.option - return luci.http.formvalue(key) + return luci.http.formvalue(self:cbid(section)) end function AbstractValue.additional(self, value) @@ -746,9 +763,7 @@ function AbstractValue.render(self, s, scope) if not self.optional or self:cfgvalue(s) or self:formcreated(s) then scope = scope or {} scope.section = s - scope.cbid = "cbid." .. self.config .. - "." .. s .. - "." .. self.option + scope.cbid = self:cbid(s) scope.ifattr = function(cond,key,val) if cond then @@ -965,3 +980,15 @@ function TextValue.__init__(self, ...) AbstractValue.__init__(self, ...) self.template = "cbi/tvalue" end + +--[[ +Button +]]-- +Button = class(AbstractValue) + +function Button.__init__(self, ...) + AbstractValue.__init__(self, ...) + self.template = "cbi/button" + self.inputstyle = nil + self.rmempty = true +end \ No newline at end of file diff --git a/libs/cbi/luasrc/view/cbi/button.htm b/libs/cbi/luasrc/view/cbi/button.htm new file mode 100644 index 000000000..2d740f45c --- /dev/null +++ b/libs/cbi/luasrc/view/cbi/button.htm @@ -0,0 +1,17 @@ +<%# +LuCI - Lua Configuration Interface +Copyright 2008 Steven Barth +Copyright 2008 Jo-Philipp Wich + +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$ + +-%> +<%+cbi/valueheader%> + class="cbi-input-<%=self.inputstyle%>"<% end %> type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.title) %> /> +<%+cbi/valuefooter%> diff --git a/libs/cbi/luasrc/view/cbi/cell_valuefooter.htm b/libs/cbi/luasrc/view/cbi/cell_valuefooter.htm index fbe266ebe..941214246 100644 --- a/libs/cbi/luasrc/view/cbi/cell_valuefooter.htm +++ b/libs/cbi/luasrc/view/cbi/cell_valuefooter.htm @@ -13,8 +13,12 @@ $Id$ -%> - <% if self.tag_invalid[section] then -%> + <% if self.tag_error[section] then -%> +
<%=self.tag_error[section]%>
+ <%- elseif self.tag_invalid[section] then -%>
<%:cbi_invalid%>
+ <%- elseif self.tag_missing[section] then -%> +
<%:cbi_missing%>
<%- end %> diff --git a/libs/cbi/luasrc/view/cbi/full_valuefooter.htm b/libs/cbi/luasrc/view/cbi/full_valuefooter.htm index a5a6046a5..5a52898d1 100644 --- a/libs/cbi/luasrc/view/cbi/full_valuefooter.htm +++ b/libs/cbi/luasrc/view/cbi/full_valuefooter.htm @@ -21,12 +21,14 @@ $Id$ <%- end -%> - <% if self.tag_invalid[section] then -%> + <% if self.tag_error[section] then -%> +
<%=self.tag_error[section]%>
+ <%- elseif self.tag_invalid[section] then -%>
<%:cbi_invalid%>
- <%- end %> - <% if self.tag_missing[section] then -%> + <%- elseif self.tag_missing[section] then -%>
<%:cbi_missing%>
<%- end %> + <% if #self.deps > 0 then -%> diff --git a/libs/sys/luasrc/sys.lua b/libs/sys/luasrc/sys.lua index 7357d4cfb..6b6ea7012 100644 --- a/libs/sys/luasrc/sys.lua +++ b/libs/sys/luasrc/sys.lua @@ -298,6 +298,46 @@ process = {} -- @return Number containing the current pid process.info = posix.getpid +--- Retrieve information about currently running processes. +-- @return Table containing process information +function process.list() + local data = {} + local k + local ps = luci.util.execi("top -bn1") + + if not ps then + return + end + + while true do + local line = ps() + if not line then + return + end + + k = luci.util.split(luci.util.trim(line), "%s+", nil, true) + if k[1] == "PID" then + break + end + end + + for line in ps do + local row = {} + + line = luci.util.trim(line) + for i, value in ipairs(luci.util.split(line, "%s+", #k-1, true)) do + row[k[i]] = value + end + + local pid = tonumber(row[k[1]]) + if pid then + data[pid] = row + end + end + + return data +end + --- Set the gid of a process identified by given pid. -- @param pid Number containing the process id -- @param gid Number containing the Unix group id @@ -318,6 +358,13 @@ function process.setuser(pid, uid) return posix.setpid("u", pid, uid) end +--- Send a signal to a process identified by given pid. +-- @param pid Number containing the process id +-- @param sig Signal to send (default: 15 [SIGTERM]) +-- @return Boolean indicating successful operation +-- @return Number containing the error code if failed +process.signal = posix.kill + --- LuCI system utilities / user related functions. -- @class module diff --git a/modules/admin-full/luasrc/controller/admin/system.lua b/modules/admin-full/luasrc/controller/admin/system.lua index 4303d86eb..6f2428000 100644 --- a/modules/admin-full/luasrc/controller/admin/system.lua +++ b/modules/admin-full/luasrc/controller/admin/system.lua @@ -23,6 +23,7 @@ function index() entry({"admin", "system", "passwd"}, form("admin_system/passwd"), i18n("a_s_changepw"), 20) entry({"admin", "system", "sshkeys"}, form("admin_system/sshkeys"), i18n("a_s_sshkeys"), 30) entry({"admin", "system", "system"}, cbi("admin_system/system"), i18n("system"), 40) + entry({"admin", "system", "processes"}, form("admin_system/processes"), i18n("process_head"), 45) entry({"admin", "system", "fstab"}, cbi("admin_system/fstab"), i18n("a_s_fstab"), 50) entry({"admin", "system", "leds"}, cbi("admin_system/leds"), i18n("leds", "LEDs"), 60) entry({"admin", "system", "backup"}, call("action_backup"), i18n("a_s_backup"), 70) @@ -85,7 +86,7 @@ function action_packages() -- Package info - local info = luci.model.ipkg.info(query) + local info = luci.model.ipkg.info("*"..query.."*") info = info or {} local pkgs = {} diff --git a/modules/admin-full/luasrc/model/cbi/admin_system/processes.lua b/modules/admin-full/luasrc/model/cbi/admin_system/processes.lua new file mode 100644 index 000000000..8ec027d11 --- /dev/null +++ b/modules/admin-full/luasrc/model/cbi/admin_system/processes.lua @@ -0,0 +1,44 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2008 Steven Barth +Copyright 2008 Jo-Philipp Wich + +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$ +]]-- +f = SimpleForm("processes", translate("process_head"), translate("process_descr")) +f.reset = false +f.submit = false + +t = f:section(Table, luci.sys.process.list()) +t:option(DummyValue, "PID", translate("process_pid")) +t:option(DummyValue, "USER", translate("process_owner")) +t:option(DummyValue, "COMMAND", translate("process_command")) +t:option(DummyValue, "%CPU", translate("process_cpu")) +t:option(DummyValue, "%MEM", translate("process_mem")) + +hup = t:option(Button, "_hup", translate("process_hup")) +hup.inputstyle = "reload" +function hup.write(self, section) + null, self.tag_error[section] = luci.sys.process.signal(section, 1) +end + +term = t:option(Button, "_term", translate("process_term")) +term.inputstyle = "remove" +function term.write(self, section) + null, self.tag_error[section] = luci.sys.process.signal(section, 15) +end + +kill = t:option(Button, "_kill", translate("process_kill")) +kill.inputstyle = "reset" +function kill.write(self, section) + null, self.tag_error[section] = luci.sys.process.signal(section, 9) +end + +return f \ No newline at end of file -- 2.25.1