update-12.04

This commit is contained in:
github-actions[bot]
2021-12-04 09:01:13 +08:00
parent d9bed163f5
commit 96e6f38956
110 changed files with 14091 additions and 382 deletions

View File

@@ -0,0 +1,16 @@
# Copyright (C) 2016 Openwrt.org
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for NginxManager From sundaqiang
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=20211102
PKG_MAINTAINER:=sundaqiang
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@@ -0,0 +1,27 @@
# luci-app-supervisord进程管理器
一款面向Luci的简单的任务管理器基于 [supervisord](https://github.com/ochinchina/supervisord)
### 特性
- 这是一款进程管理软件类似于pm2
- 需求主要是部分插件是调用项目的成品,设置项少的其实自己下载更新也蛮不错
- nodejs和python的程序也可以在这里运行前提是你固件已经有编译好nodejs和python
- 插件没附带二进制文件,第一次使用需要直接点按钮更新。如果更新失败,自行去项目下载二进制文件。
- 配置文件说明:
```ini
;需要备份文件的完整路径,多个文件以||分割,必须
;backupfile=/usr/bin/xxxxx||/etc/yyyyy
backupfile=
;获取版本号命令,必须
;getversions=xxxxx version
getversions=
```
### 效果展示
![supervisord-1][1]
![supervisord-2][2]
[1]: https://raw.githubusercontent.com/sundaqiang/openwrt-packages/master/img/supervisord-1.png
[2]: https://raw.githubusercontent.com/sundaqiang/openwrt-packages/master/img/supervisord-2.png

View File

@@ -0,0 +1,234 @@
module("luci.controller.supervisord", package.seeall)
function index()
if not nixio.fs.access("/etc/config/supervisord") then return end
entry({"admin", "services", "supervisord"}, cbi("supervisord"), _("Supervisord"), 95).dependent = true
entry({"admin", "services", "supervisord", "status"}, call("status")).leaf = true
entry({"admin", "services", "supervisord", "getver"}, call("getver")).leaf = true
entry({"admin", "services", "supervisord", "update"}, call("update")).leaf = true
entry({"admin", "services", "supervisord", "gettask"}, call("gettask")).leaf = true
entry({"admin", "services", "supervisord", "starttask"}, call("starttask")).leaf = true
entry({"admin", "services", "supervisord", "restarttask"}, call("restarttask")).leaf = true
entry({"admin", "services", "supervisord", "stoptask"}, call("stoptask")).leaf = true
entry({"admin", "services", "supervisord", "removetask"}, call("removetask")).leaf = true
entry({"admin", "services", "supervisord", "addtask"}, call("addtask")).leaf = true
entry({"admin", "services", "supervisord", "savetask"}, call("savetask")).leaf = true
entry({"admin", "services", "supervisord", "getlog"}, call("getlog")).leaf = true
end
function Split(str, delim, maxNb)
-- Eliminate bad cases...
if string.find(str, delim) == nil then
return { str }
end
if maxNb == nil or maxNb < 1 then
maxNb = 0 -- No limit
end
local result = {}
local pat = "(.-)" .. delim .. "()"
local nb = 0
local lastPos
for part, pos in string.gfind(str, pat) do
nb = nb + 1
result[nb] = part
lastPos = pos
if nb == maxNb then break end
end
-- Handle the last field
if nb ~= maxNb then
result[nb + 1] = string.sub(str, lastPos)
end
return result
end
function status()
local e = {}
e.running = luci.sys.call("ps | grep supervisord | grep -v grep >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function getver()
local e = {}
local c=luci.model.uci.cursor()
local d=c:get("supervisord", "main", "filepath")
e.nowver=luci.sys.exec(d .. " version")
e.newver=luci.sys.exec("uclient-fetch -qO- 'https://api.github.com/repos/ochinchina/supervisord/releases/latest' | jsonfilter -e '@.tag_name'")
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function update()
local e = {}
local c=luci.model.uci.cursor()
local d=c:get("supervisord", "main", "filepath")
local version = luci.http.formvalue('version')
local arch = nixio.uname().machine or ""
version = version:gsub("\n", "")
if nixio.fs.access("/usr/lib/os-release") then
LEDE_BOARD = luci.sys.exec("echo -n $(grep 'LEDE_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}')")
end
if nixio.fs.access("/etc/openwrt_release") then
DISTRIB_TARGET = luci.sys.exec("echo -n $(grep 'DISTRIB_TARGET' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}')")
end
arch=luci.util.trim(arch)
if arch == "x86_64" then
arch = "64-bit"
end
filename = "supervisord_" .. version:gsub("v", "") .. "_Linux_" .. arch .. ".tar.gz"
nixio.fs.remove("/tmp/" .. filename)
u=c:get("supervisord", "main", "usechinamirror")
if u then
u="https://ghproxy.com/"
else
u=""
end
e.error=luci.sys.call("uclient-fetch -qO- -O '/tmp/" .. filename .. "' '" .. u .. "https://github.com/ochinchina/supervisord/releases/download/" .. version .. "/" .. filename .. "'")
if e.error == 0 then
e.error=luci.sys.exec("tar -xzvf '/tmp/" .. filename .. "' -C /tmp")
if e.error then
e.error=nixio.fs.mover("/tmp/" .. filename:gsub(".tar.gz", "") .. "/supervisord", d)
if e.error then
e.error=0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
else
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
else
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
end
function gettask()
local e = {}
local name = luci.http.formvalue('name')
local data = luci.sys.exec("supervisord ctl status " .. name)
e.status=string.gsub(string.sub(data, 34, 50), " ", "")
e.description=string.sub(data, 51)
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function starttask()
local e = {}
local name = luci.http.formvalue('name')
local data = luci.sys.exec("supervisord ctl start " .. name)
if string.find(data,"started") ~= nil then
e.code=1
else
e.code=0
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function restarttask()
local e = {}
local name = luci.http.formvalue('name')
local data = luci.sys.exec("supervisord ctl stop " .. name .. " && supervisord ctl start " .. name)
if string.find(data,"started") ~= nil then
e.code=1
else
e.code=0
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function stoptask()
local e = {}
local name = luci.http.formvalue('name')
local data = luci.sys.exec("supervisord ctl stop " .. name)
if string.find(data,"stopped") ~= nil then
e.code=1
else
e.code=0
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function removetask()
local e = {}
local name = luci.http.formvalue('name')
e.code=nixio.fs.remove('/etc/supervisord/program/' .. name .. '.ini')
if e.code then
luci.sys.call("supervisord ctl reload")
e.code=1
else
e.code=0
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function addtask()
local e = {}
local name = luci.http.formvalue('name')
if nixio.fs.access('/etc/supervisord/program/' .. name .. '.ini') then
e.code=2
luci.http.prepare_content("application/json")
luci.http.write_json(e)
return
end
file=nixio.fs.readfile("/etc/supervisord/program/templates")
file=file:gsub("demo", name)
e.code=nixio.fs.writefile('/etc/supervisord/program/' .. name .. '.ini', file)
if e.code then
luci.sys.call("supervisord ctl reload")
e.code=1
e.data=file
else
e.code=0
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function savetask()
local e = {}
local name = luci.http.formvalue('name')
local data = luci.http.formvalue('data')
data = data:gsub("\r\n?", "\n")
file = '/etc/supervisord/program/' .. name .. '.ini'
e.code=nixio.fs.writefile (file, data)
if e.code then
sysupgrade=nixio.fs.readfile("/etc/sysupgrade.conf")
if not sysupgrade:find(file) then
sysupgrade=sysupgrade .. '\n' .. file
end
backupfile=data:match("backupfile=([%a%d%p]+)")
backupfile=Split(backupfile, "||")
for k, v in ipairs(backupfile) do
if not sysupgrade:find(v:gsub("%p", "%%%1")) then
sysupgrade=sysupgrade .. '\n' .. v
end
end
nixio.fs.writefile ("/etc/sysupgrade.conf", sysupgrade)
luci.sys.call("supervisord ctl reload")
e.code=1
else
e.code=0
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function getlog()
local e = {}
local name = luci.http.formvalue('name')
if name=="main" then
local data = nixio.fs.readfile ('/etc/supervisord/supervisord.conf')
data = string.match(data, "logfile=([%a%d%p]+)")
e.data=nixio.fs.readfile (data)
else
local data = nixio.fs.readfile ('/etc/supervisord/program/' .. name .. '.ini')
data = string.match(data, "stdout_logfile=([%a%d%p]+)")
e.data=nixio.fs.readfile (data)
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@@ -0,0 +1,70 @@
local fs = require "nixio.fs"
local sys = require "luci.sys"
local m = Map("supervisord",translate("Supervisord"), translate("A golang development process management") .. [[<br /><br /><a href="https://github.com/sundaqiang/openwrt-packages" target="_blank">Powered by sundaqiang</a>]])
m:section(SimpleSection).template = "supervisord/index"
s = m:section(TypedSection, "supervisord")
s.addremove = false
s.anonymous = true
s:tab("general", translate("General Settings"))
s:tab("advanced", translate("Configuration File"))
s:tab("list", translate("Task List"))
s:tab("log", translate("Log List"))
f = s:taboption("general", Flag, "enabled", translate("Enabled"))
f.rmempty = false
v = s:taboption("general", Value, "filepath", translate("File Path"))
v.rmempty = false
v = s:taboption("general", Flag, "usechinamirror", translate("Use China Mirror"))
v.rmempty = false
b = s:taboption("general", Button, "")
b.template = "supervisord/version"
file=s:taboption("advanced", TextValue, "")
file.template = "cbi/tvalue"
file.rows = 15
file.wrap = "off"
file.rmempty = false
l=s:taboption("list", DummyValue, "")
l.template = "supervisord/list"
l.list={}
index=1
for filelist in fs.dir("/etc/supervisord/program") do
if filelist:find(".ini$") ~= nil then
name=fs.readfile("/etc/supervisord/program/" .. filelist)
l.list[index]={}
l.list[index][1]=name:match("program:(%a+)")
l.list[index][2]="/etc/supervisord/program/" .. filelist
local cmd=name:match("directory=([%a%d%p ]+)") .. "/" .. name:match("getversions=([%a%d%p ]+)")
l.list[index][3]=sys.exec(cmd)
index=index+1
end
end
g=s:taboption("log", DummyValue, "")
g.template = "supervisord/log"
g.list=l.list
function s.create(self,section)
return TypedSection.create(self,section)
end
function s.remove(self,section)
return TypedSection.remove(self,section)
end
function sync_value_to_file(self, section, value, file)
value = value:gsub("\r\n?", "\n")
local old_value = fs.readfile(file)
if value ~= old_value then
fs.writefile(file, value)
self.map:set(section, "amend", "1")
end
end
function file.cfgvalue(self,section)
return fs.readfile("/etc/supervisord/supervisord.conf") or ""
end
function file.write(self, section, value)
sync_value_to_file(self, section, value, "/etc/supervisord/supervisord.conf")
end
return m

View File

@@ -0,0 +1,21 @@
<script type="text/javascript">
XHR.poll(3, '<%=url([[admin]], [[services]], [[supervisord]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('status');
if (data && tb) {
if (data.running) {
var links = '<em><b><font color=green>Supervisord <%:RUNNING%></font></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b><font color=red>Supervisord <%:NOT RUNNING%></font></b></em>';
}
}
}
);
</script>
<style></style>
<fieldset class="cbi-section">
<p id="status">
<em><%:Collecting data...%></em>
</p>
</fieldset>

View File

@@ -0,0 +1,163 @@
<%local fs = require "nixio.fs"%>
<%+cbi/valueheader%>
<div class="cbi-section-node">
<table class="cbi-section-table" id="task-list">
<tbody>
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell" style="width:120px!important"><%:Name%></th>
<th class="cbi-section-table-cell" style="width:120px!important"><%:Versions%></th>
<th class="cbi-section-table-cell" style="width:100px!important"><%:Status%></th>
<th class="cbi-section-table-cell" style="width:300px!important"><%:Description%></th>
<th class="cbi-section-table-cell"><%:Configuration File%></th>
<th class="cbi-section-table-cell" style="width:355px!important"><%:Action%></th>
</tr>
<% for _,item in pairs(self.list) do %>
<tr class="cbi-section-table-row" id="<%=item[2]:gsub('/etc/supervisord/program/', ""):gsub('.ini', "")%>-main">
<td class="cbi-value-field">
<%=item[1]%>
</td>
<td class="cbi-value-field">
<%=item[3]%>
</td>
<td class="cbi-value-field" id="<%=item[1]%>-status">
</td>
<td class="cbi-value-field" id="<%=item[1]%>-description">
</td>
<td class="cbi-value-field">
<textarea class="cbi-input-textarea" id="<%=item[1]%>-text" rows="15" wrap="off"><%=fs.readfile(item[2])%></textarea>
</td>
<td class="cbi-value-field">
<input class="cbi-button cbi-input-apply" style="font-size: 100%;background-color: green!important;" type="button" id="<%=item[1]%>-start" disabled
onclick="actions('starttask','<%=item[1]%>')" value="<%:Start%>" size="0">
<input class="cbi-button cbi-input-remove" style="font-size: 100%;background-color: #333333!important;" type="button" id="<%=item[1]%>-stop" disabled
onclick="actions('stoptask','<%=item[1]%>')" value="<%:Stop%>" size="0">
<input class="cbi-button cbi-input-apply" style="font-size: 100%;" type="button"
onclick="actions('restarttask','<%=item[1]%>')" value="<%:Reboot%>" size="0">
<input class="cbi-button cbi-input-remove" style="font-size: 100%;" type="button"
onclick="actions('savetask','<%=item[2]:gsub('/etc/supervisord/program/', ''):gsub('.ini', '')%>')" value="<%:Save%>" size="0">
<input class="cbi-button cbi-button-remove" style="font-size: 100%;" type="button"
onclick="actions('removetask','<%=item[2]:gsub('/etc/supervisord/program/', ''):gsub('.ini', '')%>')" value="<%:Delete%>" size="0">
</td>
</tr>
<% end %>
</tbody>
</table>
<div class="cbi-section-create">
<input type="text" class="cbi-section-create-name" id="addtext" value="" maxlength="20" size="0">
<input class="cbi-button cbi-button-add" onclick="addtask()" type="button" value="<%:Add%>" size="0">
</div>
</div>
<script type="text/javascript">
<% for _,item in pairs(self.list) do -%>
XHR.poll(5, '<%=url([[admin]], [[services]], [[supervisord]], [[gettask]])%>', {name: '<%=item[1]%>'},
function(x, data) {
const st = document.getElementById('<%=item[1]%>-status');
const des = document.getElementById('<%=item[1]%>-description');
if (data) {
st.innerHTML = data.status;
if (data.status == "Exited" || data.status == "Backoff"){
st.style.color="red"
document.getElementById('<%=item[1]%>-start').disabled = false;
document.getElementById('<%=item[1]%>-stop').disabled = true;
}else{
st.style.color="green"
document.getElementById('<%=item[1]%>-start').disabled = true;
document.getElementById('<%=item[1]%>-stop').disabled = false;
}
des.innerHTML = data.description;
}
}
)
<% end %>
function addtask(){
const name = document.getElementById("addtext").value
const isletter = /^[a-zA-Z]+$/.test(name);
if (!isletter) {
alert("<%:Only letters can be used for names!%>")
return
}
if (name.length > 20) {
alert("<%:Cannot exceed 20 characters!%>")
return
}
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[addtask]])%>', {name: name},
function(x, data) {
if (data.code == 0) {
alert("<%:Creation failed. Please try again!%>")
return
}else if (data.code == 1){
const currentRows = document.getElementById("task-list").rows.length;
const insertTr = document.getElementById("task-list").insertRow(currentRows);
insertTr.className = 'cbi-section-table-row';
insertTr.id = name + '-main';
insertTr.innerHTML = "<td class='cbi-value-field'>"+name+"</td><td class='cbi-value-field' id='"+name+"-status'></td><td class='cbi-value-field' id='"+name+"-description'></td><td class='cbi-value-field'><textarea class='cbi-input-textarea' id='"+name+"-text' rows='15' wrap='off'>"+data.data+"</textarea></td><td class='cbi-value-field'><input class='cbi-button cbi-input-apply' style='font-size: 100%;background-color: green!important;' type='button' id='"+name+"-start' disabled onclick='actions(&quot;starttask&quot;,&quot;"+name+"&quot;)' value='<%:Start%>' size='0'><input class='cbi-button cbi-input-remove' style='font-size: 100%;background-color: #333333!important;' type='button' id='"+name+"-stop' disabled onclick='actions(&quot;stoptask&quot;,&quot;"+name+"&quot;)' value='<%:Stop%>' size='0'><input class='cbi-button cbi-input-apply' style='font-size: 100%;' type='button' onclick='actions(&quot;restarttask&quot;,&quot;"+name+"&quot;)' value='<%:Reboot%>' size='0'><input class='cbi-button cbi-input-remove' style='font-size: 100%;' type='button' onclick='actions(&quot;savetask&quot;,&quot;"+name+"&quot;)' value='<%:Save%>' size='0'><input class='cbi-button cbi-button-remove' style='font-size: 100%;' type='button' onclick='actions(&quot;removetask&quot;,&quot;"+name+"&quot;)' value='<%:Delete%>' size='0'></td>";
document.getElementById("addtext").value="";
XHR.poll(5, '<%=url([[admin]], [[services]], [[supervisord]], [[gettask]])%>', {name: name},
function(x, data) {
const st = document.getElementById(name + '-status');
const des = document.getElementById(name + '-description');
if (data) {
st.innerHTML = data.status;
if (data.status == "Exited" || data.status == "Backoff"){
st.style.color="red"
document.getElementById(name + '-start').disabled = false;
document.getElementById(name + '-stop').disabled = true;
}else{
st.style.color="green"
document.getElementById(name + '-start').disabled = true;
document.getElementById(name + '-stop').disabled = false;
}
des.innerHTML = data.description;
}
}
)
}else if (data.code == 2){
alert("<%:A task with this name already exists!%>")
return
}
}
)
}
function actions(mode,name){
if (mode=="savetask"){
const x = new XHR()
x.post('<%=url([[admin]], [[services]], [[supervisord]], [[savetask]])%>', {name: name, data: $('#' + name + '-text').val()},
function(x) {
if (JSON.parse(x.response).code) {
alert("<%:Save success!%>")
}else{
alert("<%:Save failed!%>")
}
}
)
}else{
if (mode=="removetask") {
const ret=confirm("<%:Are you sure you want to delete this task?%>")
if (!ret) return
}
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[mode]])%>'.replace("mode",mode), {name: name},
function(x, data) {
if (data.code) {
if (mode == "starttask"){
document.getElementById(name + '-start').disabled = true;
document.getElementById(name + '-stop').disabled = false;
}
if (mode == "stoptask"){
document.getElementById(name + '-start').disabled = false;
document.getElementById(name + '-stop').disabled = true;
}
if (mode == "removetask"){
document.getElementById(name + '-main').remove();
}
}
}
)
}
}
</script>
<%+cbi/valuefooter%>

