🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

@@ -0,0 +1,90 @@
'use strict';
'require view';
'require fs';
'require form';
'require dom';
var enableLog = true;
var context = {"locations": []};
var confdPath = "/etc/nginx/conf.d/";
function log(content){
if (enableLog){
return console.log("luci-app-nginx.location: " + content);
};
};
return view.extend({
load: async function (){
var fileList = await fs.list(confdPath);
log("load: fileList is " + JSON.stringify(fileList));
for (var i in fileList){
if ((fileList[i].type == "file") && fileList[i].name.endsWith(".locations")){
var fullPath = confdPath + fileList[i].name;
var fileNameWithoutSuffix = fileList[i].name.replace(/.locations$/, "");
var content = await fs.read_direct(fullPath);
var obj = {
".name": fileNameWithoutSuffix,
"content": content
};
context["locations"].push(obj);
};
};
},
render: function (loadResult){
log("render: context is " + JSON.stringify(context));
var formMap = new form.JSONMap(
context,
_("Location files"),
_("All <code>.locations</code> files under <code>/etc/nginx/conf.d</code>")
);
var filesSection = formMap.section(
form.TypedSection, "locations",
_("Known location files"),
_("We found those <code>.locations</code> files under <code>/etc/nginx/conf.d</code>")
);
filesSection.addremove = true;
var filesOption = filesSection.option(
form.TextValue, "content"
);
filesOption.monospace = true;
filesOption.rows = 20;
filesOption.cols = 70;
return formMap.render();
},
handleSave: async function (ev){
var mapNode = document.querySelector(".cbi-map");
await dom.callClassMethod(mapNode, "save");
log("handleSaveApply: context is " + JSON.stringify(context));
var valueNodes = document.querySelectorAll(".cbi-value");
var fileNamesWithoutSuffix = [];
valueNodes.forEach(
async function (valueNode, index, valueNodesList){
if (valueNode.parentElement && valueNode.parentElement.getAttribute("data-section-id")){
var fileNameWithoutSuffix = valueNode.parentElement.getAttribute("data-section-id");
var fileName = confdPath + fileNameWithoutSuffix + ".locations";
var content = valueNode.querySelector("textarea").textContent;
fileNamesWithoutSuffix.push(fileNameWithoutSuffix);
var writeResult = await fs.write(fileName, content);
if (writeResult != 0){
log("handleSave: failed to write file %s".format(fileName));
};
}
}
);
context["locations"].forEach(
async function (fileNameWithoutSuffix, index, fileNamesWithoutSuffixList){
if (!fileNamesWithoutSuffix.includes(fileNameWithoutSuffix[".name"])){
var fileName = confdPath + fileNameWithoutSuffix[".name"] + ".locations";
var removeResult = await fs.remove(fileName);
if (removeResult != 0){
log("handleSave: failed to remove file %s".format(fileName));
}
}
}
);
location.reload();
},
handleSaveApply: null
});
@@ -0,0 +1,81 @@
'use strict';
'require view';
'require form';
var enableLog = true;
function log(content){
if (enableLog){
return console.log("luci-app-nginx.servers: " + content);
};
};
function isSSLEnabledInListenList(listenList){
for (var i in listenList){
if (listenList[i].includes("ssl")){
return true;
}
}
return false;
};
return view.extend({
render: function (load_result){
var formMap = new form.Map(
"nginx",
_("Nginx Servers"),
_("Servers Configuration for Nginx")
);
var configSection = formMap.section(
form.TypedSection, "server",
_("All Servers"),
_("All of the known Nginx servers.")
);
configSection.addremove = true;
var listenOption = configSection.option(
form.DynamicList, "listen",
_("Listening on:")
);
var serverNameOption = configSection.option(
form.Value, "server_name",
_("Server Name:")
);
serverNameOption.optional = true;
var uciManageSSLOption = configSection.option(
form.Value, "uci_manage_ssl",
_("SSL Managed By UCI:"),
_("Set to any value other than self-signed to manage it yourself.")
);
var sslCertificatePathOption = configSection.option(
form.Value, "ssl_certificate",
_("SSL Certificate:")
);
var sslCertificateKeyPathOption = configSection.option(
form.Value, "ssl_certificate_key",
_("SSL Certificate Key:")
);
var sslSessionCacheOption = configSection.option(
form.Value, "ssl_session_cache",
_("SSL Session Cache Option:")
);
sslSessionCacheOption.optional = true;
var sslSessionTimeoutOption = configSection.option(
form.Value, "ssl_session_timeout",
_("SSL Session Timeout:")
);
sslSessionTimeoutOption.optional = true;
var returnOption = configSection.option(
form.Value, "return",
_("Return:")
);
returnOption.optional = true;
var accessLogOption = configSection.option(
form.Value, "access_log",
_("Access Log:")
);
accessLogOption.optional = true;
return formMap.render();
}
});
@@ -0,0 +1,205 @@
'use strict';
'require view';
'require poll';
'require rpc';
'require fs';
'require uci';
var enableLog = true;
var pollIntervalSecs = 5;
var context = {
server: "unknown",
httpsRedirectEnabled: false,
serversCount: 0,
curlInstalled: false
};
var expectServiceObject = {
"nginx": {
"instances": {
"instance1": {}
}
}
};
function log(content){
if (enableLog){
return console.log("luci-app-nginx.main: " + content);
};
};
function toDict(string, kvSpliter){
var dict = {};
string.split(/\r?\n|\r/g).forEach(
function (line, index, array){
if (line.includes(kvSpliter)){
var kv = line.split(kvSpliter, 2);
dict[kv[0].toLowerCase()] = kv[1];
};
}
);
return dict;
};
function filterServiceFunction(data, args, extraArgs){
log("filterFunction: data is " + JSON.stringify(data));
log("filterFunction: args is " + JSON.stringify(args));
log("filterFunction: extraArgs is " + extraArgs);
if (
(args.name == "nginx") &&
(typeof data?.instances?.instance1?.running == "boolean")
){
if (data.instances.instance1.running){
return "running";
}
else {
return "stopped";
};
};
return "unknown";
};
var getServiceStatus = rpc.declare({
object: "service",
method: "list",
params: ["name"],
expect: expectServiceObject,
filter: filterServiceFunction
});
async function updateStatusContent(){
var result = await getServiceStatus("nginx");
log("updateStatusContent: trying to update nginx status to " + result);
var statusContent = document.getElementById("nginx-status-content");
log("updateStatusContent: found div#nginx-status-content: " + statusContent);
if (statusContent){
switch (result){
case "running":
statusContent.textContent = _("Running");
statusContent.style.color = "green";
break;
case "stopped":
statusContent.textContent = _("Stopped");
statusContent.style.color = "red";
break;
default:
statusContent.textContent = _("Unknown");
statusContent.style.color = "orange";
break;
};
};
};
return view.extend({
handleSaveApply: null,
handleSave: null,
handleReset: null,
load: async function (){
var curlExec = "/usr/bin/curl";
var curlStatus = await fs.stat(curlExec);
log("curlStatus is " + JSON.stringify(curlStatus));
context.curlInstalled = ((curlStatus.type == "file") && (curlStatus.mode == 33261));
log("load: context.curlInstalled is " + context.curlInstalled);
if (context.curlInstalled){
var curlResult = await fs.exec_direct(curlExec, ["-I", "-s", "http://" + location.host]);
log("load: curlResult is " + curlResult);
var headers = toDict(curlResult, ": ");
log("load: headers is " + JSON.stringify(headers));
var locationInHeaders = headers["location"];
if (locationInHeaders){
if (locationInHeaders.startsWith("https://" + location.host)){
context.httpsRedirectEnabled = true;
};
};
var serverInHeaders = headers["server"];
if (serverInHeaders){
context.server = serverInHeaders;
};
};
await uci.load("nginx");
context.serversCount = uci.sections("nginx", "server").length;
uci.unload();
},
render: function (loadResults){
log("render: loadResults is " + loadResults);
var statusTitle = E("div", {"id":"nginx-status-title"}, _("Nginx status:"));
statusTitle.style.display = "inline-block";
var statusContent = E("div", {"id": "nginx-status-content"}, _("Unknown"));
statusContent.style.color = "orange";
statusContent.style.display = "inline-block";
statusContent.style.marginLeft = "10px";
var serviceControlLinkTitle = E(
"div",
{"id": "nginx-service-control"},
"%s -> %s".format(_("System"), _("Startup"))
);
serviceControlLinkTitle.style.display = "inline-block";
var serviceControlLink = E(
"a",
{"href": location.href.replace(location.pathname, "/cgi-bin/luci/admin/system/startup")}
);
serviceControlLink.appendChild(serviceControlLinkTitle);;
serviceControlLink.style.marginLeft = "25px";
var statusElement = E("div",{"id": "nginx-status"});
statusElement.appendChild(statusTitle);
statusElement.appendChild(statusContent);
statusElement.appendChild(serviceControlLink);
statusElement.style.marginTop = "25px";
var luciServerTitle = E("div", _("LuCI on Nginx:"));
luciServerTitle.style.display = "inline-block";
var luciServerStatus;
if (context.curlInstalled){
luciServerStatus = E("div", _(context.server.startsWith("nginx")?"Yes":"No"));
luciServerStatus.style.color = context.server.startsWith("nginx")?"green":"red";
} else {
luciServerStatus = E("div", _("Install <code>curl</code> for this info."));
luciServerStatus.style.color = "orange";
};
luciServerStatus.style.display = "inline-block";
luciServerStatus.style.marginLeft = "10px";
var luciServerLinkTitle = E(
"div",
{"id": "nginx-luci-link"},
"%s -> %s -> %s".format(_("Services"), _("Nginx"), _("Servers"))
);
luciServerLinkTitle.style.display = "inline-block";
var luciServerLink = E(
"a",
{"href": location.href.replace(location.pathname, "/cgi-bin/luci/admin/services/nginx/servers")}
)
luciServerLink.appendChild(luciServerLinkTitle);
luciServerLink.style.marginLeft = "25px";
var luciServerElement = E("div", {"id": "nginx-luci-status"});
luciServerElement.appendChild(luciServerTitle);
luciServerElement.appendChild(luciServerStatus);
luciServerElement.appendChild(luciServerLink);
luciServerElement.style.marginTop = "25px";
var httpsRedirectTitle = E("div", _("Https Redirect Enabled:"));
httpsRedirectTitle.style.display = "inline-block";
var httpsRedirectStatus;
if (context.curlInstalled){
httpsRedirectStatus = E("div", _(context.httpsRedirectEnabled?"Yes":"No"));
httpsRedirectStatus.style.color = context.httpsRedirectEnabled?"green":"red";
} else {
httpsRedirectStatus = E("div", _("Install <code>curl</code> for this info."));
httpsRedirectStatus.style.color = "orange";
};
httpsRedirectStatus.style.display = "inline-block";
httpsRedirectStatus.style.marginLeft = "10px";
var httpsRedirectElement = E("div", {"id": "nginx-https-redirect"});
httpsRedirectElement.appendChild(httpsRedirectTitle);
httpsRedirectElement.appendChild(httpsRedirectStatus);
httpsRedirectElement.style.marginTop = "25px";
var serversCountTitle = E("div", _("Running Servers Count:"));
serversCountTitle.style.display = "inline-block";
var serversCountStatus = E("div", "%d".format(context.serversCount));
serversCountStatus.style.display = "inline-block";
serversCountStatus.style.marginLeft = "10px";
var serversCountElement = E("div", {"id": "nginx-servers-count"});
serversCountElement.appendChild(serversCountTitle);
serversCountElement.appendChild(serversCountStatus);
serversCountElement.style.marginTop = "25px";
poll.add(updateStatusContent, pollIntervalSecs);
return E([
statusElement, luciServerElement, httpsRedirectElement, serversCountElement
]);
}
});