mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-13 20:08:05 +08:00
🎨 Sync 2026-11-13 17:35:38
This commit is contained in:
1 parent
4dc21dd663
commit
342030204e
28 files changed
+398
-162
No files matched your search
+3
-3
@@ -5,11 +5,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=honk
|
||||
PKG_VERSION:=2026.11.12~a09d3bf
|
||||
PKG_RELEASE:=35
|
||||
PKG_VERSION:=2026.11.13~f8bbf4f
|
||||
PKG_RELEASE:=36
|
||||
|
||||
HONK_SRC_URL:=https://github.com/daeuniverse/honk.git
|
||||
HONK_SRC_VERSION:=a09d3bfa272f3670d6606373452be41606bdc29e
|
||||
HONK_SRC_VERSION:=f8bbf4f4b4ab1cdf673c440df316c3c642a31f9c
|
||||
|
||||
PKG_LICENSE:=AGPL-3.0-only
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
+11
-12
@@ -11,7 +11,7 @@ PKG_ARCH_kai:=$(ARCH)
|
||||
|
||||
PKG_NAME:=kai
|
||||
PKG_VERSION:=0.0.28
|
||||
PKG_RELEASE:=13
|
||||
PKG_RELEASE:=14
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/kai-runtime-v$(PKG_VERSION)/
|
||||
PKG_HASH:=skip
|
||||
@@ -27,7 +27,7 @@ define Package/$(PKG_NAME)
|
||||
CATEGORY:=System
|
||||
SUBMENU:=
|
||||
TITLE:=KAI
|
||||
DEPENDS:=+kai_session +kai-agent +luci-lib-linkeaseauth +linkease-app-entry
|
||||
DEPENDS:=+kai_session +kai-agent +luci-lib-linkeaseauth
|
||||
URL:=https://github.com/linkease/istore-ai-helper
|
||||
endef
|
||||
|
||||
@@ -41,13 +41,15 @@ endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
# Compatibility entry for desktops which only scan the old directory.
|
||||
# KaiPlus owns the desktop entry. Retire only links created by KAI.
|
||||
root="$${IPKG_INSTROOT:-}"
|
||||
legacy="$${root}/usr/share/linkeasefull/desktop-apps.d/05-kai-plugin.json"
|
||||
if [ ! -e "$${legacy}" ] && [ ! -L "$${legacy}" ]; then
|
||||
mkdir -p "$${legacy%/*}"
|
||||
ln -s /usr/share/kai/kai-plugin.json "$${legacy}" || exit $$?
|
||||
fi
|
||||
for directory in /usr/share/linkease/apps.d /usr/share/linkeasefull/desktop-apps.d; do
|
||||
registration="$${root}$${directory}/05-kai-plugin.json"
|
||||
if [ "$$(readlink "$${registration}" 2>/dev/null)" = "/usr/share/kai/kai-plugin.json" ]; then
|
||||
rm -f "$${registration}"
|
||||
fi
|
||||
done
|
||||
rmdir "$${root}/usr/share/linkeasefull/desktop-apps.d" 2>/dev/null || true
|
||||
exit 0
|
||||
endef
|
||||
|
||||
@@ -71,14 +73,11 @@ define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/libexec $(1)/etc/init.d $(1)/etc/config $(1)/usr/share/kai/www $(1)/usr/share/linkease/apps.d
|
||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/libexec $(1)/etc/init.d $(1)/etc/config
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/kai.$(PKG_ARCH_kai) $(1)/usr/sbin/kai_bin
|
||||
$(INSTALL_BIN) ./files/kai-session-launch $(1)/usr/libexec/kai-session-launch
|
||||
$(INSTALL_BIN) ./files/kai.init $(1)/etc/init.d/kai
|
||||
$(INSTALL_CONF) ./files/kai.config $(1)/etc/config/kai
|
||||
$(INSTALL_DATA) ./files/kai-plugin.json $(1)/usr/share/kai/kai-plugin.json
|
||||
$(INSTALL_DATA) ./files/logo.png $(1)/usr/share/kai/www/logo.png
|
||||
ln -sf /usr/share/kai/kai-plugin.json $(1)/usr/share/linkease/apps.d/05-kai-plugin.json
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
@@ -1,59 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "kai",
|
||||
"name": "KAI",
|
||||
"icon": "logo.png",
|
||||
"staticRoot": "/usr/share/kai/www",
|
||||
"desktop": {
|
||||
"mode": "iframe",
|
||||
"target": {
|
||||
"scheme": "http",
|
||||
"hostMode": "request-host",
|
||||
"port": {
|
||||
"default": 8197,
|
||||
"keys": {
|
||||
"uci": "kai.@kai[0].port"
|
||||
}
|
||||
},
|
||||
"path": "/apps/kai/"
|
||||
},
|
||||
"access": {
|
||||
"scope": "lan",
|
||||
"blockedTitle": "请在局域网内打开 KAI",
|
||||
"blockedMessage": "KAI 运行在设备的独立服务端口,请连接设备所在局域网后再打开。"
|
||||
}
|
||||
},
|
||||
"standalone": {
|
||||
"basePath": "/apps/kai/",
|
||||
"externalOpen": {
|
||||
"enabled": true,
|
||||
"label": "在浏览器中打开 KAI"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"providerOrder": ["uci"],
|
||||
"providers": {
|
||||
"uci": {
|
||||
"type": "uci"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backend": {
|
||||
"type": "http",
|
||||
"transport": "tcp",
|
||||
"scheme": "http",
|
||||
"host": "127.0.0.1",
|
||||
"portFromUci": "kai.@kai[0].port",
|
||||
"defaultPort": 8197,
|
||||
"upstreamBasePath": "/apps/kai/",
|
||||
"pathMode": "preserve",
|
||||
"proxyMode": "app-base"
|
||||
},
|
||||
"window": {
|
||||
"width": 1180,
|
||||
"height": 760,
|
||||
"singleton": true
|
||||
},
|
||||
"capabilities": ["assistant", "chat"],
|
||||
"categories": ["other"]
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB |
@@ -1312,7 +1312,7 @@ function loadModalTitle(title, addtitle, section_id) {
|
||||
return label ? title + ' » ' + label : addtitle;
|
||||
}
|
||||
|
||||
function loadLabel(preadds, section_id) {
|
||||
function loadChoices(preadds, section_id) {
|
||||
delete this.keylist;
|
||||
delete this.vallist;
|
||||
|
||||
@@ -1322,7 +1322,7 @@ function loadLabel(preadds, section_id) {
|
||||
return this.super('load', section_id);
|
||||
}
|
||||
|
||||
function loadLabelValues(uciconfig, sectiontype, options = {}) {
|
||||
function loadChoicesGetMap(uciconfig, sectiontype, options = {}) {
|
||||
const values = [];
|
||||
|
||||
switch (sectiontype) {
|
||||
@@ -2106,8 +2106,8 @@ return baseclass.extend({
|
||||
// load
|
||||
loadDefaultLabel,
|
||||
loadModalTitle,
|
||||
loadLabel,
|
||||
loadLabelValues,
|
||||
loadChoices,
|
||||
loadChoicesGetMap,
|
||||
// render
|
||||
renderStatus,
|
||||
updateStatus,
|
||||
|
||||
@@ -627,9 +627,9 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
_('Name of the Sub rule used for inbound matching.'));
|
||||
o.value.apply(o, ['', _('none')]);
|
||||
o.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('none')],
|
||||
...hm.loadLabelValues(this.config, 'subrule-group')
|
||||
...hm.loadChoicesGetMap(this.config, 'subrule-group')
|
||||
], section_id);
|
||||
}
|
||||
o.modalonly = false;
|
||||
@@ -642,9 +642,9 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.value.apply(o, res);
|
||||
})
|
||||
o.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.direct,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
o.modalonly = false;
|
||||
@@ -789,9 +789,9 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.value.apply(o, res);
|
||||
})
|
||||
o.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.direct,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
o.depends('tls_reality', '1');
|
||||
@@ -1016,9 +1016,9 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.value.apply(o, res);
|
||||
})
|
||||
o.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.direct,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
o.depends('hysteria2_realm', '1');
|
||||
|
||||
@@ -609,9 +609,9 @@ function renderPayload(s, total, uciconfig) {
|
||||
initPayload(o, n, 'factor');
|
||||
const inname_old_load = o.load;
|
||||
o.load = function(section_id) {
|
||||
hm.loadLabel.call(this, [
|
||||
hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'inbound')
|
||||
...hm.loadChoicesGetMap(this.config, 'inbound')
|
||||
], section_id);
|
||||
|
||||
return inname_old_load.apply(this, arguments);
|
||||
@@ -624,9 +624,9 @@ function renderPayload(s, total, uciconfig) {
|
||||
initPayload(o, n, 'factor');
|
||||
const rematchname_old_load = o.load;
|
||||
o.load = function(section_id) {
|
||||
hm.loadLabel.call(this, [
|
||||
hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'rematch-name')
|
||||
...hm.loadChoicesGetMap(this.config, 'rematch-name')
|
||||
], section_id);
|
||||
|
||||
return rematchname_old_load.apply(this, arguments);
|
||||
@@ -661,7 +661,7 @@ function renderPayload(s, total, uciconfig) {
|
||||
initPayload(o, n, 'factor');
|
||||
const rule_set_old_load = o.load;
|
||||
o.load = function(section_id) {
|
||||
hm.loadLabel.call(this, hm.loadLabelValues(this.config, 'ruleset'), section_id);
|
||||
hm.loadChoices.call(this, hm.loadChoicesGetMap(this.config, 'ruleset'), section_id);
|
||||
|
||||
return rule_set_old_load.apply(this, arguments);
|
||||
}
|
||||
@@ -712,13 +712,13 @@ function renderPayload(s, total, uciconfig) {
|
||||
initDynamicPayload(o, n, 'factor');
|
||||
const fused_old_load = o.load;
|
||||
o.load = function(section_id) {
|
||||
hm.loadLabel.call(this, [
|
||||
hm.loadChoices.call(this, [
|
||||
...hm.inbound_type.map(e => [e, _('IN-TYPE')]), // Multi-values are not supported
|
||||
...hm.loadLabelValues(this.config, 'inbound').map(e => [e, _('IN-NAME')]),
|
||||
...hm.loadLabelValues(this.config, 'rematch-name').map(e => [e, _('REMATCH-NAME')]),
|
||||
...hm.loadChoicesGetMap(this.config, 'inbound').map(e => [e, _('IN-NAME')]),
|
||||
...hm.loadChoicesGetMap(this.config, 'rematch-name').map(e => [e, _('REMATCH-NAME')]),
|
||||
[['udp', _('UDP')], _('NETWORK')],
|
||||
[['tcp', _('TCP')], _('NETWORK')],
|
||||
...hm.loadLabelValues(this.config, 'ruleset').map(e => [e, _('RULE-SET')])
|
||||
...hm.loadChoicesGetMap(this.config, 'ruleset').map(e => [e, _('RULE-SET')])
|
||||
], section_id);
|
||||
|
||||
return fused_old_load.apply(this, arguments);
|
||||
@@ -823,9 +823,9 @@ function renderRules(s, uciconfig) {
|
||||
initEntryOption(o, 'detour');
|
||||
const detour_old_load = o.load;
|
||||
o.load = function(section_id) {
|
||||
hm.loadLabel.call(this, [
|
||||
hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.full,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
|
||||
return detour_old_load.apply(this, arguments);
|
||||
@@ -878,9 +878,9 @@ function renderPolicies(s, uciconfig) {
|
||||
_('Match rule set.'));
|
||||
o.value('', _('-- Please choose --'));
|
||||
o.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'ruleset', {behaviors: ['domain', 'classical']})
|
||||
...hm.loadChoicesGetMap(this.config, 'ruleset', {behaviors: ['domain', 'classical']})
|
||||
], section_id);
|
||||
}
|
||||
o.depends('type', 'rule_set');
|
||||
@@ -909,9 +909,9 @@ function renderPolicies(s, uciconfig) {
|
||||
o.value.apply(o, res);
|
||||
})
|
||||
o.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.direct,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
o.editable = true;
|
||||
@@ -1068,9 +1068,9 @@ return view.extend({
|
||||
})
|
||||
so.keep_order = true;
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.proxy,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
so.editable = true;
|
||||
@@ -1079,9 +1079,9 @@ return view.extend({
|
||||
so.value('', _('-- Please choose --'));
|
||||
so.keep_order = true;
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'node')
|
||||
...hm.loadChoicesGetMap(this.config, 'node')
|
||||
], section_id);
|
||||
}
|
||||
so.validate = function(section_id, value) {
|
||||
@@ -1099,9 +1099,9 @@ return view.extend({
|
||||
so.value('', _('-- Please choose --'));
|
||||
so.keep_order = true;
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'provider')
|
||||
...hm.loadChoicesGetMap(this.config, 'provider')
|
||||
], section_id);
|
||||
}
|
||||
so.validate = function(section_id, value) {
|
||||
@@ -1136,10 +1136,10 @@ return view.extend({
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.proxy,
|
||||
['NODE', _('-- PROXY-NODE --')],
|
||||
...hm.loadLabelValues(this.config, 'node')
|
||||
...hm.loadChoicesGetMap(this.config, 'node')
|
||||
], section_id);
|
||||
}
|
||||
so.textvalue = hm.textvalue2Value;
|
||||
@@ -1201,12 +1201,12 @@ return view.extend({
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.proxy,
|
||||
['GROUP', _('-- PROXY-GROUP --')],
|
||||
...hm.loadLabelValues(this.config, 'proxy_group'),
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group'),
|
||||
['NODE', _('-- PROXY-NODE --')],
|
||||
...hm.loadLabelValues(this.config, 'node')
|
||||
...hm.loadChoicesGetMap(this.config, 'node')
|
||||
], section_id);
|
||||
}
|
||||
so.depends('type', 'select');
|
||||
@@ -1359,9 +1359,9 @@ return view.extend({
|
||||
|
||||
so = ss.option(form.ListValue, 'SUB-RULE', _('SUB-RULE'));
|
||||
so.load = function(section_id) {
|
||||
hm.loadLabel.call(this, [
|
||||
hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'subrule-group')
|
||||
...hm.loadChoicesGetMap(this.config, 'subrule-group')
|
||||
], section_id);
|
||||
|
||||
return this.section.getOption('entry').instget(section_id).subrule || '';
|
||||
@@ -1646,9 +1646,9 @@ return view.extend({
|
||||
);
|
||||
const detour_old_load = so.load;
|
||||
so.load = function(section_id) {
|
||||
hm.loadLabel.call(this, [
|
||||
hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.dns,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
|
||||
return detour_old_load.apply(this, arguments);
|
||||
|
||||
@@ -301,9 +301,9 @@ return view.extend({
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'target_sub_rule', _('Use sub rule'));
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'subrule-group')
|
||||
...hm.loadChoicesGetMap(this.config, 'subrule-group')
|
||||
], section_id);
|
||||
}
|
||||
so.validate = function(section_id, value) {
|
||||
@@ -2426,9 +2426,9 @@ return view.extend({
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.direct,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
so.textvalue = hm.textvalue2Value;
|
||||
@@ -2751,9 +2751,9 @@ return view.extend({
|
||||
|
||||
so = ss.option(form.ListValue, 'chain_head_sub', _('Destination provider'));
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'provider')
|
||||
...hm.loadChoicesGetMap(this.config, 'provider')
|
||||
], section_id);
|
||||
}
|
||||
so.rmempty = false;
|
||||
@@ -2762,9 +2762,9 @@ return view.extend({
|
||||
|
||||
so = ss.option(form.ListValue, 'chain_head', _('Destination proxy node'));
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'node')
|
||||
...hm.loadChoicesGetMap(this.config, 'node')
|
||||
], section_id);
|
||||
}
|
||||
so.rmempty = false;
|
||||
@@ -2781,9 +2781,9 @@ return view.extend({
|
||||
|
||||
so = ss.option(form.ListValue, 'chain_tail_group', _('Transit proxy group'));
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
so.rmempty = false;
|
||||
@@ -2792,9 +2792,9 @@ return view.extend({
|
||||
|
||||
so = ss.option(form.ListValue, 'chain_tail', _('Transit proxy node'));
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
['', _('-- Please choose --')],
|
||||
...hm.loadLabelValues(this.config, 'node')
|
||||
...hm.loadChoicesGetMap(this.config, 'node')
|
||||
], section_id);
|
||||
}
|
||||
so.rmempty = false;
|
||||
|
||||
@@ -418,9 +418,9 @@ return view.extend({
|
||||
o.value.apply(o, res);
|
||||
})
|
||||
o.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
return hm.loadChoices.call(this, [
|
||||
...hm.preset_outbound.direct,
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
...hm.loadChoicesGetMap(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
o.textvalue = hm.textvalue2Value;
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=KaiPlus
|
||||
PKG_VERSION:=1.0.11-r1
|
||||
PKG_RELEASE:=16
|
||||
PKG_VERSION:=1.0.11-r2
|
||||
PKG_RELEASE:=17
|
||||
LUCI_DEPENDS:=+kaiplus +luci-compat +luci-lib-taskd +luci-lib-linkeaseauth +linkease-app-entry
|
||||
LUCI_MINIFY_CSS:=0
|
||||
LUCI_MINIFY_JS:=0
|
||||
|
||||
@@ -9,14 +9,16 @@ function classic.installed()
|
||||
and fs.access("/usr/sbin/kai_session", "x")
|
||||
and fs.access("/etc/init.d/kai", "x")
|
||||
and fs.access("/etc/config/kai")
|
||||
and fs.access("/usr/share/kai/kai-plugin.json")
|
||||
)
|
||||
end
|
||||
|
||||
function classic.status()
|
||||
local installed = classic.installed()
|
||||
local port = tonumber(require("luci.model.uci").cursor():get_first("kai", "kai", "port") or "8197")
|
||||
if not port or port < 1 or port > 65535 or port % 1 ~= 0 then port = nil end
|
||||
return {
|
||||
installed = installed,
|
||||
port = port,
|
||||
running = installed and sys.call("pidof kai_bin >/dev/null") == 0
|
||||
}
|
||||
end
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
var classicPageInstalled = <%= installed and "true" or "false" %>;
|
||||
var classicInstallUrl = '<%=url("admin/services/kaiplus/install_kai")%>';
|
||||
var classicUpdateUrl = '<%=url("admin/services/kaiplus/update_kai")%>';
|
||||
var classicOpenUrl = '<%=url("admin/services/linkease_apps/open")%>?id=kai';
|
||||
var classicAuthUrl = '<%=url("admin/services/linkease_auth/auth")%>';
|
||||
var classicOpenUrl = '';
|
||||
|
||||
function installClassicKai() {
|
||||
classicPackageTask(false);
|
||||
@@ -83,7 +84,11 @@ XHR.poll(5, '<%=url("admin/services/kaiplus/classic_status")%>', null, function(
|
||||
installButton.style.display = st.installed ? 'none' : '';
|
||||
updateButton.style.display = st.installed ? '' : 'none';
|
||||
updateHint.style.display = st.installed ? '' : 'none';
|
||||
openButton.style.display = st.installed && st.running ? '' : 'none';
|
||||
var port = Number(st.port);
|
||||
classicOpenUrl = port >= 1 && port <= 65535 && port === Math.floor(port)
|
||||
? classicAuthUrl + '?return=' + encodeURIComponent('http://' + window.location.hostname + ':' + port + '/apps/kai/')
|
||||
: '';
|
||||
openButton.style.display = st.installed && st.running && classicOpenUrl ? '' : 'none';
|
||||
});
|
||||
//]]></script>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const vm = require('node:vm');
|
||||
function page(installed) {
|
||||
function page(installed, hostname = '192.168.30.7') {
|
||||
const elements = Object.fromEntries(['classic-kai-status', 'classic-kai-install', 'classic-kai-update', 'classic-kai-update-hint', 'classic-kai-open']
|
||||
.map(id => [id, { style: {}, disabled: false }]));
|
||||
const state = { elements, alerts: [], logs: [], reloads: 0 };
|
||||
@@ -11,7 +11,7 @@ function page(installed) {
|
||||
XHR, document: { getElementById: id => elements[id] },
|
||||
window: {
|
||||
confirm: () => true, alert: message => state.alerts.push(message),
|
||||
location: { reload: () => state.reloads++ },
|
||||
location: { hostname, reload: () => state.reloads++ },
|
||||
taskd: { csrfToken: 'test-token', show_log: id => state.logs.push(id) }
|
||||
}
|
||||
};
|
||||
@@ -46,13 +46,21 @@ state.context.installClassicKai();
|
||||
state.post.callback({ responseText: '{"ok":true,"installed":true}' });
|
||||
assert.equal(state.reloads, 1);
|
||||
state = page(true);
|
||||
state.poll(null, { installed: true, running: true });
|
||||
state.poll(null, { installed: true, running: true, port: 8197 });
|
||||
assert.equal(state.elements['classic-kai-install'].style.display, 'none');
|
||||
assert.equal(state.elements['classic-kai-update'].style.display, '');
|
||||
assert.equal(state.elements['classic-kai-open'].style.display, '');
|
||||
assert.equal(state.elements['classic-kai-status'].style.color, 'green');
|
||||
assert.equal(state.reloads, 0);
|
||||
assert.equal(state.context.classicOpenUrl, '/cgi-bin/luci/admin/services/linkease_apps/open?id=kai');
|
||||
assert.equal(state.context.classicOpenUrl, '/cgi-bin/luci/admin/services/linkease_auth/auth?return=' + encodeURIComponent('http://192.168.30.7:8197/apps/kai/'));
|
||||
const ipv6 = page(true, '[fd00::7]');
|
||||
ipv6.poll(null, { installed: true, running: true, port: 8201 });
|
||||
assert.equal(ipv6.context.classicOpenUrl, '/cgi-bin/luci/admin/services/linkease_auth/auth?return=' + encodeURIComponent('http://[fd00::7]:8201/apps/kai/'));
|
||||
for (const port of [0, 65536, 1.5, 'invalid', undefined]) {
|
||||
ipv6.poll(null, { installed: true, running: true, port });
|
||||
assert.equal(ipv6.context.classicOpenUrl, '');
|
||||
assert.equal(ipv6.elements['classic-kai-open'].style.display, 'none');
|
||||
}
|
||||
state.poll(null, { installed: true, running: false });
|
||||
assert.equal(state.elements['classic-kai-open'].style.display, 'none');
|
||||
assert.equal(state.elements['classic-kai-update'].style.display, '');
|
||||
|
||||
@@ -5,7 +5,7 @@ local function check(value, message)
|
||||
assert(value, message)
|
||||
checks = checks + 1
|
||||
end
|
||||
local runtime_files = { "/usr/sbin/kai_bin", "/usr/sbin/kai_session", "/etc/init.d/kai", "/etc/config/kai", "/usr/share/kai/kai-plugin.json" }
|
||||
local runtime_files = { "/usr/sbin/kai_bin", "/usr/sbin/kai_session", "/etc/init.d/kai", "/etc/config/kai" }
|
||||
local function fixture(o)
|
||||
o = o or {}
|
||||
local f = { calls = {}, routes = {} }
|
||||
@@ -22,6 +22,12 @@ local function fixture(o)
|
||||
exec = function(command) f.task_query = command; return "task status fixture" end
|
||||
}
|
||||
package.loaded["nixio.fs"], package.loaded["luci.sys"] = fs, sys
|
||||
package.loaded["luci.model.uci"] = { cursor = function() return {
|
||||
get_first = function(_, config, section, option)
|
||||
check(config == "kai" and section == "kai" and option == "port", "read classic port")
|
||||
return o.port
|
||||
end
|
||||
} end }
|
||||
package.loaded["luci.jsonc"] = { parse = function() return o.task_status or {} end }
|
||||
package.loaded["luci.util"] = { shellquote = function(v) return "'" .. v:gsub("'", "'\\''") .. "'" end }
|
||||
package.loaded["luci.http"] = {
|
||||
@@ -87,7 +93,18 @@ f.controller.classic_status()
|
||||
check(f.reply.installed == false and f.reply.running == false, "missing KAI status")
|
||||
f = fixture({ installed = true, running = true })
|
||||
f.controller.classic_status()
|
||||
check(f.reply.installed and f.reply.running, "runtime must work without luci-app-kai")
|
||||
check(f.reply.installed and f.reply.running, "runtime must work without luci-app-kai or a desktop manifest")
|
||||
check(f.reply.port == 8197, "default classic port")
|
||||
for _, port in ipairs({ "8201", "80", "65535" }) do
|
||||
local configured = fixture({ installed = true, port = port })
|
||||
configured.controller.classic_status()
|
||||
check(configured.reply.port == tonumber(port), "custom classic port")
|
||||
end
|
||||
for _, port in ipairs({ "0", "65536", "8197.5", "invalid" }) do
|
||||
local configured = fixture({ installed = true, port = port })
|
||||
configured.controller.classic_status()
|
||||
check(configured.reply.port == nil, "invalid ports must not produce a launch target")
|
||||
end
|
||||
check(f.calls[1] == "pidof kai_bin >/dev/null", "status must use classic process")
|
||||
for _, path in ipairs(runtime_files) do
|
||||
f = fixture({ installed = true, missing = path })
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-open-box
|
||||
PKG_VERSION:=0.1.429
|
||||
PKG_RELEASE:=75
|
||||
PKG_VERSION:=0.1.432
|
||||
PKG_RELEASE:=76
|
||||
|
||||
PKG_MAINTAINER:=liandu2024
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
|
||||
@@ -9,10 +9,14 @@ LUCI_TITLE:=LuCI support for quickstart
|
||||
LUCI_DEPENDS:=+quickstart +luci-app-ttyd +luci-i18n-ttyd-zh-cn
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_VERSION:=0.17.1-rc20261028-r1
|
||||
PKG_VERSION:=0.17.1-rc20261028-r2
|
||||
# PKG_RELEASE MUST be empty for luci.mk
|
||||
PKG_RELEASE:=
|
||||
|
||||
ifeq ($(CONFIG_USE_APK),y)
|
||||
PKG_VERSION:=$(subst -rc,_rc,$(PKG_VERSION))
|
||||
endif
|
||||
|
||||
LUCI_MINIFY_CSS:=0
|
||||
LUCI_MINIFY_JS:=0
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ LUCI_TITLE:=luci-app-ssr-plus
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_NAME:=luci-app-ssr-plus
|
||||
PKG_VERSION:=198
|
||||
PKG_RELEASE:=102
|
||||
PKG_RELEASE:=103
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \
|
||||
@@ -33,7 +33,7 @@ LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:= \
|
||||
+libuci-lua +lua +luci-compat +dns2tcp +dnsmasq-full \
|
||||
+ip-full +lua-neturl +libuci-lua +microsocks +ipt2socks +lyaml \
|
||||
+resolveip +curl +nping \
|
||||
+resolveip +curl +nping +coreutils-timeout \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:coreutils-timeout \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Http_Proxy:3proxy \
|
||||
@@ -109,7 +109,7 @@ endchoice
|
||||
|
||||
choice
|
||||
prompt "V2ray-core Selection"
|
||||
default PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY
|
||||
default PACKAGE_$(PKG_NAME)_INCLUDE_Xray
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY
|
||||
bool "None"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-trafficctl
|
||||
PKG_VERSION:=1.30.3
|
||||
PKG_RELEASE:=30
|
||||
PKG_VERSION:=1.30.4
|
||||
PKG_RELEASE:=31
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_MAINTAINER:=Denis Iusupov <yusdyr@gmail.com>
|
||||
|
||||
@@ -554,6 +554,20 @@ return baseclass.extend({
|
||||
o.value('cdma', 'CDMA');
|
||||
bind(o);
|
||||
|
||||
/* NSA vs SA is a switch of its own, not part of "Radio technology":
|
||||
the modem's vendor AT setting, which wwand knows only for the
|
||||
Foxconn T99W175 and the Quectel RG50xQ/RM5xxQ (wwand atcmd.uc
|
||||
nr5g_mode_commands); elsewhere the daemon reports it as not
|
||||
applied */
|
||||
o = s.taboption(tab, form.ListValue, 'nr5g_mode', _('5G NR mode'),
|
||||
_('Which kind of 5G the modem may use: non-standalone (5G on an LTE anchor), standalone (5G core), or both. Separate from "Radio technology", which only allows 5G at all. Set over QMI on Qualcomm modems (QMI, or MBIM with the QMI passthrough), otherwise over AT on the Foxconn T99W175 and Quectel RG50xQ/RM5xxQ. With "5G NR" alone, "NSA only" finds no network, because NSA needs LTE.'));
|
||||
o.value('', _('Leave modem setting unchanged'));
|
||||
o.value('both', _('NSA and SA'));
|
||||
o.value('nsa', _('NSA only'));
|
||||
o.value('sa', _('SA only'));
|
||||
o.optional = true;
|
||||
bind(o);
|
||||
|
||||
/* the names are config_check / nas.uc RAT_ORDER_IDS; the daemon drops
|
||||
an unknown or repeated one with a warning, so it is refused here
|
||||
before it gets that far */
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-proto-wwand
|
||||
PKG_VERSION:=1.7.0_pre1
|
||||
PKG_RELEASE:=18
|
||||
PKG_VERSION:=1.8.0_pre2
|
||||
PKG_RELEASE:=19
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/ddimension/luci-proto-wwand.git
|
||||
PKG_SOURCE_VERSION:=fb547fef6576e16ca0e83bd8379f82c27a040613
|
||||
PKG_SOURCE_VERSION:=c451947e1355487391964dea79d73da2e58738a4
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#
|
||||
# Copyright (C) 2026 Quickstart NetPolicy Contributors
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=quickstart-netpolicy
|
||||
PKG_VERSION:=fastnet-runtime-v0.8.9
|
||||
PKG_RELEASE:=1
|
||||
NETPOLICY_TARGET_x86_64:=x86_64-unknown-linux-musl
|
||||
NETPOLICY_TARGET_aarch64:=aarch64-unknown-linux-musl
|
||||
NETPOLICY_TARGET:=$(NETPOLICY_TARGET_$(ARCH))
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(NETPOLICY_TARGET).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/quickstart-runtime-v0.17.1-rc20261028/
|
||||
PKG_HASH_x86_64:=39861c6d508a900d691315b6443f274ea1e283bc3f8c9f9fa91b4e992814a372
|
||||
PKG_HASH_aarch64:=ef2dd2c67ce02b945e89c9fbff66650586fb1c1410717b9306e583c4ad53e480
|
||||
PKG_HASH:=skip
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
ifeq ($(CONFIG_USE_APK),y)
|
||||
PKG_VERSION:=fastnet-runtime-v0.8.9
|
||||
endif
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
# The packaged ELF must match binarySha256 in the runtime manifest.
|
||||
RSTRIP:=:
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=Quickstart native network policy engine
|
||||
URL:=https://github.com/istoreos/quickstart-netpolicy
|
||||
DEPENDS:=@(x86_64||aarch64) +ca-bundle
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
Independent eBPF network-policy engine for Quickstart device rate limits.
|
||||
It uses its own binary, port, data files and kernel maps and does not replace Bandix.
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/quickstart-netpolicy
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
rm -rf $(PKG_BUILD_DIR)
|
||||
$(INSTALL_DIR) $(PKG_BUILD_DIR)
|
||||
gzip -dc $(DL_DIR)/$(PKG_SOURCE) | tar -C $(PKG_BUILD_DIR) -xf -
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin $(1)/etc/init.d $(1)/etc/config $(1)/usr/share/quickstart-netpolicy
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/payload/quickstart-netpolicy $(1)/usr/bin/quickstart-netpolicy
|
||||
$(INSTALL_BIN) ./files/quickstart-netpolicy.init $(1)/etc/init.d/quickstart-netpolicy
|
||||
$(INSTALL_CONF) ./files/quickstart-netpolicy.config $(1)/etc/config/quickstart-netpolicy
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/manifest.json $(1)/usr/share/quickstart-netpolicy/manifest.json
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/payload/LICENSE $(1)/usr/share/quickstart-netpolicy/LICENSE
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/payload/NOTICE $(1)/usr/share/quickstart-netpolicy/NOTICE
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
@@ -0,0 +1,18 @@
|
||||
# Legacy main keeps its original endpoint and data directory.
|
||||
config quickstart-netpolicy 'main'
|
||||
option network 'lan'
|
||||
option enabled '0'
|
||||
option interface 'br-lan'
|
||||
option port '8765'
|
||||
option data_dir '/usr/share/quickstart-netpolicy'
|
||||
option log_level 'info'
|
||||
option traffic_history '0'
|
||||
option dns_monitoring '0'
|
||||
|
||||
# Additional networks are opt-in and require explicit stable resources:
|
||||
# config quickstart-netpolicy 'office'
|
||||
# option enabled '0'
|
||||
# option network 'office'
|
||||
# option interface 'br-office'
|
||||
# option port '8766'
|
||||
# option data_dir '/usr/share/quickstart-netpolicy/networks/office'
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# quickstart-scope-context: 1
|
||||
|
||||
START=91
|
||||
STOP=15
|
||||
USE_PROCD=1
|
||||
PROG=/usr/bin/quickstart-netpolicy
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger quickstart-netpolicy
|
||||
config_load quickstart-netpolicy
|
||||
config_foreach add_network_trigger quickstart-netpolicy
|
||||
}
|
||||
|
||||
add_network_trigger() {
|
||||
local network enabled
|
||||
config_get_bool enabled "$1" enabled 0
|
||||
[ "$enabled" -eq 1 ] || return 0
|
||||
config_get network "$1" network
|
||||
[ "$1" != main ] || network="${network:-lan}"
|
||||
[ -z "$network" ] || procd_add_reload_interface_trigger "$network"
|
||||
}
|
||||
|
||||
instance_error() {
|
||||
logger -t quickstart-netpolicy "instance $1: $2"
|
||||
}
|
||||
|
||||
# Validate the whole enabled set before opening any instance. Duplicate resources
|
||||
# invalidate both entries; configuration order must not choose the winning LAN.
|
||||
collect_instance() {
|
||||
local section="$1" enabled network interface port data_dir log_level history dns other
|
||||
config_get_bool enabled "$section" enabled 0
|
||||
[ "$enabled" -eq 1 ] || return 0
|
||||
config_get network "$section" network
|
||||
config_get interface "$section" interface
|
||||
config_get port "$section" port
|
||||
config_get data_dir "$section" data_dir
|
||||
config_get log_level "$section" log_level info
|
||||
config_get_bool history "$section" traffic_history 0
|
||||
config_get_bool dns "$section" dns_monitoring 0
|
||||
if [ "$section" = main ]; then
|
||||
network="${network:-lan}"
|
||||
interface="${interface:-br-lan}"
|
||||
port="${port:-8765}"
|
||||
data_dir="${data_dir:-/usr/share/quickstart-netpolicy}"
|
||||
fi
|
||||
case "$section" in ''|*[!A-Za-z0-9_-]*) instance_error "$section" 'invalid instance identity'; return 0;; esac
|
||||
case "$network" in ''|*[!A-Za-z0-9_-]*) instance_error "$section" 'invalid network identity'; return 0;; esac
|
||||
case "$interface" in ''|*[!A-Za-z0-9_.-]*) instance_error "$section" 'invalid interface'; return 0;; esac
|
||||
case "$port" in ''|*[!0-9]*) instance_error "$section" 'port is required'; return 0;; esac
|
||||
port="$(expr "$port" + 0)"
|
||||
[ "$port" -gt 0 ] && [ "$port" -le 65535 ] || { instance_error "$section" 'invalid port'; return 0; }
|
||||
case "$data_dir" in /*) ;; *) instance_error "$section" 'absolute data_dir is required'; return 0;; esac
|
||||
case "$data_dir" in *'|'*|*'
|
||||
'*) instance_error "$section" 'invalid data_dir'; return 0;; esac
|
||||
case "$log_level" in trace|debug|info|warn|error) ;; *) instance_error "$section" 'invalid log level'; return 0;; esac
|
||||
local canonical
|
||||
canonical="$(readlink -f "$data_dir" 2>/dev/null)"
|
||||
[ -z "$canonical" ] || data_dir="$canonical"
|
||||
local IFS='
|
||||
'
|
||||
for other in $instance_records; do
|
||||
local old_section old_network old_interface old_port old_dir rest
|
||||
old_section="${other%%|*}"; rest="${other#*|}"
|
||||
old_network="${rest%%|*}"; rest="${rest#*|}"
|
||||
old_interface="${rest%%|*}"; rest="${rest#*|}"
|
||||
old_port="${rest%%|*}"; rest="${rest#*|}"
|
||||
old_dir="${rest%%|*}"
|
||||
if [ "$network" = "$old_network" ] || [ "$interface" = "$old_interface" ] || [ "$port" = "$old_port" ] || [ "$data_dir" = "$old_dir" ]; then
|
||||
invalid_instances="$invalid_instances $section $old_section"
|
||||
instance_error "$section" "duplicate network/interface/port/data_dir with $old_section"
|
||||
fi
|
||||
done
|
||||
instance_records="${instance_records}${instance_records:+
|
||||
}$section|$network|$interface|$port|$data_dir|$log_level|$history|$dns"
|
||||
}
|
||||
|
||||
start_instance() {
|
||||
local section="$1" network interface port data_dir log_level history dns status actual
|
||||
case " $invalid_instances " in *" $section "*) return 0;; esac
|
||||
config_get network "$section" network lan
|
||||
config_get interface "$section" interface br-lan
|
||||
config_get port "$section" port 8765
|
||||
config_get data_dir "$section" data_dir /usr/share/quickstart-netpolicy
|
||||
config_get log_level "$section" log_level info
|
||||
config_get_bool history "$section" traffic_history 0
|
||||
config_get_bool dns "$section" dns_monitoring 0
|
||||
status="$(ubus -S call "network.interface.$network" status 2>/dev/null)" || { instance_error "$section" 'network unavailable'; return 0; }
|
||||
actual="$(printf '%s' "$status" | jsonfilter -e '@.l3_device')"
|
||||
[ "$actual" = "$interface" ] || { instance_error "$section" 'interface does not match logical network'; return 0; }
|
||||
[ -d "/sys/class/net/$interface" ] || { instance_error "$section" 'interface unavailable'; return 0; }
|
||||
procd_open_instance "$section"
|
||||
procd_set_param command "$binary" --iface "$interface" --port "$port" --data-dir "$data_dir" --network-id "$network" --instance-id "$section" --log-level "$log_level" --enable-traffic
|
||||
[ "$history" -eq 1 ] && procd_append_param command --traffic-enable-storage
|
||||
[ "$dns" -eq 1 ] && procd_append_param command --enable-dns
|
||||
procd_set_param netdev "$interface"
|
||||
procd_set_param respawn 3600 5 3
|
||||
procd_set_param term_timeout 10
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param limits core="0 0"
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local instance_records='' invalid_instances='' record binary="$PROG"
|
||||
[ -x "$binary" ] || { instance_error main "missing executable $binary"; return 1; }
|
||||
config_load quickstart-netpolicy
|
||||
config_foreach collect_instance quickstart-netpolicy
|
||||
local IFS='
|
||||
'
|
||||
for record in $instance_records; do start_instance "${record%%|*}"; done
|
||||
}
|
||||
|
||||
# procd compares named instance commands, so unchanged networks keep their
|
||||
# processes and TC links. Do not implement reload as stop/start.
|
||||
reload_service() {
|
||||
rc_procd start_service
|
||||
}
|
||||
+30
-3
@@ -10,19 +10,26 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_ARCH_quickstart:=$(ARCH)
|
||||
|
||||
PKG_NAME:=quickstart
|
||||
PKG_VERSION:=0.13.1
|
||||
PKG_RELEASE:=6
|
||||
PKG_VERSION:=0.17.1-rc20261028
|
||||
PKG_RELEASE:=7
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/linkease/istore-packages/releases/download/prebuilt/
|
||||
PKG_SOURCE_URL:=https://github.com/istoreos/quickstart/releases/download/v$(PKG_VERSION)/
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
||||
|
||||
ifeq ($(CONFIG_USE_APK),y)
|
||||
PKG_VERSION:=$(subst -rc,_rc,$(PKG_VERSION))
|
||||
endif
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
# Runtime manifests cover these prebuilt bytes; do not strip them again.
|
||||
RSTRIP:=:
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
@@ -39,6 +46,23 @@ endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/quickstart
|
||||
/etc/quickstart/home-layout.json
|
||||
/etc/quickstart/home-layout.json.bak
|
||||
/etc/quickstart/home-layout.json.damaged
|
||||
/etc/quickstart/home-layout.json.bak.damaged
|
||||
/etc/quickstart/home-launcher.json
|
||||
/etc/quickstart/home-launcher.json.bak
|
||||
/etc/quickstart/home-launcher.json.damaged
|
||||
/etc/quickstart/home-launcher.json.bak.damaged
|
||||
/etc/quickstart/device-classifications.json
|
||||
/etc/quickstart/device-profiles.json
|
||||
/etc/quickstart/manual-devices.json
|
||||
/etc/quickstart/device-groups.json
|
||||
/etc/quickstart/traffic-insights.json
|
||||
/etc/quickstart/device-policy-effects-v1.json
|
||||
/etc/quickstart/task-transactions-v1.json
|
||||
/etc/quickstart/lan-device-model-v1.json
|
||||
/etc/quickstart/network-audit.json
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
@@ -71,7 +95,10 @@ define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_BIN) ./files/startdhns.hotplug $(1)/etc/hotplug.d/iface/21-startdhns
|
||||
$(INSTALL_DIR) $(1)/usr/share/quickstart
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/MANIFEST $(1)/usr/share/quickstart/MANIFEST
|
||||
$(INSTALL_DATA) ./files/manuf $(1)/usr/share/quickstart/manuf
|
||||
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
|
||||
$(INSTALL_DATA) ./files/quickstart.keep $(1)/lib/upgrade/keep.d/quickstart
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
@@ -0,0 +1,8 @@
|
||||
/etc/quickstart/home-layout.json
|
||||
/etc/quickstart/home-layout.json.bak
|
||||
/etc/quickstart/home-layout.json.damaged
|
||||
/etc/quickstart/home-layout.json.bak.damaged
|
||||
/etc/quickstart/home-launcher.json
|
||||
/etc/quickstart/home-launcher.json.bak
|
||||
/etc/quickstart/home-launcher.json.damaged
|
||||
/etc/quickstart/home-launcher.json.bak.damaged
|
||||
@@ -10,8 +10,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=v2raya-core
|
||||
PKG_VERSION:=2.5.14
|
||||
PKG_RELEASE:=1
|
||||
PKG_VERSION:=2.5.15
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=v2rayA-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)?
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=v2raya
|
||||
PKG_VERSION:=2.5.14
|
||||
PKG_RELEASE:=8
|
||||
PKG_VERSION:=2.5.15
|
||||
PKG_RELEASE:=9
|
||||
|
||||
PKG_SOURCE:=v2rayA-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)?
|
||||
|
||||
+3
-3
@@ -50,12 +50,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wwand
|
||||
PKG_VERSION:=1.9.0_pre14
|
||||
PKG_RELEASE:=92
|
||||
PKG_VERSION:=1.9.0_pre20
|
||||
PKG_RELEASE:=93
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/ddimension/wwand.git
|
||||
PKG_SOURCE_VERSION:=4f3c54b1eeb65d898246545435ca2300e57ac30e
|
||||
PKG_SOURCE_VERSION:=b646c9ec93928e8a8e57356551cfa7717d7171b6
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
|
||||
Reference in new issue
Block a user