View File

@@ -0,0 +1,35 @@
<%local fs = require "nixio.fs"%>
<%+cbi/valueheader%>
<div class="cbi-value">
<label class="cbi-value-title">
<p style="color: red">日记列表</p>
</label>
<div class="cbi-value-field">
<select class="cbi-input-select" size="1">
<option value="main">supervisord</option>
<% for _,item in pairs(self.list) do %>
<option value="<%=item[2]:gsub('/etc/supervisord/program/', ''):gsub('.ini', '')%>">
<%=item[2]:gsub('/etc/supervisord/program/', ''):gsub('.ini', '')%>
</option>
<% end %>
</select>
</div>
</div>
<textarea class="cbi-input-textarea" id="log-text" rows="30" wrap="off" readonly></textarea>
<script type="text/javascript">
getlog('main')
$(".cbi-input-select").change(function (e) {
getlog($(this).val())
});
function getlog(name) {
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[getlog]])%>', {name: name},
function (x, data) {
if (data.data) {
document.getElementById("log-text").value = data.data;
}
}
)
}
</script>
<%+cbi/valuefooter%>

View File

@@ -0,0 +1,56 @@
<%+cbi/valueheader%>
<label class="cbi-value-title"><%= translate("Update the core") %></label>
<div class="cbi-value-field">
<input class="btn cbi-button cbi-button-reload" id="update" type="button" size="0" onclick="check_version()" value="<%:Collecting data...%>" />
<div class="cbi-value-description">
<span class="cbi-value-helpicon"><img src="/luci-static/resources/cbi/help.gif" alt="帮助"></span>
<%:If repeated failures occur, you can download the binaries for the corresponding schemas at the following url.%>
</br>&nbsp;&nbsp;&nbsp;&nbsp;
<%:https://github.com/ochinchina/supervisord/releases%>
</br>&nbsp;&nbsp;&nbsp;&nbsp;
<%:Unpack the package and place it in the top path.%>
</br>&nbsp;&nbsp;&nbsp;&nbsp;
<%:The author binary version number may not have changed.%>
</br>&nbsp;&nbsp;&nbsp;&nbsp;
<%:If you successfully update, the refresh page is still lower than the latest version.%>
</br>&nbsp;&nbsp;&nbsp;&nbsp;
<%:This is normal.%>
</div>
</div>
<script type="text/javascript">
function getver() {
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[getver]])%>', null,
function(x, data) {
const tb = document.getElementById('update');
if (data && tb) {
if (data.newver) {
tb.value = '<%:Local version is %>' + data.nowver + '<%:, New version is %>' + data.newver;
tb.setAttribute('newver', data.newver);
}else{
tb.value = '<%:The check failed. Please try again%>';
}
}
}
);
}
getver()
function check_version() {
const tb = document.getElementById('update');
const newver= tb.getAttribute("newver")
if (newver){
tb.disabled = true;
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[update]])%>', {version: newver}, (x, r) => {
if (r.error == 0) {
tb.disabled = false;
tb.value = '<%:Local version is %>' + newver + '<%:, New version is %>' + newver;
} else {
tb.disabled = false;
tb.value = '<%:The update failed. Please try again%>';
}
});
}else{
getver()
}
}
</script>
<%+cbi/valuefooter%>

