mirror of
https://github.com/kenzok8/small-package.git
synced 2026-02-07 23:27:13 +08:00
update-12.04
This commit is contained in:
16
luci-app-supervisord/Makefile
Normal file
16
luci-app-supervisord/Makefile
Normal 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
|
||||
27
luci-app-supervisord/README.md
Normal file
27
luci-app-supervisord/README.md
Normal 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
|
||||
234
luci-app-supervisord/luasrc/controller/supervisord.lua
Normal file
234
luci-app-supervisord/luasrc/controller/supervisord.lua
Normal 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
|
||||
70
luci-app-supervisord/luasrc/model/cbi/supervisord.lua
Normal file
70
luci-app-supervisord/luasrc/model/cbi/supervisord.lua
Normal 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
|
||||
21
luci-app-supervisord/luasrc/view/supervisord/index.htm
Normal file
21
luci-app-supervisord/luasrc/view/supervisord/index.htm
Normal 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>
|
||||
163
luci-app-supervisord/luasrc/view/supervisord/list.htm
Normal file
163
luci-app-supervisord/luasrc/view/supervisord/list.htm
Normal 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("starttask",""+name+"")' 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("stoptask",""+name+"")' value='<%:Stop%>' size='0'><input class='cbi-button cbi-input-apply' style='font-size: 100%;' type='button' onclick='actions("restarttask",""+name+"")' value='<%:Reboot%>' size='0'><input class='cbi-button cbi-input-remove' style='font-size: 100%;' type='button' onclick='actions("savetask",""+name+"")' value='<%:Save%>' size='0'><input class='cbi-button cbi-button-remove' style='font-size: 100%;' type='button' onclick='actions("removetask",""+name+"")' 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%>
|
||||
35
luci-app-supervisord/luasrc/view/supervisord/log.htm
Normal file
35
luci-app-supervisord/luasrc/view/supervisord/log.htm
Normal 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%>
|
||||
56
luci-app-supervisord/luasrc/view/supervisord/version.htm
Normal file
56
luci-app-supervisord/luasrc/view/supervisord/version.htm
Normal 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>
|
||||
<%:https://github.com/ochinchina/supervisord/releases%>
|
||||
</br>
|
||||
<%:Unpack the package and place it in the top path.%>
|
||||
</br>
|
||||
<%:The author binary version number may not have changed.%>
|
||||
</br>
|
||||
<%:If you successfully update, the refresh page is still lower than the latest version.%>
|
||||
</br>
|
||||
<%: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%>
|
||||
80
luci-app-supervisord/po/zh-cn/supervisord.po
Normal file
80
luci-app-supervisord/po/zh-cn/supervisord.po
Normal 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 "您确定要删除该任务吗?"
|
||||
1
luci-app-supervisord/po/zh_Hans
Symbolic link
1
luci-app-supervisord/po/zh_Hans
Symbolic link
@@ -0,0 +1 @@
|
||||
zh-cn
|
||||
6
luci-app-supervisord/root/etc/config/supervisord
Normal file
6
luci-app-supervisord/root/etc/config/supervisord
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
config supervisord 'main'
|
||||
option filepath '/usr/bin/supervisord'
|
||||
option enabled '1'
|
||||
option amend '0'
|
||||
|
||||
42
luci-app-supervisord/root/etc/init.d/supervisord
Executable file
42
luci-app-supervisord/root/etc/init.d/supervisord
Executable 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
|
||||
}
|
||||
60
luci-app-supervisord/root/etc/supervisord/program/templates
Normal file
60
luci-app-supervisord/root/etc/supervisord/program/templates
Normal 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
|
||||
40
luci-app-supervisord/root/etc/supervisord/supervisord.conf
Normal file
40
luci-app-supervisord/root/etc/supervisord/supervisord.conf
Normal 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
|
||||
11
luci-app-supervisord/root/etc/uci-defaults/luci-supervisord
Normal file
11
luci-app-supervisord/root/etc/uci-defaults/luci-supervisord
Normal 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
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-supervisord": {
|
||||
"description": "Grant UCI access for luci-app-supervisord",
|
||||
"read": {
|
||||
"uci": [ "supervisord" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "supervisord" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user