View File

@@ -0,0 +1,80 @@
msgid "Supervisord"
msgstr "进程管理器"
msgid "A golang development process management"
msgstr "一款golang开发的进程管理"
msgid "General Settings"
msgstr "基础设置"
msgid "Configuration File"
msgstr "配置文件"
msgid "Task List"
msgstr "任务列表"
msgid "Log List"
msgstr "日志列表"
msgid "Enabled"
msgstr "启用"
msgid "File Path"
msgstr "文件路径"
msgid "Use China Mirror"
msgstr "使用中国镜像"
msgid "Update the core"
msgstr "更新核心"
msgid "If repeated failures occur, you can download the binaries for the corresponding schemas at the following url."
msgstr "如果重复失败您可以从以下url下载对应模式的二进制文件。"
msgid "Unpack the package and place it in the top path."
msgstr "解压后并将其放置在上方设置的路径中。"
msgid "The author binary version number may not have changed."
msgstr "作者二进制版本号可能没有改变。"
msgid "If you successfully update, the refresh page is still lower than the latest version."
msgstr "如果更新成功,刷新页面仍然低于最新版本。"
msgid "This is normal."
msgstr "这是正常的。"
msgid "Local version is"
msgstr "本地版本是"
msgid ", New version is"
msgstr ",最新版本是"
msgid "The check failed. Please try again"
msgstr "检查失败。请再试一次"
msgid "The update failed. Please try again"
msgstr "更新失败。请再试一次"
msgid "Versions"
msgstr "版本"
msgid "Only letters can be used for names!"
msgstr "只有字母可以用来命名!"
msgid "Cannot exceed 20 characters!"
msgstr "不能超过20个字符"
msgid "Creation failed. Please try again!"
msgstr "创建失败了。请再试一次!"
msgid "A task with this name already exists!"
msgstr "已经存在此名称的任务!"
msgid "Save success!"
msgstr "保存成功!"
msgid "Save failed!"
msgstr "保存失败!"
msgid "Are you sure you want to delete this task?"
msgstr "您确定要删除该任务吗?"

View File

@@ -0,0 +1 @@
zh-cn

View File

@@ -0,0 +1,6 @@
config supervisord 'main'
option filepath '/usr/bin/supervisord'
option enabled '1'
option amend '0'

View File

@@ -0,0 +1,42 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2015 OpenWrt.org
START=90
get_config() {
config_get_bool enabled $1 enabled 0
config_get_bool amend $1 amend 0
config_get filepath $1 filepath /usr/bin/supervisord
}
start() {
config_load supervisord
config_foreach get_config supervisord
[ $enabled -eq 0 ] && exit 0
$filepath -c /etc/supervisord/supervisord.conf -d
}
stop() {
config_load supervisord
config_foreach get_config supervisord
$filepath ctl shutdown
}
reload() {
config_load supervisord
config_foreach get_config supervisord
[ $enabled -eq 0 ] && logger -t supervisord disabled to stop && stop && exit 0
status=$(ps | grep supervisord | grep -v grep | grep -v luci | grep -v init | grep -v version | wc -l)
[ $status -eq 0 ] && logger -t supervisord unstarted to start && start && exit 0
if [ $amend -eq 1 ]; then
logger -t supervisord amend to restart
stop
sleep 1
uci set supervisord.main.amend=0
uci commit supervisord
start
else
logger -t supervisord fixed to reload
$filepath ctl reload
fi
}

View File

@@ -0,0 +1,60 @@
;更多参数查看https://github.com/ochinchina/supervisord/
;程序名称,没事别乱改
[program:demo]
;程序启动命令,必须
;command=xxxxx
command=
;执行命令的路径,必须
;directory=/usr/bin
directory=
;需要备份文件的完整路径,多个文件以||分割,必须
;backupfile=/usr/bin/xxxxx||/etc/yyyyy
backupfile=
;获取版本号命令,必须
;getversions=xxxxx version
getversions=
;在supervisord启动的时候也自动启动
autostart=true
;启动10秒后没有异常退出就表示进程正常启动了默认为1秒
startsecs=10
;程序退出后自动重启,可选值:[unexpected,true,false]
;默认为unexpected表示进程意外杀死后才重启
autorestart=true
;启动失败自动重试次数默认是3
startretries=3
;用哪个用户启动进程默认是root
user=root
;进程启动优先级默认999值小的优先启动
priority=999
;把stderr重定向到stdout默认false
redirect_stderr=true
;stdout日志文件大小默认1MB
stdout_logfile_maxbytes=1MB
;stdout日志文件备份数默认是10
stdout_logfile_backups=10
;stdout日志文件需要注意当指定目录不存在时无法正常启动所以需手动创建目录
stdout_logfile=/var/log/demo.log
;日志的级别
loglevel=info
;默认为false,进程被杀死时是否向这个进程组发送stop信号包括子进程
stopasgroup=false
;默认为false向进程组发送kill信号包括子进程
killasgroup=false

View File

@@ -0,0 +1,40 @@
;更多参数查看https://github.com/ochinchina/supervisord/
[supervisord]
;主日志文件;默认路径是$CWD/supervisord.log
logfile=/var/log/supervisord.log
;最大主日志文件尺寸;默认3MB
logfile_maxbytes=3MB
;主日志文件备份的数量;默认10
logfile_backups=10
;日志等级;默认info;其他:debug,warn,trace
loglevel=debug
;supervisord的pid文件;默认supervisord.pid
pidfile=/var/run/supervisord.pid
;如果为true从前台开始;默认false
nodaemon=false
;最小效用启动文件描述符;默认1024
minfds=1024
;最小效用过程描述符;默认200
minprocs=200
;启用web界面默认仅本地访问且不设置密码
[inet_http_server]
port=127.0.0.1:9001
;username=admin
;password=admin
;启用命令行操作任务需启用web界面且未设置密码
[supervisorctl]
serverurl=http://127.0.0.1:9001
;加载任务配置文件
[include]
files = /etc/supervisord/program/*.ini

View File

@@ -0,0 +1,11 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@supervisord[-1]
add ucitrack supervisord
set ucitrack.@supervisord[-1].init=supervisord
commit ucitrack
EOF
rm -f /tmp/luci-indexcache
exit 0

View File

@@ -0,0 +1,11 @@
{
"luci-app-supervisord": {
"description": "Grant UCI access for luci-app-supervisord",
"read": {
"uci": [ "supervisord" ]
},
"write": {
"uci": [ "supervisord" ]
}
}
}