初始化仓库
This commit is contained in:
59
README.md
59
README.md
@@ -1,6 +1,43 @@
|
||||
# Openwrt-actions
|
||||
# 中文 | [English](https://github.com/Siriling/istoreos-actions/blob/main/EngLish.md)
|
||||
|
||||
# 移动通信模组自动构建
|
||||
|
||||
[](https://blog.siriling.com:1212/2023/03/18/openwrt-5g-modem) [](../../releases/latest)
|
||||
|
||||
  
|
||||
|
||||
# 目录
|
||||
|
||||
[一、简介](#一简介)
|
||||
|
||||
[二、源代码地址 ](#二源代码地址)
|
||||
|
||||
[三、资源](#三资源)
|
||||
|
||||
[四、使用说明](#四使用说明)
|
||||
|
||||
# 一、简介
|
||||
|
||||
Modem插件自动构建
|
||||
|
||||
# 二、源代码地址
|
||||
|
||||
- luci-app-modem:https://github.com/Siriling/5G-Modem-Support/tree/main/luci-app-modem
|
||||
|
||||
- sms-tool:https://github.com/obsy/sms_tool
|
||||
- quectel_cm_5G:https://github.com/Siriling/5G-Modem-Support/tree/main/quectel_cm_5G
|
||||
- quectel_MHI:https://github.com/Siriling/5G-Modem-Support/tree/main/quectel_MHI
|
||||
|
||||
# 三、资源
|
||||
|
||||
|
||||
|
||||
# 四、使用说明
|
||||
|
||||
## 在线构建
|
||||
|
||||
使用步骤
|
||||
|
||||
## 使用步骤
|
||||
1. 选择actions标签,选择Build IPKs
|
||||
|
||||
2. 点击run workflow,输入要编译的插件名称,空格隔开,或者填“all”用来编译所有插件,然后开始编译
|
||||
@@ -8,8 +45,18 @@
|
||||
3. 等待编译完成,点击任务进入详情页
|
||||
4. 在详情页下载插件压缩包
|
||||
|
||||
## ForkApp
|
||||
## 离线构建
|
||||
|
||||
1. ./forkapp forkapp -from ../applications/luci-app-plex -to ../applications/luci-app-demo
|
||||
2. ./forkapp upload -ip 192.168.100.1 -pwd "password" -from ../applications/luci-app-demo -to /root/
|
||||
3. ./forkapp upload -ip 192.168.100.1 -pwd "password" -from ../applications/luci-app-demo -to /root/ -script ../tools/simple-install.sh -install
|
||||
ForkApp使用步骤
|
||||
|
||||
```shell
|
||||
./forkapp forkapp -from ../applications/luci-app-plex -to ../applications/luci-app-demo
|
||||
```
|
||||
|
||||
```shell
|
||||
./forkapp upload -ip 192.168.100.1 -pwd "password" -from ../applications/luci-app-demo -to /root/
|
||||
```
|
||||
|
||||
```shell
|
||||
./forkapp upload -ip 192.168.100.1 -pwd "password" -from ../applications/luci-app-demo -to /root/ -script ../tools/simple-install.sh -install
|
||||
```
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=airconnect
|
||||
PKG_VERSION:=1.0.13
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_VERSION:=9fc8c184da22d6b34a5b093f6ec8cf6ecaf22dbf
|
||||
PKG_SOURCE_URL_FILE:=$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/philippe44/AirConnect/archive/
|
||||
PKG_HASH:=0da27af9a1d49cd83f8381453d5e1b9c6551ad1ce45bbb7b820e5499796c5440
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/AirConnect-$(PKG_SOURCE_VERSION)
|
||||
|
||||
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=multimedia
|
||||
CATEGORY:=Multimedia
|
||||
TITLE:=AirConnect
|
||||
URL:=https://github.com/philippe44/AirConnect
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
Use AirPlay to stream to UPnP/Sonos & Chromecast devices
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/airconnect
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin $(1)/etc/config $(1)/etc/init.d
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/aircast-linux-$(ARCH)-static $(1)/usr/bin/aircast
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/airupnp-linux-$(ARCH)-static $(1)/usr/bin/airupnp
|
||||
$(INSTALL_CONF) ./files/airconnect.config $(1)/etc/config/airconnect
|
||||
$(INSTALL_BIN) ./files/airconnect.init $(1)/etc/init.d/airconnect
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,airconnect))
|
||||
@@ -1,5 +0,0 @@
|
||||
config main
|
||||
option 'enabled' '0'
|
||||
option 'interface' 'lan'
|
||||
option 'aircast' '1'
|
||||
option 'airupnp' '1'
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
STOP=01
|
||||
USE_PROCD=1
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "airconnect"
|
||||
}
|
||||
|
||||
main_config() {
|
||||
config_get AIRUPNP_IFACE "$1" interface "lan"
|
||||
config_get_bool ENABLE_MAIN "$1" enabled 0
|
||||
config_get_bool ENABLE_AIRCAST "$1" aircast 0
|
||||
config_get_bool ENABLE_AIRUPNP "$1" airupnp 0
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load airconnect
|
||||
config_foreach main_config main
|
||||
[ "$ENABLE_MAIN" = 0 ] && return 0
|
||||
[ "$ENABLE_AIRCAST" = 0 -a "$ENABLE_AIRUPNP" = 0 ] && return 0
|
||||
|
||||
local interface=$(
|
||||
. /lib/functions/network.sh
|
||||
|
||||
network_is_up "$AIRUPNP_IFACE" || exit 0
|
||||
network_get_device device "$AIRUPNP_IFACE"
|
||||
printf "%s" "${device:-$AIRUPNP_IFACE}"
|
||||
)
|
||||
[ -z "$interface" ] && interface=br-lan
|
||||
local common_args="-Z -b $interface"
|
||||
|
||||
if [ "$ENABLE_AIRUPNP" = 1 ]; then
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/bin/airupnp $common_args
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
fi
|
||||
if [ "$ENABLE_AIRCAST" = 1 ]; then
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/bin/aircast $common_args
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
fi
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.0-20221219
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for airconnect
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+airconnect
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.airconnect", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "airconnect"}, alias("admin", "services", "airconnect", "config"), _("AirConnect"), 90).dependent = true
|
||||
entry({"admin", "services", "airconnect", "config"}, cbi("airconnect"))
|
||||
end
|
||||
@@ -1,31 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local m, s, o
|
||||
|
||||
m = Map("airconnect", translate("AirConnect"), translate("Use AirPlay to stream to UPnP/Sonos & Chromecast devices"))
|
||||
|
||||
s = m:section(TypedSection, "main", translate("Global Settings"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Flag, "enabled", translate("Enable"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "interface", translate("Interface"), translate("Network interface for serving, usually LAN"))
|
||||
o.template = "cbi/network_netlist"
|
||||
o.nocreate = true
|
||||
o.default = "lan"
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Flag, "aircast", translate("Supports Chromecast"), translate("Select this if you have Chromecast devices"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Flag, "airupnp", translate("Supports UPnP/Sonos"), translate("Select this if you have UPnP/Sonos devices"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
return m
|
||||
@@ -1,23 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Use AirPlay to stream to UPnP/Sonos & Chromecast devices"
|
||||
msgstr "AirConnect 让 UPnP/Sonos 和 Chromecast 设备支持 AirPlay 音频串流"
|
||||
|
||||
msgid "Global Settings"
|
||||
msgstr "全局设置"
|
||||
|
||||
msgid "Network interface for serving, usually LAN"
|
||||
msgstr "提供服务的网络接口,通常是 LAN 口"
|
||||
|
||||
msgid "Supports Chromecast"
|
||||
msgstr "支持 Chromecast 设备"
|
||||
|
||||
msgid "Supports UPnP/Sonos"
|
||||
msgstr "支持 UPnP/Sonos 设备"
|
||||
|
||||
msgid "Select this if you have Chromecast devices"
|
||||
msgstr "如果你有 Chromecast 设备就选中这个"
|
||||
|
||||
msgid "Select this if you have UPnP/Sonos devices"
|
||||
msgstr "如果你有 UPnP/Sonos 设备就选中这个"
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.4-20230408
|
||||
PKG_RELEASE:=
|
||||
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
|
||||
|
||||
LUCI_TITLE:=Easy Access AP / Modem
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
define Package/luci-app-ap-modem/conffiles
|
||||
/etc/config/ap_modem
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,54 +0,0 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require uci';
|
||||
'require form';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
uci.load('ap_modem')
|
||||
]);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
|
||||
var m, s, o, ss;
|
||||
|
||||
m = new form.Map('ap_modem', _('Access AP / Modem'),
|
||||
_('Allows clients in the local network to access AP or modem on different subnet.'));
|
||||
|
||||
s = m.section(form.NamedSection, 'config', 'ap_modem', _('Global Settings'));
|
||||
s.anonymous = true;
|
||||
s.addremove = false;
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('Enable'));
|
||||
o.rmempty = false;
|
||||
|
||||
s = m.section(form.NamedSection, 'config', 'ap_modem', _('Interface Settings'));
|
||||
s.anonymous = true;
|
||||
s.addremove = false;
|
||||
|
||||
[
|
||||
{id:"lan", title:_("LAN"), subtitle:_("AP on LAN side"), placeholder:"192.168.31.254",
|
||||
example:_("<br>For example, you want to access the AP, its IP address is 192.168.31.1, but the client and the router are not in its subnet, so it cannot be connected. "
|
||||
+ "Then you can add 192.168.31.254 here, the client will be able to access 192.168.31.1 after saving and applying.")},
|
||||
{id:"wan", title:_("WAN"), subtitle:_("AP / Modem on WAN side"), placeholder:"192.168.1.254",
|
||||
example:_("<br>For example, you want to access the modem, its IP address is 192.168.1.1, but because it uses PPPoE bridge mode, so it cannot be connected. "
|
||||
+ "Then you can add 192.168.1.254 here, the client will be able to access 192.168.1.1 after saving and applying.")},
|
||||
].forEach(function(vif) {
|
||||
s.tab(vif.id, vif.title);
|
||||
|
||||
o = s.taboption(vif.id, form.SectionValue, '__'+vif.id+'__', form.NamedSection, vif.id, null,
|
||||
vif.subtitle, _('Here add the IP address of the same subnet as the target device, but not the same as the target device. <br>Do not add IPs already used by other devices.') + vif.example);
|
||||
|
||||
ss = o.subsection;
|
||||
ss.anonymous = true;
|
||||
|
||||
o = ss.option(form.DynamicList, 'ipaddr', _('Virtual IP'), _('Supports "IP/MASK", "IP/PREFIX", and pure "IP" format, pure "IP" assumes a prefix of 24 bits'));
|
||||
o.datatype = 'ipmask4';
|
||||
o.placeholder = vif.placeholder;
|
||||
});
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Access AP / Modem"
|
||||
msgstr "访问AP/光猫"
|
||||
|
||||
msgid "Allows clients in the local network to access AP or modem on different subnet."
|
||||
msgstr "让局域网客户端访问不同子网的AP或光猫"
|
||||
|
||||
msgid "Global Settings"
|
||||
msgstr "全局设置"
|
||||
|
||||
msgid "Interface Settings"
|
||||
msgstr "网络接口配置"
|
||||
|
||||
msgid "AP on LAN side"
|
||||
msgstr "位于LAN口的AP"
|
||||
|
||||
msgid "AP / Modem on WAN side"
|
||||
msgstr "位于WAN口的AP或光猫"
|
||||
|
||||
msgid "Virtual IP"
|
||||
msgstr "虚拟IP地址"
|
||||
|
||||
msgid ""
|
||||
"Here add the IP address of the same subnet as the target device, but not the same as the target device. "
|
||||
"<br>Do not add IPs already used by other devices."
|
||||
msgstr ""
|
||||
"这里添加与目标设备同子网的IP地址,但不能与目标设备IP完全相同。<br>不要添加其他设备正在使用的IP。"
|
||||
|
||||
msgid ""
|
||||
"<br>For example, you want to access the AP, its IP address is 192.168.31.1, but the client and the router are not in its subnet, so it cannot be connected. "
|
||||
"Then you can add 192.168.31.254 here, the client will be able to access 192.168.31.1 after saving and applying."
|
||||
msgstr "<br>例如,你想要访问AP后台,它的IP地址是192.168.31.1,但是由于现在客户端和路由器都不在它的子网,无法连接。那么可以在这里添加192.168.31.254,保存并应用之后客户端就能访问192.168.31.1了。"
|
||||
|
||||
msgid ""
|
||||
"<br>For example, you want to access the modem, its IP address is 192.168.1.1, but because it uses PPPoE bridge mode, so it cannot be connected. "
|
||||
"Then you can add 192.168.1.254 here, the client will be able to access 192.168.1.1 after saving and applying."
|
||||
msgstr "<br>例如,你想要访问光猫后台,它的IP地址是192.168.1.1,但是由于它使用PPPoE桥接模式,无法连接。那么可以在这里添加192.168.1.254,保存并应用之后客户端就能访问192.168.1.1了。"
|
||||
|
||||
msgid "Supports \"IP/MASK\", \"IP/PREFIX\", and pure \"IP\" format, pure \"IP\" assumes a prefix of 24 bits"
|
||||
msgstr "支持“IP/掩码”、“IP/前缀长度”、以及纯“IP”格式,纯“IP”则假设前缀24位"
|
||||
@@ -1,8 +0,0 @@
|
||||
config ap_modem 'config'
|
||||
option enabled '0'
|
||||
|
||||
config interface 'lan'
|
||||
# list ipaddr '192.168.31.254'
|
||||
|
||||
config interface 'wan'
|
||||
# list ipaddr '192.168.1.254'
|
||||
@@ -1,208 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=20
|
||||
USE_PROCD=1
|
||||
|
||||
boot() {
|
||||
# procd will call service_triggers
|
||||
rc_procd true
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "network" "ap_modem"
|
||||
}
|
||||
|
||||
find_uci_section_i() {
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
local testv
|
||||
config_get testv "$1" "$key"
|
||||
[[ "$value" = "$testv" ]] && echo "$1"
|
||||
}
|
||||
|
||||
find_uci_section() {
|
||||
local config="$1"
|
||||
local type="$2"
|
||||
local key="$3"
|
||||
local value="$4"
|
||||
(
|
||||
config_load "$config"
|
||||
config_foreach find_uci_section_i "$type" "$key" "$value"
|
||||
)
|
||||
}
|
||||
|
||||
generate_config() {
|
||||
[[ "`uci -q get network.lan.device`" = "br-lan" ]] || {
|
||||
echo "network.lan.device != br-lan in uci" >&2
|
||||
return 1
|
||||
}
|
||||
local wan_dev="`uci -q get network.wan.device`"
|
||||
[[ -z "$wan_dev" ]] && {
|
||||
echo "get network.wan.device in uci failed" >&2
|
||||
return 1
|
||||
}
|
||||
local lan_dev=`find_uci_section network device name 'br-lan' | head -1`
|
||||
[[ -z "$lan_dev" ]] && {
|
||||
echo "network.device.name=br-lan not found in uci" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
local wan_zone=`find_uci_section firewall zone name 'wan' | head -1`
|
||||
[[ -z "$wan_zone" ]] && {
|
||||
echo "firewall.zone.name=wan not found in uci" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# virutal lan device
|
||||
uci -q get network.veth_lan >/dev/null || uci -q batch <<-EOF >/dev/null
|
||||
set network.veth_lan=device
|
||||
set network.veth_lan.type=veth
|
||||
set network.veth_lan.name=vap-lan
|
||||
set network.veth_lan.sendredirects=0
|
||||
set network.veth_lan.ipv6=0
|
||||
set network.veth_lan.multicast=0
|
||||
set network.veth_lan.peer_name=vap-lan-peer
|
||||
EOF
|
||||
uci -q get network.veth_lan_peer >/dev/null || uci -q batch <<-EOF >/dev/null
|
||||
set network.veth_lan_peer=device
|
||||
set network.veth_lan_peer.name=vap-lan-peer
|
||||
set network.veth_lan_peer.sendredirects=0
|
||||
set network.veth_lan_peer.ipv6=0
|
||||
set network.veth_lan_peer.multicast=0
|
||||
EOF
|
||||
uci -q get "network.$lan_dev.ports" | grep -Fwq 'vap-lan' || uci add_list "network.$lan_dev.ports=vap-lan"
|
||||
|
||||
# interface
|
||||
if uci -q get network.vap_lan >/dev/null; then
|
||||
uci -q delete network.vap_lan.auto
|
||||
else
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
set network.vap_lan=interface
|
||||
set network.vap_lan.proto=static
|
||||
set network.vap_lan.device=vap-lan-peer
|
||||
set network.vap_lan.defaultroute=0
|
||||
set network.vap_lan.delegate=0
|
||||
EOF
|
||||
fi
|
||||
if uci -q get network.vap_wan >/dev/null; then
|
||||
uci -q delete network.vap_wan.auto
|
||||
else
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
set network.vap_wan=interface
|
||||
set network.vap_wan.proto=static
|
||||
set network.vap_wan.device=$wan_dev
|
||||
set network.vap_wan.defaultroute=0
|
||||
set network.vap_wan.delegate=0
|
||||
EOF
|
||||
fi
|
||||
# firewall
|
||||
local fw_wan_net="`uci -q get firewall.$wan_zone.network`"
|
||||
echo "$fw_wan_net" | grep -Fwq 'vap_lan' || uci -q batch <<-EOF >/dev/null
|
||||
add_list firewall.$wan_zone.network=vap_lan
|
||||
EOF
|
||||
echo "$fw_wan_net" | grep -Fwq 'vap_wan' || uci -q batch <<-EOF >/dev/null
|
||||
add_list firewall.$wan_zone.network=vap_wan
|
||||
EOF
|
||||
uci commit firewall
|
||||
|
||||
# ip
|
||||
local bip
|
||||
local black_ip="127.0.0.1/8"
|
||||
[[ "`uci -q get network.lan.proto`" = "static" ]] && {
|
||||
local lan_ip="`uci -q get network.lan.ipaddr`"
|
||||
if [[ -n "$lan_ip" ]]; then
|
||||
if echo "$lan_ip" | grep -Fq '/'; then
|
||||
for bip in $lan_ip; do
|
||||
eval "$(ipcalc.sh ${bip/\// } )";black_ip="$black_ip $IP/$PREFIX"
|
||||
done
|
||||
else
|
||||
local netmask="`uci -q get network.lan.netmask`"
|
||||
eval "$(ipcalc.sh "$lan_ip" "$netmask" )";black_ip="$black_ip $IP/$PREFIX"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
logger -t 'ap_modem' -p INFO "black: $black_ip"
|
||||
|
||||
local ipaddr
|
||||
local vip
|
||||
local vip_p
|
||||
local vnet
|
||||
local bnet
|
||||
local ok
|
||||
local vif
|
||||
for vif in lan wan; do
|
||||
config_get ipaddr $vif ipaddr
|
||||
[[ -z "$ipaddr" ]] || {
|
||||
for vip in $ipaddr; do
|
||||
ok=1
|
||||
eval "$(ipcalc.sh ${vip/\// } )";vip="$IP";vip_p="$PREFIX"
|
||||
[[ "$vip_p" = 32 ]] && {
|
||||
logger -t 'ap_modem' -p DEBUG "vap_$vif skip $vip/$vip_p"
|
||||
break
|
||||
}
|
||||
[[ "$vip_p" = 0 ]] && vip_p=24
|
||||
for bip in $black_ip; do
|
||||
eval "$(ipcalc.sh "$bip" )";bip="$IP";
|
||||
[[ "$PREFIX" -le "$vip_p" ]] || PREFIX=$vip_p
|
||||
eval "$(ipcalc.sh "$vip" "$PREFIX" )";vnet="$NETWORK";
|
||||
eval "$(ipcalc.sh "$bip" "$PREFIX" )";bnet="$NETWORK";
|
||||
if [[ "$vnet" = "$bnet" ]]; then
|
||||
logger -t 'ap_modem' -p DEBUG "vap_$vif skip $vip/$vip_p"
|
||||
ok=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
[[ "$ok" = 1 ]] && {
|
||||
uci add_list "network.vap_$vif.ipaddr=$vip/$vip_p"
|
||||
black_ip="$black_ip $vip/$vip_p"
|
||||
}
|
||||
done
|
||||
}
|
||||
done
|
||||
|
||||
uci commit network
|
||||
}
|
||||
|
||||
clean_config() {
|
||||
local wan_zone=`find_uci_section firewall zone name 'wan' | head -1`
|
||||
[[ -z "$wan_zone" ]] || uci -q batch <<-EOF >/dev/null
|
||||
del_list firewall.$wan_zone.network=vap_lan
|
||||
del_list firewall.$wan_zone.network=vap_wan
|
||||
commit firewall
|
||||
EOF
|
||||
local lan_dev=`find_uci_section network device name 'br-lan' | head -1`
|
||||
[[ -z "$lan_dev" ]] || {
|
||||
uci del_list "network.$lan_dev.ports=vap-lan"
|
||||
}
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
set network.vap_lan.auto=0
|
||||
set network.vap_wan.auto=0
|
||||
delete network.veth_lan_peer
|
||||
delete network.veth_lan
|
||||
commit network
|
||||
EOF
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load ap_modem
|
||||
config_get_bool enabled "config" enabled 0
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete network.vap_lan.ipaddr
|
||||
delete network.vap_wan.ipaddr
|
||||
commit network
|
||||
EOF
|
||||
if [[ "$enabled" = "1" ]]; then
|
||||
generate_config
|
||||
else
|
||||
clean_config
|
||||
fi
|
||||
/etc/init.d/network reload
|
||||
return 0
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
clean_config
|
||||
/etc/init.d/network reload
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"admin/network/ap_modem": {
|
||||
"title": "Access AP / Modem",
|
||||
"order": 99,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "ap_modem"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-ap-modem" ],
|
||||
"uci": { "ap_modem": true }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"luci-app-ap-modem": {
|
||||
"description": "Grant access to 'Access AP / Modem'",
|
||||
"read": {
|
||||
"uci": [ "ap_modem" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "ap_modem" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.1-20231208
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for bmtedge
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-bmtedge/conffiles
|
||||
/etc/config/bmtedge
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.bmtedge", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "bmtedge"}, alias("admin", "services", "bmtedge", "config"), _("BlueMountain Edge"), 30).dependent = true
|
||||
entry({"admin", "services", "bmtedge", "config"}, cbi("bmtedge"))
|
||||
end
|
||||
@@ -1,58 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
local nixio = require "nixio"
|
||||
|
||||
local bmtedge = {}
|
||||
|
||||
bmtedge.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
bmtedge.default_image = function()
|
||||
if string.find(nixio.uname().machine, "x86_64") then
|
||||
return "jinshanyun/jinshan-x86_64"
|
||||
else
|
||||
return "jinshanyun/jinshan-arm64"
|
||||
end
|
||||
end
|
||||
|
||||
local random_str = function(t)
|
||||
math.randomseed(os.time())
|
||||
local s = "0123456789abcdefghijklmnopqrstuvwsyz"
|
||||
local value = ""
|
||||
for x = 1,t do
|
||||
local rand = math.random(#s)
|
||||
value = value .. string.sub(s, rand, rand)
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
bmtedge.default_uid = function()
|
||||
local f = io.open("/sys/class/net/eth0/address", "r")
|
||||
if not f then
|
||||
f = io.open("/sys/class/net/br-lan/address", "r")
|
||||
end
|
||||
if not f then
|
||||
return random_str(16)
|
||||
end
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
return string.gsub(ret, "[ \r\n:]+", "") .. random_str(8)
|
||||
end
|
||||
|
||||
return bmtedge
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local bmtedge_model = require "luci.model.bmtedge"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("bmtedge", "bmtedge", "/usr/libexec/istorec/bmtedge.sh",
|
||||
translate("BlueMountain Edge"),
|
||||
"蓝山云-流量宝由蓝山联合金山云推出的一款镜像软件,通过简单安装后可快速加入蓝山的边缘计算生态,在线共享带宽即可赚钱,每月可获取一定的现金回报!了解更多,请登录「<a href=\"https://www.bmtcloud.com.cn\" target=\"_blank\" >蓝山云官网</a>」并查看<a href=\"https://doc.linkease.com/zh/guide/istoreos/software/bmtedge.html\" target=\"_blank\">「教程」</a>")
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("BlueMountain Edge status:"), "注意网心云会以超级权限运行!")
|
||||
s:append(Template("bmtedge/status"))
|
||||
|
||||
s = m:section(TypedSection, "bmtedge", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
local default_image = bmtedge_model.default_image()
|
||||
o = s:option(Value, "image_name", translate("Image").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o:value("jinshanyun/jinshan-x86_64", "jinshanyun/jinshan-x86_64")
|
||||
o:value("jinshanyun/jinshan-arm64", "jinshanyun/jinshan-arm64")
|
||||
o:value("jinshanyun/jinshan-x86_64:v1.2", "jinshanyun/jinshan-x86_64:v1.2")
|
||||
o:value("jinshanyun/jinshan-arm64:v2.2", "jinshanyun/jinshan-arm64:v2.2")
|
||||
o.default = default_image
|
||||
|
||||
local default_uid = bmtedge_model.default_uid()
|
||||
o = s:option(Value, "uid", translate("UID").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o:value(default_uid, default_uid)
|
||||
o.default = default_uid
|
||||
|
||||
local blks = bmtedge_model.blocks()
|
||||
local dir
|
||||
o = s:option(Value, "cache_path", translate("Cache path").."<b>*</b>", "请选择合适的存储位置进行安装,安装位置容量越大,收益越高。安装后请勿轻易改动")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
for _, dir in pairs(blks) do
|
||||
dir = dir .. "/bmtedge1"
|
||||
o:value(dir, dir)
|
||||
end
|
||||
if #blks > 0 then
|
||||
o.default = blks[1] .. "/bmtedge1"
|
||||
end
|
||||
|
||||
return m
|
||||
@@ -1,73 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/bmtedge.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local uid = uci:get_first("bmtedge", "bmtedge", "uid", "")
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" id="btnShowQr"><%:Running, click to show QR%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:BlueMountain Edge is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbi-value" id="winContainer" style="display: none">
|
||||
<label class="cbi-value-title"></label>
|
||||
<div class="cbi-value-field">
|
||||
<div style="display: flex;flex-direction: column;align-items: center; width:276px; background-color: white;">
|
||||
<div style="
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
margin: 10px;
|
||||
">
|
||||
<div id="qrimage" >
|
||||
</div>
|
||||
<div id="weapp" style="display: none">
|
||||
<img src="/luci-static/bmtedge/weapp.jpg" alt="小程序码" style="
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
">
|
||||
</div>
|
||||
</div>
|
||||
<h6>用<a id="btnShowWeapp" href="javascript:void(0);">“蓝山云”小程序</a>扫码,请查看:<a href="https://doc.linkease.com/zh/guide/istoreos/software/bmtedge.html" target="_blank">教程</a></h6>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/luci-static/bmtedge/qrcode.min.js"></script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
'use strict';
|
||||
var shown = false;
|
||||
var tryShowQr = function() {
|
||||
if (shown) {
|
||||
return;
|
||||
}
|
||||
shown = true;
|
||||
new QRCode(document.getElementById("qrimage"), "lsyK17032_"+"<%=uid%>");
|
||||
document.getElementById("winContainer").style.removeProperty('display');
|
||||
};
|
||||
|
||||
document.getElementById("btnShowQr").addEventListener("click", function(e){
|
||||
e.preventDefault();
|
||||
tryShowQr();
|
||||
});
|
||||
document.getElementById("btnShowWeapp").addEventListener("mouseenter", function(e){
|
||||
e.preventDefault();
|
||||
document.getElementById("qrimage").style.display='none';
|
||||
document.getElementById("weapp").style.removeProperty('display');
|
||||
});
|
||||
document.getElementById("btnShowWeapp").addEventListener("mouseleave", function(e){
|
||||
e.preventDefault();
|
||||
document.getElementById("weapp").style.display='none';
|
||||
document.getElementById("qrimage").style.removeProperty('display');
|
||||
});
|
||||
})();
|
||||
|
||||
</script>
|
||||
@@ -1,40 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "BlueMountain Edge"
|
||||
msgstr "蓝山云-流量宝"
|
||||
|
||||
msgid "Cache path"
|
||||
msgstr "缓存文件路径"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "BlueMountain Edge status:"
|
||||
msgstr "蓝山云的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Running, click to show QR"
|
||||
msgstr "运行中,点击查看二维码"
|
||||
|
||||
msgid "BlueMountain Edge is not running"
|
||||
msgstr "蓝山云未运行"
|
||||
|
||||
|
||||
msgid "Use “蓝山云” Wechat Little APP to scan the QR, click:"
|
||||
msgstr "用“蓝山云”小程序扫码,请查看:"
|
||||
|
||||
msgid "Guide"
|
||||
msgstr "教程"
|
||||
|
||||
msgid "UID"
|
||||
msgstr "唯一标识"
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
config bmtedge
|
||||
# option cache_path ''
|
||||
# option image_name ''
|
||||
# option uid ''
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete firewall.bmtedge
|
||||
set firewall.bmtedge=rule
|
||||
set firewall.bmtedge.name="bmtedge"
|
||||
set firewall.bmtedge.target="ACCEPT"
|
||||
set firewall.bmtedge.src="wan"
|
||||
set firewall.bmtedge.dest_port="1024-65535"
|
||||
set firewall.bmtedge.enabled="0"
|
||||
commit firewall
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
@@ -1,103 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local path=`uci get bmtedge.@bmtedge[0].cache_path 2>/dev/null`
|
||||
local uid=`uci get bmtedge.@bmtedge[0].uid 2>/dev/null`
|
||||
local image_name=`uci get bmtedge.@bmtedge[0].image_name 2>/dev/null`
|
||||
|
||||
if [ -z "$path" ]; then
|
||||
echo "path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local netdev=`ip route list|awk ' /^default/ {print $5}'`
|
||||
if [ -z "$netdev" ]; then
|
||||
echo "defualt gateway is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$image_name" ] && image_name="jinshanyun/jinshan-x86_64:latest"
|
||||
echo "docker pull ${image_name}"
|
||||
docker pull ${image_name}
|
||||
docker rm -f bmtedge
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d \
|
||||
--privileged \
|
||||
--network=host \
|
||||
--dns=127.0.0.1 \
|
||||
--dns=223.5.5.5 \
|
||||
--tmpfs /run \
|
||||
--tmpfs /tmp \
|
||||
-v \"$path:/data/ksc1\" \
|
||||
-v \"$path/containerd:/var/lib/containerd\" \
|
||||
-e ksc_datadir=\"/data/ksc1\" \
|
||||
-e ksc_net=\"$netdev\" \
|
||||
-e ksc_machine_code=\"lsyK17032_$uid\" "
|
||||
|
||||
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
cmd="$cmd --name bmtedge \"$image_name\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
if [ "$?" = "0" ]; then
|
||||
if [ "`uci -q get firewall.bmtedge.enabled`" = 0 ]; then
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
set firewall.bmtedge.enabled="1"
|
||||
commit firewall
|
||||
EOF
|
||||
/etc/init.d/firewall reload
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Install OK!"
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the bmtedge"
|
||||
echo " upgrade Upgrade the bmtedge"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the bmtedge"
|
||||
echo " status Onething Edge status"
|
||||
echo " port Onething Edge port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f bmtedge
|
||||
if [ "`uci -q get firewall.bmtedge.enabled`" = 1 ]; then
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
set firewall.bmtedge.enabled="0"
|
||||
commit firewall
|
||||
EOF
|
||||
/etc/init.d/firewall reload
|
||||
fi
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} bmtedge
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=bmtedge' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=bmtedge' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.3-20240113
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for ChineseSubFinder
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-chinesesubfinder/conffiles
|
||||
/etc/config/chinesesubfinder
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.chinesesubfinder", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "chinesesubfinder"}, alias("admin", "services", "chinesesubfinder", "config"), _("ChineseSubFinder"), 30).dependent = true
|
||||
entry({"admin", "services", "chinesesubfinder", "config"}, cbi("chinesesubfinder"))
|
||||
end
|
||||
@@ -1,54 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local chinesesubfinder_model = require "luci.model.chinesesubfinder"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("chinesesubfinder", "chinesesubfinder", "/usr/libexec/istorec/chinesesubfinder.sh",
|
||||
translate("ChineseSubFinder"),
|
||||
translate("ChineseSubFinder is a tool which can download chinese subtitle automaticly.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://github.com/allanpk716/ChineseSubFinder\" target=\"_blank\">https://github.com/allanpk716/ChineseSubFinder</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("ChineseSubFinder status:"))
|
||||
s:append(Template("chinesesubfinder/status"))
|
||||
|
||||
s = m:section(TypedSection, "main", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "http_port", translate("HTTP Port").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "19035"
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "web_port", "WEB Port<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "19037"
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "image_name", translate("Image").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o:value("allanpk716/chinesesubfinder:latest-lite", "allanpk716/chinesesubfinder:latest-lite")
|
||||
o:value("allanpk716/chinesesubfinder:v0.43.1-lite", "allanpk716/chinesesubfinder:v0.43.1-lite")
|
||||
o.default = "allanpk716/chinesesubfinder:latest-lite"
|
||||
|
||||
local blocks = chinesesubfinder_model.blocks()
|
||||
local home = chinesesubfinder_model.home()
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
local paths, default_path = chinesesubfinder_model.find_paths(blocks, home, "Configs")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
o = s:option(Value, "media_path", translate("Media path"), translate("Not required, all disk is mounted in") .. " <a href='/cgi-bin/luci/admin/services/linkease/file/?path=/root/mnt' target='_blank'>/mnt</a>")
|
||||
o.datatype = "string"
|
||||
|
||||
return m
|
||||
@@ -1,55 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local chinesesubfinder = {}
|
||||
|
||||
chinesesubfinder.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
chinesesubfinder.home = function()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local home_dirs = {}
|
||||
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
|
||||
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
|
||||
home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
|
||||
home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads")
|
||||
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
|
||||
return home_dirs
|
||||
end
|
||||
|
||||
chinesesubfinder.find_paths = function(blocks, home_dirs, path_name)
|
||||
local default_path = ''
|
||||
local configs = {}
|
||||
|
||||
default_path = home_dirs[path_name] .. "/ChineseSubFinder"
|
||||
if #blocks == 0 then
|
||||
table.insert(configs, default_path)
|
||||
else
|
||||
for _, val in pairs(blocks) do
|
||||
table.insert(configs, val .. "/" .. path_name .. "/ChineseSubFinder")
|
||||
end
|
||||
local without_conf_dir = "/root/" .. path_name .. "/ChineseSubFinder"
|
||||
if default_path == without_conf_dir then
|
||||
default_path = configs[1]
|
||||
end
|
||||
end
|
||||
|
||||
return configs, default_path
|
||||
end
|
||||
|
||||
return chinesesubfinder
|
||||
@@ -1,31 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/chinesesubfinder.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:ChineseSubFinder is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:ChineseSubFinder is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/chinesesubfinder.sh port"))
|
||||
if port == "" then
|
||||
port="19035"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open ChineseSubFinder%>" onclick="window.open('http://'+location.hostname+':<%=port%>', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,41 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "ChineseSubFinder is a tool which can download chinese subtitle automaticly."
|
||||
msgstr "ChineseSubFinder是一个自动化中文字幕下载工具。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "HTTP Port"
|
||||
msgstr "HTTP 端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "ChineseSubFinder status:"
|
||||
msgstr "ChineseSubFinder 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "ChineseSubFinder is running"
|
||||
msgstr "ChineseSubFinder 运行中"
|
||||
|
||||
msgid "ChineseSubFinder is not running"
|
||||
msgstr "ChineseSubFinder 未运行"
|
||||
|
||||
msgid "Open ChineseSubFinder"
|
||||
msgstr "打开 ChineseSubFinder"
|
||||
|
||||
msgid "Not required, all disk is mounted in"
|
||||
msgstr "可不填,所有硬盘都在"
|
||||
@@ -1,6 +0,0 @@
|
||||
config main
|
||||
option 'http_port' '19035'
|
||||
option 'web_port' '19037'
|
||||
option 'image_name' ''
|
||||
option 'config_path' ''
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Author Xiaobao(xiaobao@linkease.com)
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local http_port=`uci get chinesesubfinder.@main[0].http_port 2>/dev/null`
|
||||
local web_port=`uci get chinesesubfinder.@main[0].web_port 2>/dev/null`
|
||||
local image_name=`uci get chinesesubfinder.@main[0].image_name 2>/dev/null`
|
||||
local config=`uci get chinesesubfinder.@main[0].config_path 2>/dev/null`
|
||||
local media=`uci get chinesesubfinder.@main[0].media_path 2>/dev/null`
|
||||
|
||||
[ -z "$image_name" ] && image_name="allanpk716/chinesesubfinder:latest-lite"
|
||||
echo "docker pull ${image_name}"
|
||||
docker pull ${image_name}
|
||||
docker rm -f chinesesubfinder
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$http_port" ] && http_port=19035
|
||||
[ -z "$web_port" ] && web_port=19037
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d -v \"$config:/config\" --dns=172.17.0.1 -p $http_port:19035 -p $web_port:19037 \
|
||||
--hostname chinesesubfinder \
|
||||
--log-driver \"json-file\" \
|
||||
--log-opt \"max-size=100m\" "
|
||||
|
||||
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
[ -z "$media" ] || cmd="$cmd -v \"$media:/media\""
|
||||
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
cmd="$cmd --name chinesesubfinder \"$image_name\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the chinesesubfinder"
|
||||
echo " upgrade Upgrade the chinesesubfinder"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the chinesesubfinder"
|
||||
echo " status ChineseSubFinder status"
|
||||
echo " port ChineseSubFinder port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f chinesesubfinder
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} chinesesubfinder
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=chinesesubfinder' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
uci -q get chinesesubfinder.@main[0].http_port 2>/dev/null
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.1-20240117
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for CloudDrive2
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+mount-utils +lsblk +docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-clouddrive2/conffiles
|
||||
/etc/config/clouddrive2
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.clouddrive2", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "clouddrive2"}, alias("admin", "services", "clouddrive2", "config"), _("CloudDrive2"), 30).dependent = true
|
||||
entry({"admin", "services", "clouddrive2", "config"}, cbi("clouddrive2"))
|
||||
end
|
||||
@@ -1,58 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local clouddrive2_model = require "luci.model.clouddrive2"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("clouddrive2", "clouddrive2", "/usr/libexec/istorec/clouddrive2.sh",
|
||||
translate("CloudDrive2"),
|
||||
translate("CloudDrive is a powerful multi-cloud drive management tool with local mounting of cloud drives.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://www.clouddrive2.com/\" target=\"_blank\">https://www.clouddrive2.com/</a>' .. '<br>'
|
||||
.. translate("Since mounting within the container requires the use of a special shared mount point, to avoid compatibility issues, only mounting to /mnt/CloudNAS is supported (mounting to other paths cannot be seen by the host). The shared mount point is automatically created by this plug-in, uninstalling the plug-in may cause the deployed CloudDrive container to fail to start or mount (iStoreOS is an exception, because /mnt is the shared mount point by default).") .. '<br>'
|
||||
.. translate("Disclaimer: This LuCI plug-in is developed by individuals. It only facilitates users to deploy CloudDrive containers (https://hub.docker.com/u/cloudnas) and has nothing to do with CloudDrive. Since CloudDrive is not open source software, although this plug-in has restricted its permissions to the greatest extent, it does not make any guarantees about the software content and services provided by CloudDrive. Use at your own risk!"))
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("CloudDrive2 status:"))
|
||||
s:append(Template("clouddrive2/status"))
|
||||
|
||||
s = m:section(TypedSection, "clouddrive2", translate("Setup"),
|
||||
translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "image", translate("Docker image"))
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o:value("default", translate("Default (cloudnas/clouddrive2)"))
|
||||
o:value("cloudnas/clouddrive2-unstable", "cloudnas/clouddrive2-unstable")
|
||||
o.default = "default"
|
||||
|
||||
o = s:option(Value, "port", translate("Port"))
|
||||
o.default = "19798"
|
||||
o.datatype = "port"
|
||||
|
||||
local blocks = clouddrive2_model.blocks()
|
||||
local home = clouddrive2_model.home()
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
local paths, default_path = clouddrive2_model.find_paths(blocks, home, "Configs")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
o = s:option(Value, "cache_path", translate("Temporary file path"), translate("Default use 'temp' in 'config path' if not set, please make sure there has enough space"))
|
||||
o.datatype = "string"
|
||||
local paths, default_path = clouddrive2_model.find_paths(blocks, home, "Caches")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
|
||||
o = s:option(Flag, "share_mnt", translate("Share /mnt"), translate("CloudDrive can read and write other mount points under /mnt for its synchronization or backup functions"))
|
||||
o.default = 0
|
||||
|
||||
return m
|
||||
@@ -1,55 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local clouddrive2 = {}
|
||||
|
||||
clouddrive2.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
clouddrive2.home = function()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local home_dirs = {}
|
||||
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
|
||||
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
|
||||
home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
|
||||
home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads")
|
||||
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
|
||||
return home_dirs
|
||||
end
|
||||
|
||||
clouddrive2.find_paths = function(blocks, home_dirs, path_name)
|
||||
local default_path = ''
|
||||
local configs = {}
|
||||
|
||||
default_path = home_dirs[path_name] .. "/CloudDrive2"
|
||||
if #blocks == 0 then
|
||||
table.insert(configs, default_path)
|
||||
else
|
||||
for _, val in pairs(blocks) do
|
||||
table.insert(configs, val .. "/" .. path_name .. "/CloudDrive2")
|
||||
end
|
||||
local without_conf_dir = "/root/" .. path_name .. "/CloudDrive2"
|
||||
if default_path == without_conf_dir then
|
||||
default_path = configs[1]
|
||||
end
|
||||
end
|
||||
|
||||
return configs, default_path
|
||||
end
|
||||
|
||||
return clouddrive2
|
||||
@@ -1,31 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/clouddrive2.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:CloudDrive2 is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:CloudDrive2 is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/clouddrive2.sh port"))
|
||||
if port == "" then
|
||||
port="19798"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open CloudDrive2%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,59 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "CloudDrive is a powerful multi-cloud drive management tool with local mounting of cloud drives."
|
||||
msgstr "CloudDrive 是一个强大的多云盘管理工具,为用户提供包含云盘本地挂载的一站式的多云盘解决方案。"
|
||||
|
||||
msgid "Since mounting within the container requires the use of a special shared mount point, to avoid compatibility issues, only mounting to /mnt/CloudNAS is supported (mounting to other paths cannot be seen by the host). The shared mount point is automatically created by this plug-in, uninstalling the plug-in may cause the deployed CloudDrive container to fail to start or mount (iStoreOS is an exception, because /mnt is the shared mount point by default)."
|
||||
msgstr "由于容器内挂载需要使用特殊的共享挂载点,为避免兼容性问题,只支持挂载到 /mnt/CloudNAS 之下(挂载到其他路径宿主看不到)。共享挂载点由此插件自动创建,卸载插件可能导致系统重启以后已经部署的 CloudDrive 容器无法启动或无法挂载(iStoreOS 是例外,因为 /mnt 默认就是共享挂载点)。"
|
||||
|
||||
msgid "Disclaimer: This LuCI plug-in is developed by individuals. It only facilitates users to deploy CloudDrive containers (https://hub.docker.com/u/cloudnas) and has nothing to do with CloudDrive. Since CloudDrive is not open source software, although this plug-in has restricted its permissions to the greatest extent, it does not make any guarantees about the software content and services provided by CloudDrive. Use at your own risk!"
|
||||
msgstr "免责声明:此 LuCI 插件为个人开发,仅方便用户部署 CloudDrive 容器( https://hub.docker.com/u/cloudnas ),与 CloudDrive 官方无关。由于 CloudDrive 非开源软件,尽管此插件已最大程度限制其权限,但不对 CloudDrive 提供的软件内容和服务做出任何保证。Use at your own risk!"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Docker image"
|
||||
msgstr "Docker 镜像"
|
||||
|
||||
msgid "Temporary file path"
|
||||
msgstr "临时文件路径"
|
||||
|
||||
msgid "Default use 'temp' in 'config path' if not set, please make sure there has enough space"
|
||||
msgstr "留空则使用配置文件路径下的 temp,请确保有足够空间"
|
||||
|
||||
msgid "Share /mnt"
|
||||
msgstr "共享 /mnt"
|
||||
|
||||
msgid "CloudDrive can read and write other mount points under /mnt for its synchronization or backup functions"
|
||||
msgstr "CloudDrive 能够读写 /mnt 下的其他挂载点,用于支持其同步或备份功能"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "CloudDrive2 status:"
|
||||
msgstr "CloudDrive2 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "CloudDrive2 is running"
|
||||
msgstr "CloudDrive2 运行中"
|
||||
|
||||
msgid "CloudDrive2 is not running"
|
||||
msgstr "CloudDrive2 未运行"
|
||||
|
||||
msgid "Open CloudDrive2"
|
||||
msgstr "打开 CloudDrive2"
|
||||
@@ -1,6 +0,0 @@
|
||||
config clouddrive2
|
||||
option 'port' '19798'
|
||||
option 'image' 'default'
|
||||
# option 'config_path' ''
|
||||
# option 'cache_path' ''
|
||||
option 'share_mnt' '0'
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=98
|
||||
|
||||
boot() {
|
||||
# /usr/bin/mountpoint -q /CloudNAS || /usr/bin/mount --make-shared -t tmpfs -o size=4M tmpfs /CloudNAS
|
||||
[ -d /mnt/CloudNAS ] || mkdir -p /mnt/CloudNAS
|
||||
if /usr/bin/mountpoint -q /mnt; then
|
||||
/usr/bin/mount --make-shared /mnt
|
||||
else
|
||||
/usr/bin/mount --make-shared -t tmpfs -o size=4M tmpfs /mnt/CloudNAS
|
||||
fi
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Author jjm2473@gmail.com
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
IMAGE_NAME='default'
|
||||
|
||||
get_image() {
|
||||
IMAGE_NAME=`uci -q get clouddrive2.@clouddrive2[0].image 2>/dev/null`
|
||||
if [ -z "$IMAGE_NAME" -o "$IMAGE_NAME" == "default" ]; then
|
||||
IMAGE_NAME="cloudnas/clouddrive2"
|
||||
fi
|
||||
}
|
||||
|
||||
do_install() {
|
||||
get_image
|
||||
echo "docker pull ${IMAGE_NAME}"
|
||||
docker pull ${IMAGE_NAME}
|
||||
docker stop clouddrive2
|
||||
docker rm -f clouddrive2
|
||||
|
||||
do_install_detail
|
||||
}
|
||||
|
||||
do_install_detail() {
|
||||
local config=`uci -q get clouddrive2.@clouddrive2[0].config_path 2>/dev/null`
|
||||
local cache=`uci -q get clouddrive2.@clouddrive2[0].cache_path 2>/dev/null`
|
||||
local port=`uci -q get clouddrive2.@clouddrive2[0].port 2>/dev/null`
|
||||
local share_mnt=`uci -q get clouddrive2.@clouddrive2[0].share_mnt 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$port" ] && port=19798
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d -e CLOUDDRIVE_HOME=/Config -v \"$config:/Config\" "
|
||||
[ -z "$cache" ] || cmd="$cmd -v \"$cache:/Config/temp\" "
|
||||
|
||||
cmd="$cmd\
|
||||
--dns=172.17.0.1 \
|
||||
-p $port:19798"
|
||||
|
||||
local tz="`uci -q get system.@system[0].zonename | sed 's/ /_/g'`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
# make sure shared mount point existed
|
||||
/etc/init.d/clouddrive2 boot
|
||||
|
||||
if [ "$share_mnt" = 1 ]; then
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
fi
|
||||
cmd="$cmd -v /mnt/CloudNAS:/mnt/CloudNAS:shared"
|
||||
|
||||
# fuse
|
||||
cmd="$cmd\
|
||||
--cap-add SYS_ADMIN \
|
||||
--security-opt apparmor:unconfined \
|
||||
--device /dev/fuse:/dev/fuse"
|
||||
|
||||
cmd="$cmd --name clouddrive2 \"$IMAGE_NAME\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the CloudDrive2"
|
||||
echo " upgrade Upgrade the CloudDrive2"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the CloudDrive2"
|
||||
echo " status CloudDrive2 status"
|
||||
echo " port CloudDrive2 port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker stop clouddrive2
|
||||
docker rm -f clouddrive2
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} clouddrive2
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=clouddrive2' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=clouddrive2' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*->19798/tcp' | sed 's/0.0.0.0:\([0-9]*\)->.*/\1/'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.1-20231208
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for CodeServer
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-codeserver/conffiles
|
||||
/etc/config/codeserver
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
module("luci.controller.codeserver", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "codeserver"}, alias("admin", "services", "codeserver", "config"), _("CodeServer"), 30).dependent = true
|
||||
entry({"admin", "services", "codeserver", "config"}, cbi("codeserver/config"), _("Config"), 10).leaf = true
|
||||
entry({"admin", "services", "codeserver", "tool"}, form("codeserver/tool"), _("Tool"), 30).leaf = true
|
||||
entry({"admin", "services", "codeserver", "console"}, form("codeserver/console"), _("Console"), 50).leaf = true
|
||||
end
|
||||
@@ -1,64 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local codeserver_model = require "luci.model.codeserver"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("codeserver", "codeserver", "/usr/libexec/istorec/codeserver.sh",
|
||||
translate("CodeServer"),
|
||||
translate("CodeServer is a web version of VSCode.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://coder.com/\" target=\"_blank\">https://coder.com/</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("CodeServer status:"))
|
||||
s:append(Template("codeserver/status"))
|
||||
|
||||
s = m:section(TypedSection, "main", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "http_port", translate("HTTP Port").."<b>*</b>")
|
||||
o.default = "8085"
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "image_name", translate("Image").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o:value("lscr.io/linuxserver/code-server:latest", "lscr.io/linuxserver/code-server:latest")
|
||||
o:value("lscr.io/linuxserver/code-server:4.8.3", "lscr.io/linuxserver/code-server:4.8.3")
|
||||
o.default = "lscr.io/linuxserver/code-server:latest"
|
||||
|
||||
local blocks = codeserver_model.blocks()
|
||||
local home = codeserver_model.home()
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
local paths, default_path = codeserver_model.find_paths(blocks, home, "Configs")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
o = s:option(Value, "env_password", "PASSWORD")
|
||||
o.password = true
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "env_hashed_password", "HASHED_PASSWORD")
|
||||
o.datatype = "string"
|
||||
o.password = true
|
||||
|
||||
o = s:option(Value, "env_sudo_password", "SUDO_PASSWORD")
|
||||
o.password = true
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "env_sudo_password_hash", "SUDO_PASSWORD_HASH")
|
||||
o.password = true
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "env_proxy_domain", "PROXY_DOMAIN")
|
||||
o.datatype = "string"
|
||||
|
||||
return m
|
||||
@@ -1,110 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
|
||||
require "luci.util"
|
||||
|
||||
local docker = require "luci.model.docker"
|
||||
local dk = docker.new()
|
||||
|
||||
local container_name = "codeserver"
|
||||
|
||||
local m, s, o
|
||||
local images, networks, container_info, res
|
||||
|
||||
res = dk.containers:inspect({name = container_name})
|
||||
if res.code < 300 then
|
||||
container_info = res.body
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
m=SimpleForm("Console", "", translate("Only works in LAN"))
|
||||
m.submit = false
|
||||
m.reset = false
|
||||
|
||||
local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil
|
||||
local cmd_ttyd = luci.util.exec("command -v ttyd"):match("^.+ttyd") or nil
|
||||
|
||||
if cmd_docker and cmd_ttyd and container_info.State.Status == "running" then
|
||||
local cmd = "/bin/bash"
|
||||
local uid
|
||||
|
||||
s = m:section(SimpleSection)
|
||||
|
||||
o = s:option(Value, "command", translate("Command"))
|
||||
o:value("/bin/sh", "/bin/sh")
|
||||
o:value("/bin/ash", "/bin/ash")
|
||||
o:value("/bin/bash", "/bin/bash")
|
||||
o.default = "/bin/bash"
|
||||
o.forcewrite = true
|
||||
o.write = function(self, section, value)
|
||||
cmd = value
|
||||
end
|
||||
|
||||
o = s:option(Value, "uid", translate("UID"))
|
||||
o.forcewrite = true
|
||||
o.write = function(self, section, value)
|
||||
uid = value
|
||||
end
|
||||
|
||||
o = s:option(Button, "connect")
|
||||
o.render = function(self, section, scope)
|
||||
self.inputstyle = "add"
|
||||
self.title = " "
|
||||
self.inputtitle = translate("Connect")
|
||||
Button.render(self, section, scope)
|
||||
end
|
||||
o.write = function(self, section)
|
||||
local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil
|
||||
local cmd_ttyd = luci.util.exec("command -v ttyd"):match("^.+ttyd") or nil
|
||||
|
||||
if not cmd_docker or not cmd_ttyd or cmd_docker:match("^%s+$") or cmd_ttyd:match("^%s+$")then
|
||||
return
|
||||
end
|
||||
|
||||
local pid = luci.util.trim(luci.util.exec("netstat -lnpt | grep :7682 | grep ttyd | tr -s ' ' | cut -d ' ' -f7 | cut -d'/' -f1"))
|
||||
if pid and pid ~= "" then
|
||||
luci.util.exec("kill -9 " .. pid)
|
||||
end
|
||||
|
||||
local hosts
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local remote = uci:get_bool("dockerd", "globals", "remote_endpoint") or false
|
||||
local host = nil
|
||||
local port = nil
|
||||
local socket = nil
|
||||
|
||||
if remote then
|
||||
host = uci:get("dockerd", "globals", "remote_host") or nil
|
||||
port = uci:get("dockerd", "globals", "remote_port") or nil
|
||||
else
|
||||
socket = uci:get("dockerd", "globals", "socket_path") or "/var/run/docker.sock"
|
||||
end
|
||||
|
||||
if remote and host and port then
|
||||
hosts = host .. ':'.. port
|
||||
elseif socket then
|
||||
hosts = socket
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
if uid and uid ~= "" then
|
||||
uid = "-u " .. uid
|
||||
else
|
||||
uid = ""
|
||||
end
|
||||
|
||||
local start_cmd = string.format('%s -d 2 --once -p 7682 %s -H "unix://%s" exec -it %s %s %s&', cmd_ttyd, cmd_docker, hosts, uid, container_name, cmd)
|
||||
|
||||
os.execute(start_cmd)
|
||||
|
||||
o = s:option(DummyValue, "console")
|
||||
o.container_id = container_id
|
||||
o.template = "codeserver/console"
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
||||
@@ -1,56 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local http = require 'luci.http'
|
||||
|
||||
m=SimpleForm("Tools")
|
||||
m.submit = false
|
||||
m.reset = false
|
||||
|
||||
s = m:section(SimpleSection)
|
||||
|
||||
o = s:option(Value, "action", translate("Action").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o:value("git-config", "git-config")
|
||||
o.default = "git-config"
|
||||
|
||||
local data = {}
|
||||
o = s:option(Value, "username", "user.name")
|
||||
o.datatype = "string"
|
||||
o.placeholder = "username"
|
||||
o:depends("action", "git-config")
|
||||
|
||||
o = s:option(Value, "email", "user.email")
|
||||
o.datatype = "string"
|
||||
o.placeholder = "email@address"
|
||||
o:depends("action", "git-config")
|
||||
|
||||
local t=Template("codeserver/tool")
|
||||
m:append(t)
|
||||
|
||||
local btn_do = s:option(Button, "_do")
|
||||
btn_do.render = function(self, section, scope)
|
||||
self.inputstyle = "add"
|
||||
self.title = " "
|
||||
self.inputtitle = translate("Execute")
|
||||
Button.render(self, section, scope)
|
||||
end
|
||||
|
||||
btn_do.write = function(self, section, value)
|
||||
local action = m:get(section, "action")
|
||||
if action == "git-config" then
|
||||
local user = m:get(section, "username")
|
||||
local email = m:get(section, "email")
|
||||
if user ~= nil and email ~= nil then
|
||||
local cmd = string.format("/usr/libexec/istorec/codeserver.sh %s %s %s", action, user, email)
|
||||
cmd = "/etc/init.d/tasks task_add codeserver " .. luci.util.shellquote(cmd) .. " >/dev/null 2>&1"
|
||||
os.execute(cmd)
|
||||
t.show_log_taskid = "codeserver"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local codeserver = {}
|
||||
|
||||
codeserver.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
codeserver.home = function()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local home_dirs = {}
|
||||
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
|
||||
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
|
||||
home_dirs["Public"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["main_dir"].."/Public")
|
||||
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
|
||||
return home_dirs
|
||||
end
|
||||
|
||||
codeserver.find_paths = function(blocks, home_dirs, path_name)
|
||||
local default_path = ''
|
||||
local configs = {}
|
||||
|
||||
default_path = home_dirs[path_name] .. "/CodeServer"
|
||||
if #blocks == 0 then
|
||||
table.insert(configs, default_path)
|
||||
else
|
||||
for _, val in pairs(blocks) do
|
||||
table.insert(configs, val .. "/" .. path_name .. "/CodeServer")
|
||||
end
|
||||
local without_conf_dir = "/root/" .. path_name .. "/CodeServer"
|
||||
if default_path == without_conf_dir then
|
||||
default_path = configs[1]
|
||||
end
|
||||
end
|
||||
|
||||
return configs, default_path
|
||||
end
|
||||
|
||||
return codeserver
|
||||
@@ -1,10 +0,0 @@
|
||||
<div class="cbi-map">
|
||||
<iframe id="terminal" style="width: 100%; min-height: 600px; border: none; border-radius: 3px;"></iframe>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
const el = document.querySelectorAll(".cbi-value")
|
||||
for (let i = 0; i < el.length; i++) {
|
||||
el[i].style.display = "none";
|
||||
}
|
||||
document.getElementById("terminal").src = "http://" + window.location.hostname + ":7682";
|
||||
</script>
|
||||
@@ -1,31 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/codeserver.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:CodeServer is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:CodeServer is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/codeserver.sh port"))
|
||||
if port == "" then
|
||||
port="8085"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open CodeServer%>" onclick="window.open('http://'+location.hostname+':<%=port%>', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,11 +0,0 @@
|
||||
<%+tasks/embed%>
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function(){
|
||||
const taskd = window.taskd;
|
||||
<% if self.show_log_taskid then -%>
|
||||
taskd.show_log("<%=self.show_log_taskid%>");
|
||||
<%- end %>
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "CodeServer is a web version of VSCode."
|
||||
msgstr "CodeServer 就一个在线版本的 VSCode,可以在线开发。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "HTTP Port"
|
||||
msgstr "HTTP 端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "CodeServer status:"
|
||||
msgstr "CodeServer 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "CodeServer is running"
|
||||
msgstr "CodeServer 运行中"
|
||||
|
||||
msgid "CodeServer is not running"
|
||||
msgstr "CodeServer 未运行"
|
||||
|
||||
msgid "Open CodeServer"
|
||||
msgstr "打开 CodeServer"
|
||||
|
||||
msgid "Tool"
|
||||
msgstr "操作"
|
||||
|
||||
msgid "Console"
|
||||
msgstr "控制台"
|
||||
|
||||
msgid "Only works in LAN"
|
||||
msgstr "只在内网环境下工作。"
|
||||
|
||||
msgid "Execute"
|
||||
msgstr "执行"
|
||||
@@ -1,10 +0,0 @@
|
||||
config main
|
||||
option 'http_port' '8085'
|
||||
option 'image_name' 'lscr.io/linuxserver/code-server:latest'
|
||||
option 'config_path' ''
|
||||
option 'env_password' ''
|
||||
option 'env_hashed_password' ''
|
||||
option 'env_sudo_password' ''
|
||||
option 'env_sudo_password_hash' ''
|
||||
option 'env_proxy_domain' ''
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Author Xiaobao(xiaobao@linkease.com)
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local http_port=`uci get codeserver.@main[0].http_port 2>/dev/null`
|
||||
local image_name=`uci get codeserver.@main[0].image_name 2>/dev/null`
|
||||
local config=`uci get codeserver.@main[0].config_path 2>/dev/null`
|
||||
local env_password=`uci get codeserver.@main[0].env_password 2>/dev/null`
|
||||
local env_hashed_password=`uci get codeserver.@main[0].env_hashed_password 2>/dev/null`
|
||||
local env_sudo_password=`uci get codeserver.@main[0].env_sudo_password 2>/dev/null`
|
||||
local env_sudo_password_hash=`uci get codeserver.@main[0].env_sudo_password_hash 2>/dev/null`
|
||||
local env_proxy_domain=`uci get codeserver.@main[0].env_proxy_domain 2>/dev/null`
|
||||
|
||||
[ -z "$image_name" ] && image_name="lscr.io/linuxserver/code-server:latest"
|
||||
echo "docker pull ${image_name}"
|
||||
docker pull ${image_name}
|
||||
docker rm -f codeserver
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$http_port" ] && http_port=8085
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d -v \"$config:/config\" \
|
||||
--dns=172.17.0.1 \
|
||||
-e DEFAULT_WORKSPACE=/config/workspace \
|
||||
-p $http_port:8443 "
|
||||
|
||||
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
[ -z "$env_password" ] || cmd="$cmd -e \"PASSWORD=$env_password\""
|
||||
[ -z "$env_hashed_password" ] || cmd="$cmd -e \"HASHED_PASSWORD=$env_hashed_password\""
|
||||
[ -z "$env_sudo_password" ] || cmd="$cmd -e \"SUDO_PASSWORD=$env_sudo_password\""
|
||||
[ -z "$env_sudo_password_hash" ] || cmd="$cmd -e \"SUDO_PASSWORD_HASH=$env_sudo_password_hash\""
|
||||
[ -z "$env_proxy_domain" ] || cmd="$cmd -e \"PROXY_DOMAIN=$env_proxy_domain\""
|
||||
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
cmd="$cmd --name codeserver \"$image_name\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the codeserver"
|
||||
echo " upgrade Upgrade the codeserver"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the codeserver"
|
||||
echo " status CodeServer status"
|
||||
echo " port CodeServer port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f codeserver
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} codeserver
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=codeserver' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=codeserver' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
"git-config")
|
||||
docker exec codeserver git config --global user.name "${1}"
|
||||
docker exec codeserver git config --global user.email "${2}"
|
||||
echo "git config --global user.name ${1}"
|
||||
echo "git config --global user.email ${2}"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.0-20221212
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for DrawIO
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker +docker-compose
|
||||
|
||||
define Package/luci-app-drawio/conffiles
|
||||
/etc/config/drawio
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.drawio", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "drawio"}, alias("admin", "services", "drawio", "config"), _("DrawIO"), 30).dependent = true
|
||||
entry({"admin", "services", "drawio", "config"}, cbi("drawio"))
|
||||
end
|
||||
@@ -1,51 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local docker = require "luci.docker"
|
||||
local drawio_model = require "luci.model.drawio"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("drawio", "drawio", "/usr/libexec/istorec/drawio.sh",
|
||||
translate("DrawIO"),
|
||||
translate("DrawIO is a draw.io is a client-side editor for general diagramming and whiteboarding.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://www.diagrams.net/\" target=\"_blank\">https://www.diagrams.net/</a>')
|
||||
|
||||
local dk = docker.new({socket_path="/var/run/docker.sock"})
|
||||
local dockerd_running = dk:_ping().code == 200
|
||||
local docker_info = dockerd_running and dk:info().body or {}
|
||||
local docker_aspace = 0
|
||||
if docker_info.DockerRootDir then
|
||||
local statvfs = nixio.fs.statvfs(docker_info.DockerRootDir)
|
||||
docker_aspace = statvfs and (statvfs.bavail * statvfs.bsize) or 0
|
||||
end
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("DrawIO status:"))
|
||||
s:append(Template("drawio/status"))
|
||||
|
||||
s = m:section(TypedSection, "main", translate("Setup"),
|
||||
(docker_aspace < 2147483648 and
|
||||
(translate("The free space of Docker is less than 2GB, which may cause the installation to fail.")
|
||||
.. "<br>") or "") .. translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "port", translate("Port").."<b>*</b>")
|
||||
o.default = "8091"
|
||||
o.datatype = "port"
|
||||
|
||||
local blocks = drawio_model.blocks()
|
||||
local home = drawio_model.home()
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
local paths, default_path = drawio_model.find_paths(blocks, home, "Configs")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
return m
|
||||
@@ -1,55 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local drawio = {}
|
||||
|
||||
drawio.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
drawio.home = function()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local home_dirs = {}
|
||||
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
|
||||
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
|
||||
home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
|
||||
home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads")
|
||||
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
|
||||
return home_dirs
|
||||
end
|
||||
|
||||
drawio.find_paths = function(blocks, home_dirs, path_name)
|
||||
local default_path = ''
|
||||
local configs = {}
|
||||
|
||||
default_path = home_dirs[path_name] .. "/DrawIO"
|
||||
if #blocks == 0 then
|
||||
table.insert(configs, default_path)
|
||||
else
|
||||
for _, val in pairs(blocks) do
|
||||
table.insert(configs, val .. "/" .. path_name .. "/DrawIO")
|
||||
end
|
||||
local without_conf_dir = "/root/" .. path_name .. "/DrawIO"
|
||||
if default_path == without_conf_dir then
|
||||
default_path = configs[1]
|
||||
end
|
||||
end
|
||||
|
||||
return configs, default_path
|
||||
end
|
||||
|
||||
return drawio
|
||||
@@ -1,31 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/drawio.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:DrawIO is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:DrawIO is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/drawio.sh port"))
|
||||
if port == "" then
|
||||
port="8091"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open DrawIO%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,47 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "DrawIO"
|
||||
msgstr "DrawIO绘图"
|
||||
|
||||
msgid "DrawIO is a draw.io is a client-side editor for general diagramming and whiteboarding."
|
||||
msgstr "DrawIO 是运行在浏览器中的在线绘图工具。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "DrawIO status:"
|
||||
msgstr "DrawIO 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "DrawIO is running"
|
||||
msgstr "DrawIO 运行中"
|
||||
|
||||
msgid "DrawIO is not running"
|
||||
msgstr "DrawIO 未运行"
|
||||
|
||||
msgid "Open DrawIO"
|
||||
msgstr "打开 DrawIO"
|
||||
|
||||
msgid "The free space of Docker is less than 2GB, which may cause the installation to fail."
|
||||
msgstr "Docker 可用空间已不足2GB,可能导致安装失败。"
|
||||
|
||||
msgid "Please make sure there has enough space"
|
||||
msgstr "请确保有足够空间"
|
||||
@@ -1,4 +0,0 @@
|
||||
config main
|
||||
option 'port' '8091'
|
||||
option 'config_path' ''
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Author Xiaobao(xiaobao@linkease.com)
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local port=`uci get drawio.@main[0].port 2>/dev/null`
|
||||
local config=`uci get drawio.@main[0].config_path 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $config
|
||||
RET=$?
|
||||
if [ ! "$RET" = "0" ]; then
|
||||
echo "mkdir config path failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z $port ] && port=8090
|
||||
sed 's/PORT_VAR/'$port'/g' /usr/share/drawio/docker-compose.template.yaml > $config/docker-compose.yaml
|
||||
RET=$?
|
||||
if [ ! "$RET" = "0" ]; then
|
||||
echo "convert docker-compose.yaml failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $config
|
||||
export COMPOSE_PROJECT_NAME=linkease-drawio
|
||||
docker-compose down || true
|
||||
docker-compose up -d
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the drawio"
|
||||
echo " upgrade Upgrade the drawio"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the drawio"
|
||||
echo " status DrawIO status"
|
||||
echo " port DrawIO port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f drawio
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
config=`uci get drawio.@main[0].config_path 2>/dev/null`
|
||||
cd $config && docker-compose ${ACTION}
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=linkease-drawio_drawio_1' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=linkease-drawio_drawio_1' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,67 +0,0 @@
|
||||
version: '3'
|
||||
services:
|
||||
plantuml-server:
|
||||
image: linkease/drawio-plantuml-server:2022121901
|
||||
expose:
|
||||
- "8080"
|
||||
networks:
|
||||
- drawionet
|
||||
volumes:
|
||||
- fonts_volume:/usr/share/fonts/drawio
|
||||
image-export:
|
||||
image: linkease/drawio-image-export:2022121901
|
||||
expose:
|
||||
- "8000"
|
||||
networks:
|
||||
- drawionet
|
||||
volumes:
|
||||
- fonts_volume:/usr/share/fonts/drawio
|
||||
environment:
|
||||
- DRAWIO_SERVER_URL=${DRAWIO_BASE_URL}
|
||||
drawio:
|
||||
image: jgraph/drawio
|
||||
ports:
|
||||
- "PORT_VAR:8080"
|
||||
links:
|
||||
- plantuml-server:plantuml-server
|
||||
- image-export:image-export
|
||||
depends_on:
|
||||
- plantuml-server
|
||||
- image-export
|
||||
networks:
|
||||
- drawionet
|
||||
environment:
|
||||
- DRAWIO_SELF_CONTAINED=1
|
||||
- PLANTUML_URL=http://plantuml-server:8080/
|
||||
- EXPORT_URL=http://image-export:8000/
|
||||
- DRAWIO_BASE_URL=${DRAWIO_BASE_URL}
|
||||
- DRAWIO_CSP_HEADER=${DRAWIO_CSP_HEADER}
|
||||
- DRAWIO_VIEWER_URL=${DRAWIO_VIEWER_URL}
|
||||
- DRAWIO_LIGHTBOX_URL=${DRAWIO_LIGHTBOX_URL}
|
||||
- DRAWIO_CONFIG=${DRAWIO_CONFIG}
|
||||
- DRAWIO_GOOGLE_CLIENT_ID=${DRAWIO_GOOGLE_CLIENT_ID}
|
||||
- DRAWIO_GOOGLE_APP_ID=${DRAWIO_GOOGLE_APP_ID}
|
||||
- DRAWIO_GOOGLE_CLIENT_SECRET=${DRAWIO_GOOGLE_CLIENT_SECRET}
|
||||
- DRAWIO_GOOGLE_VIEWER_CLIENT_ID=${DRAWIO_GOOGLE_VIEWER_CLIENT_ID}
|
||||
- DRAWIO_GOOGLE_VIEWER_APP_ID=${DRAWIO_GOOGLE_VIEWER_APP_ID}
|
||||
- DRAWIO_GOOGLE_VIEWER_CLIENT_SECRET=${DRAWIO_GOOGLE_VIEWER_CLIENT_SECRET}
|
||||
- DRAWIO_MSGRAPH_CLIENT_ID=${DRAWIO_MSGRAPH_CLIENT_ID}
|
||||
- DRAWIO_MSGRAPH_CLIENT_SECRET=${DRAWIO_MSGRAPH_CLIENT_SECRET}
|
||||
- DRAWIO_MSGRAPH_TENANT_ID=${DRAWIO_MSGRAPH_TENANT_ID}
|
||||
- DRAWIO_GITLAB_ID=${DRAWIO_GITLAB_ID}
|
||||
- DRAWIO_GITLAB_SECRET=${DRAWIO_GITLAB_SECRET}
|
||||
- DRAWIO_GITLAB_URL=${DRAWIO_GITLAB_URL}
|
||||
- DRAWIO_CLOUD_CONVERT_APIKEY=${DRAWIO_CLOUD_CONVERT_APIKEY}
|
||||
- DRAWIO_CACHE_DOMAIN=${DRAWIO_CACHE_DOMAIN}
|
||||
- DRAWIO_MEMCACHED_ENDPOINT=${DRAWIO_MEMCACHED_ENDPOINT}
|
||||
- DRAWIO_PUSHER_MODE=2
|
||||
- DRAWIO_IOT_ENDPOINT=${DRAWIO_IOT_ENDPOINT}
|
||||
- DRAWIO_IOT_CERT_PEM=${DRAWIO_IOT_CERT_PEM}
|
||||
- DRAWIO_IOT_PRIVATE_KEY=${DRAWIO_IOT_PRIVATE_KEY}
|
||||
- DRAWIO_IOT_ROOT_CA=${DRAWIO_IOT_ROOT_CA}
|
||||
- DRAWIO_MXPUSHER_ENDPOINT=${DRAWIO_MXPUSHER_ENDPOINT}
|
||||
networks:
|
||||
drawionet:
|
||||
|
||||
volumes:
|
||||
fonts_volume:
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.3-20231208
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for Emby
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-emby/conffiles
|
||||
/etc/config/emby
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.emby", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "emby"}, alias("admin", "services", "emby", "config"), _("Emby"), 30).dependent = true
|
||||
entry({"admin", "services", "emby", "config"}, cbi("emby"))
|
||||
end
|
||||
@@ -1,63 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local emby_model = require "luci.model.emby"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("emby", "emby", "/usr/libexec/istorec/emby.sh",
|
||||
translate("Emby"),
|
||||
translate("Emby brings together your personal videos, music, photos, and live television.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://emby.media/\" target=\"_blank\">https://emby.media/</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("Emby status:"))
|
||||
s:append(Template("emby/status"))
|
||||
|
||||
s = m:section(TypedSection, "main", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Flag, "hostnet", translate("Host network"), translate("Emby running in host network, for DLNA application, port is always 8096 if enabled"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "http_port", translate("HTTP Port").."<b>*</b>")
|
||||
o.default = "8097"
|
||||
o.datatype = "port"
|
||||
o:depends("hostnet", 0)
|
||||
|
||||
o = s:option(Value, "image_name", translate("Image").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o:value("emby/embyserver", "emby/embyserver")
|
||||
o:value("emby/embyserver:4.8.0.59", "emby/embyserver:4.8.0.59")
|
||||
o:value("emby/embyserver_arm32v7", "emby/embyserver_arm32v7")
|
||||
o:value("emby/embyserver_arm64v8", "emby/embyserver_arm64v8")
|
||||
o.default = "emby/embyserver"
|
||||
|
||||
local blocks = emby_model.blocks()
|
||||
local home = emby_model.home()
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
local paths, default_path = emby_model.find_paths(blocks, home, "Configs")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
o = s:option(Value, "media_path", translate("Media path"), translate("Not required, all disk is mounted in") .. " <a href='/cgi-bin/luci/admin/services/linkease/file/?path=/root/mnt' target='_blank'>/mnt</a>")
|
||||
o.datatype = "string"
|
||||
|
||||
o = s:option(Value, "cache_path", translate("Transcode cache path"), translate("Default use 'transcodes' in 'config path' if not set, please make sure there has enough space"))
|
||||
o.datatype = "string"
|
||||
local paths, default_path = emby_model.find_paths(blocks, home, "Caches")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
return m
|
||||
@@ -1,55 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local emby = {}
|
||||
|
||||
emby.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
emby.home = function()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local home_dirs = {}
|
||||
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
|
||||
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
|
||||
home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
|
||||
home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads")
|
||||
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
|
||||
return home_dirs
|
||||
end
|
||||
|
||||
emby.find_paths = function(blocks, home_dirs, path_name)
|
||||
local default_path = ''
|
||||
local configs = {}
|
||||
|
||||
default_path = home_dirs[path_name] .. "/Emby"
|
||||
if #blocks == 0 then
|
||||
table.insert(configs, default_path)
|
||||
else
|
||||
for _, val in pairs(blocks) do
|
||||
table.insert(configs, val .. "/" .. path_name .. "/Emby")
|
||||
end
|
||||
local without_conf_dir = "/root/" .. path_name .. "/Emby"
|
||||
if default_path == without_conf_dir then
|
||||
default_path = configs[1]
|
||||
end
|
||||
end
|
||||
|
||||
return configs, default_path
|
||||
end
|
||||
|
||||
return emby
|
||||
@@ -1,31 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/emby.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:Emby is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:Emby is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/emby.sh port"))
|
||||
if port == "" then
|
||||
port="8096"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open Emby%>" onclick="window.open('http://'+location.hostname+':<%=port%>', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,44 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "Emby brings together your personal videos, music, photos, and live television."
|
||||
msgstr "Emby 是一个多媒体串流平台。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "HTTP Port"
|
||||
msgstr "HTTP 端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "Emby status:"
|
||||
msgstr "Emby 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Emby is running"
|
||||
msgstr "Emby 运行中"
|
||||
|
||||
msgid "Emby is not running"
|
||||
msgstr "Emby 未运行"
|
||||
|
||||
msgid "Open Emby"
|
||||
msgstr "打开 Emby"
|
||||
|
||||
msgid "Not required, all disk is mounted in"
|
||||
msgstr "可不填,所有硬盘都在"
|
||||
|
||||
msgid "Emby running in host network, for DLNA application, port is always 8096 if enabled"
|
||||
msgstr "在宿主网络运行 Emby,以支持 DLNA 等应用,例如投屏,如果启用则端口固定为8096,需注意端口与 Jellyfin 冲突"
|
||||
@@ -1,6 +0,0 @@
|
||||
config main
|
||||
option 'hostnet' '0'
|
||||
option 'http_port' '8097'
|
||||
option 'image_name' 'emby/embyserver'
|
||||
option 'config_path' ''
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Author Xiaobao(xiaobao@linkease.com)
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local hostnet=`uci get emby.@main[0].hostnet 2>/dev/null`
|
||||
local http_port=`uci get emby.@main[0].http_port 2>/dev/null`
|
||||
local image_name=`uci get emby.@main[0].image_name 2>/dev/null`
|
||||
local config=`uci get emby.@main[0].config_path 2>/dev/null`
|
||||
local media=`uci get emby.@main[0].media_path 2>/dev/null`
|
||||
local cache=`uci get emby.@main[0].cache_path 2>/dev/null`
|
||||
|
||||
[ -z "$image_name" ] && image_name="emby/embyserver"
|
||||
echo "docker pull ${image_name}"
|
||||
docker pull ${image_name}
|
||||
docker rm -f emby
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# not conflict with jellyfin
|
||||
[ -z "$http_port" ] && http_port=8097
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d -u 0 -e UID=0 -e GID=0 -e GIDLIST=0 -v \"$config:/config\" "
|
||||
|
||||
if [ -d /dev/dri ]; then
|
||||
cmd="$cmd\
|
||||
--device /dev/dri:/dev/dri \
|
||||
--privileged "
|
||||
fi
|
||||
|
||||
if [ "$hostnet" = 1 ]; then
|
||||
cmd="$cmd\
|
||||
--dns=127.0.0.1 \
|
||||
--network=host "
|
||||
else
|
||||
cmd="$cmd\
|
||||
--dns=172.17.0.1 \
|
||||
-p $http_port:8096 "
|
||||
fi
|
||||
|
||||
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
[ -z "$cache" ] || cmd="$cmd -v \"$cache:/config/cache\""
|
||||
[ -z "$media" ] || cmd="$cmd -v \"$media:/data\""
|
||||
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
cmd="$cmd --name emby \"$image_name\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the emby"
|
||||
echo " upgrade Upgrade the emby"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the emby"
|
||||
echo " status Emby status"
|
||||
echo " port Emby port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f emby
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} emby
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=emby' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=emby' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*->8096/tcp' | sed 's/0.0.0.0:\([0-9]*\)->.*/\1/'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.0-20221212
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for Excalidraw
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker +docker-compose
|
||||
|
||||
define Package/luci-app-excalidraw/conffiles
|
||||
/etc/config/excalidraw
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.excalidraw", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "excalidraw"}, alias("admin", "services", "excalidraw", "config"), _("Excalidraw"), 30).dependent = true
|
||||
entry({"admin", "services", "excalidraw", "config"}, cbi("excalidraw"))
|
||||
end
|
||||
@@ -1,57 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local docker = require "luci.docker"
|
||||
local excalidraw_model = require "luci.model.excalidraw"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("excalidraw", "excalidraw", "/usr/libexec/istorec/excalidraw.sh",
|
||||
translate("Excalidraw"),
|
||||
translate("Excalidraw is a self-host virtual whiteboard for sketching hand-drawn like diagrams.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://excalidraw.com/\" target=\"_blank\">https://excalidraw.com/</a>')
|
||||
|
||||
local dk = docker.new({socket_path="/var/run/docker.sock"})
|
||||
local dockerd_running = dk:_ping().code == 200
|
||||
local docker_info = dockerd_running and dk:info().body or {}
|
||||
local docker_aspace = 0
|
||||
if docker_info.DockerRootDir then
|
||||
local statvfs = nixio.fs.statvfs(docker_info.DockerRootDir)
|
||||
docker_aspace = statvfs and (statvfs.bavail * statvfs.bsize) or 0
|
||||
end
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("Excalidraw status:"))
|
||||
s:append(Template("excalidraw/status"))
|
||||
|
||||
s = m:section(TypedSection, "main", translate("Setup"),
|
||||
(docker_aspace < 2147483648 and
|
||||
(translate("The free space of Docker is less than 2GB, which may cause the installation to fail.")
|
||||
.. "<br>") or "") .. translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "port", translate("Port").."<b>*</b>")
|
||||
o.default = "8090"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "image_ver", translate("Image").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o.default = "v0.13.0"
|
||||
o:value("v0.13.0", "v0.13.0")
|
||||
|
||||
local blocks = excalidraw_model.blocks()
|
||||
local home = excalidraw_model.home()
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
local paths, default_path = excalidraw_model.find_paths(blocks, home, "Configs")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
return m
|
||||
@@ -1,55 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local excalidraw = {}
|
||||
|
||||
excalidraw.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
excalidraw.home = function()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local home_dirs = {}
|
||||
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
|
||||
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
|
||||
home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
|
||||
home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads")
|
||||
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
|
||||
return home_dirs
|
||||
end
|
||||
|
||||
excalidraw.find_paths = function(blocks, home_dirs, path_name)
|
||||
local default_path = ''
|
||||
local configs = {}
|
||||
|
||||
default_path = home_dirs[path_name] .. "/Excalidraw"
|
||||
if #blocks == 0 then
|
||||
table.insert(configs, default_path)
|
||||
else
|
||||
for _, val in pairs(blocks) do
|
||||
table.insert(configs, val .. "/" .. path_name .. "/Excalidraw")
|
||||
end
|
||||
local without_conf_dir = "/root/" .. path_name .. "/Excalidraw"
|
||||
if default_path == without_conf_dir then
|
||||
default_path = configs[1]
|
||||
end
|
||||
end
|
||||
|
||||
return configs, default_path
|
||||
end
|
||||
|
||||
return excalidraw
|
||||
@@ -1,31 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/excalidraw.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:Excalidraw is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:Excalidraw is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/excalidraw.sh port"))
|
||||
if port == "" then
|
||||
port="8090"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open Excalidraw%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,48 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "Excalidraw"
|
||||
msgstr "Excalidraw画板"
|
||||
|
||||
msgid "Excalidraw is a self-host virtual whiteboard for sketching hand-drawn like diagrams."
|
||||
msgstr "Excalidraw 是支持多人协同的私有化在线画板工具。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "Excalidraw status:"
|
||||
msgstr "Excalidraw 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Excalidraw is running"
|
||||
msgstr "Excalidraw 运行中"
|
||||
|
||||
msgid "Excalidraw is not running"
|
||||
msgstr "Excalidraw 未运行"
|
||||
|
||||
msgid "Open Excalidraw"
|
||||
msgstr "打开 Excalidraw"
|
||||
|
||||
msgid "The free space of Docker is less than 2GB, which may cause the installation to fail."
|
||||
msgstr "Docker 可用空间已不足2GB,可能导致安装失败。"
|
||||
|
||||
msgid "Please make sure there has enough space"
|
||||
msgstr "请确保有足够空间"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
config main
|
||||
option 'port' '8090'
|
||||
option 'config_path' ''
|
||||
option 'image_ver' ''
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Author Xiaobao(xiaobao@linkease.com)
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local port=`uci get excalidraw.@main[0].port 2>/dev/null`
|
||||
local config=`uci get excalidraw.@main[0].config_path 2>/dev/null`
|
||||
local image_ver=`uci get excalidraw.@main[0].image_ver 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $config
|
||||
RET=$?
|
||||
if [ ! "$RET" = "0" ]; then
|
||||
echo "mkdir config path failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z $port ] && port=8090
|
||||
sed 's/PORT_VAR/'$port'/g; s/IMAGE_VER_VAR/'$image_ver'/g' /usr/share/excalidraw/docker-compose.template.yaml > $config/docker-compose.yaml
|
||||
RET=$?
|
||||
if [ ! "$RET" = "0" ]; then
|
||||
echo "convert docker-compose.yaml failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $config
|
||||
export COMPOSE_PROJECT_NAME=linkease-excalidraw
|
||||
docker-compose down || true
|
||||
docker-compose up -d
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the excalidraw"
|
||||
echo " upgrade Upgrade the excalidraw"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the excalidraw"
|
||||
echo " status Excalidraw status"
|
||||
echo " port Excalidraw port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f excalidraw
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
config=`uci get excalidraw.@main[0].config_path 2>/dev/null`
|
||||
cd $config && docker-compose ${ACTION}
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=linkease-excalidraw_frontend_1' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
docker ps --all -f 'name=linkease-excalidraw_frontend_1' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,25 +0,0 @@
|
||||
version: "3"
|
||||
|
||||
networks:
|
||||
excalidrawnet:
|
||||
|
||||
services:
|
||||
frontend:
|
||||
image: janson/excalidraw:IMAGE_VER_VAR
|
||||
ports:
|
||||
- PORT_VAR:80
|
||||
networks:
|
||||
- excalidrawnet
|
||||
|
||||
storage:
|
||||
image: janson/excalidraw-storage-backend:IMAGE_VER_VAR
|
||||
restart: always
|
||||
environment:
|
||||
- PORT=8081
|
||||
networks:
|
||||
- excalidrawnet
|
||||
|
||||
room:
|
||||
image: janson/excalidraw-room:IMAGE_VER_VAR
|
||||
networks:
|
||||
- excalidrawnet
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.2-20231208
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for FeiShuVpn
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker
|
||||
|
||||
define Package/luci-app-feishuvpn/conffiles
|
||||
/etc/config/feishuvpn
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.feishuvpn", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "feishuvpn"}, alias("admin", "services", "feishuvpn", "config"), _("FeiShuVpn"), 30).dependent = true
|
||||
entry({"admin", "services", "feishuvpn", "config"}, cbi("feishuvpn"))
|
||||
end
|
||||
@@ -1,57 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local docker = require "luci.docker"
|
||||
local feishuvpn_model = require "luci.model.feishuvpn"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("feishuvpn", "feishuvpn", "/usr/libexec/istorec/feishuvpn.sh",
|
||||
translate("FeiShuVpn"),
|
||||
translate("FeiShuVpn is p2p vpn client.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://wiki.feishuwg.com/\" target=\"_blank\">https://wiki.feishuwg.com/</a>')
|
||||
|
||||
local dk = docker.new({socket_path="/var/run/docker.sock"})
|
||||
local dockerd_running = dk:_ping().code == 200
|
||||
local docker_info = dockerd_running and dk:info().body or {}
|
||||
local docker_aspace = 0
|
||||
if docker_info.DockerRootDir then
|
||||
local statvfs = nixio.fs.statvfs(docker_info.DockerRootDir)
|
||||
docker_aspace = statvfs and (statvfs.bavail * statvfs.bsize) or 0
|
||||
end
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("FeiShuVpn status:"))
|
||||
s:append(Template("feishuvpn/status"))
|
||||
|
||||
s = m:section(TypedSection, "main", translate("Setup"),
|
||||
(docker_aspace < 2147483648 and
|
||||
(translate("The free space of Docker is less than 2GB, which may cause the installation to fail.")
|
||||
.. "<br>") or "") .. translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "port", translate("Port").."<b>*</b>")
|
||||
o.default = "9091"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "image_name", translate("Image").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o.default = "registry.cn-qingdao.aliyuncs.com/feishuwg/p2p:v2.2"
|
||||
o:value("registry.cn-qingdao.aliyuncs.com/feishuwg/p2p:v2.2", "registry.cn-qingdao.aliyuncs.com/feishuwg/p2p:v2.2")
|
||||
|
||||
local blocks = feishuvpn_model.blocks()
|
||||
local home = feishuvpn_model.home()
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
local paths, default_path = feishuvpn_model.find_paths(blocks, home, "Configs")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
return m
|
||||
@@ -1,55 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local feishuvpn = {}
|
||||
|
||||
feishuvpn.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
feishuvpn.home = function()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local home_dirs = {}
|
||||
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
|
||||
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
|
||||
home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
|
||||
home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads")
|
||||
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
|
||||
return home_dirs
|
||||
end
|
||||
|
||||
feishuvpn.find_paths = function(blocks, home_dirs, path_name)
|
||||
local default_path = ''
|
||||
local configs = {}
|
||||
|
||||
default_path = home_dirs[path_name] .. "/FeiShuVpn"
|
||||
if #blocks == 0 then
|
||||
table.insert(configs, default_path)
|
||||
else
|
||||
for _, val in pairs(blocks) do
|
||||
table.insert(configs, val .. "/" .. path_name .. "/FeiShuVpn")
|
||||
end
|
||||
local without_conf_dir = "/root/" .. path_name .. "/FeiShuVpn"
|
||||
if default_path == without_conf_dir then
|
||||
default_path = configs[1]
|
||||
end
|
||||
end
|
||||
|
||||
return configs, default_path
|
||||
end
|
||||
|
||||
return feishuvpn
|
||||
@@ -1,31 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/feishuvpn.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:FeiShuVpn is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:FeiShuVpn is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/feishuvpn.sh port"))
|
||||
if port == "" then
|
||||
port="9091"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open FeiShuVpn%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,50 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "FeiShuVpn"
|
||||
msgstr "飞鼠组网"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "FeiShuVpn is p2p vpn client."
|
||||
msgstr "飞鼠组网是一个点对点的组网工具。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "FeiShuVpn status:"
|
||||
msgstr "飞鼠组网的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "FeiShuVpn is running"
|
||||
msgstr "飞鼠组网运行中"
|
||||
|
||||
msgid "FeiShuVpn is not running"
|
||||
msgstr "飞鼠组网未运行"
|
||||
|
||||
msgid "Open FeiShuVpn"
|
||||
msgstr "打开飞鼠组网"
|
||||
|
||||
msgid "Not required, all disk will be mounted under %s"
|
||||
msgstr "可不填,所有硬盘都会挂载到 %s 下"
|
||||
|
||||
msgid "The free space of Docker is less than 2GB, which may cause the installation to fail."
|
||||
msgstr "Docker 可用空间已不足2GB,可能导致安装失败。"
|
||||
|
||||
msgid "Please make sure there has enough space"
|
||||
msgstr "请确保有足够空间"
|
||||
@@ -1,3 +0,0 @@
|
||||
config main
|
||||
option 'config_path' ''
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Author Xiaobao(xiaobao@linkease.com)
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local image_name=`uci get feishuvpn.@main[0].image_name 2>/dev/null`
|
||||
local config=`uci get feishuvpn.@main[0].config_path 2>/dev/null`
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$image_name" ] && image_name="registry.cn-qingdao.aliyuncs.com/feishuwg/p2p:v2.2"
|
||||
echo "docker pull ${image_name}"
|
||||
docker pull ${image_name}
|
||||
docker rm -f feishuvpn
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d -h FeiShuVpnServer -v \"$config:/data/feishu/conf\" "
|
||||
|
||||
cmd="$cmd\
|
||||
--cap-add=ALL \
|
||||
--privileged=true \
|
||||
--device=/dev/net/tun \
|
||||
--dns=127.0.0.1 \
|
||||
--network=host "
|
||||
|
||||
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
cmd="$cmd --name feishuvpn \"$image_name\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the feishuvpn"
|
||||
echo " upgrade Upgrade the feishuvpn"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the feishuvpn"
|
||||
echo " status FeiShuVpn status"
|
||||
echo " port FeiShuVpn port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f feishuvpn
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} feishuvpn
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=feishuvpn' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
echo 9091
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.0.3-20240304
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for Gogs
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-gogs/conffiles
|
||||
/etc/config/gogs
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.gogs", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "gogs"}, alias("admin", "services", "gogs", "config"), _("Gogs"), 30).dependent = true
|
||||
entry({"admin", "services", "gogs", "config"}, cbi("gogs"))
|
||||
end
|
||||
@@ -1,51 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local gogs_model = require "luci.model.gogs"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("gogs", "gogs", "/usr/libexec/istorec/gogs.sh",
|
||||
translate("Gogs"),
|
||||
translate("Gogs is a painless self-hosted Git service.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://gogs.io/\" target=\"_blank\">https://gogs.io/</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("Gogs status:"))
|
||||
s:append(Template("gogs/status"))
|
||||
|
||||
s = m:section(TypedSection, "main", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "http_port", translate("HTTP Port").."<b>*</b>")
|
||||
o.default = "3001"
|
||||
o.datatype = "string"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "ssh_port", translate("SSH Port").."<b>*</b>")
|
||||
o.default = "3022"
|
||||
o.datatype = "string"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "image_name", translate("Image").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
o:value("gogs/gogs:latest", "gogs/gogs:latest")
|
||||
o:value("gogs/gogs:0.12", "gogs/gogs:0.12")
|
||||
o.default = "gogs/gogs:latest"
|
||||
|
||||
local blocks = gogs_model.blocks()
|
||||
local home = gogs_model.home()
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.datatype = "string"
|
||||
|
||||
local paths, default_path = gogs_model.find_paths(blocks, home, "Configs")
|
||||
for _, val in pairs(paths) do
|
||||
o:value(val, val)
|
||||
end
|
||||
o.default = default_path
|
||||
|
||||
return m
|
||||
@@ -1,54 +0,0 @@
|
||||
local util = require "luci.util"
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local gogs = {}
|
||||
|
||||
gogs.blocks = function()
|
||||
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
|
||||
local vals = {}
|
||||
if f then
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
local obj = jsonc.parse(ret)
|
||||
for _, val in pairs(obj["blockdevices"]) do
|
||||
local fsize = val["fssize"]
|
||||
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
|
||||
-- fsize > 1G
|
||||
vals[#vals+1] = val["mountpoint"]
|
||||
end
|
||||
end
|
||||
end
|
||||
return vals
|
||||
end
|
||||
|
||||
gogs.home = function()
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local home_dirs = {}
|
||||
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
|
||||
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
|
||||
home_dirs["Public"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["main_dir"].."/Public")
|
||||
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
|
||||
return home_dirs
|
||||
end
|
||||
|
||||
gogs.find_paths = function(blocks, home_dirs, path_name)
|
||||
local default_path = ''
|
||||
local configs = {}
|
||||
|
||||
default_path = home_dirs[path_name] .. "/Gogs"
|
||||
if #blocks == 0 then
|
||||
table.insert(configs, default_path)
|
||||
else
|
||||
for _, val in pairs(blocks) do
|
||||
table.insert(configs, val .. "/" .. path_name .. "/Gogs")
|
||||
end
|
||||
local without_conf_dir = "/root/" .. path_name .. "/Gogs"
|
||||
if default_path == without_conf_dir then
|
||||
default_path = configs[1]
|
||||
end
|
||||
end
|
||||
|
||||
return configs, default_path
|
||||
end
|
||||
|
||||
return gogs
|
||||
@@ -1,31 +0,0 @@
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local container_status = util.trim(util.exec("/usr/libexec/istorec/gogs.sh status"))
|
||||
local container_install = (string.len(container_status) > 0)
|
||||
local container_running = container_status == "running"
|
||||
-%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%:Status%></label>
|
||||
<div class="cbi-value-field">
|
||||
<% if container_running then %>
|
||||
<button class="cbi-button cbi-button-success" disabled="true"><%:Gogs is running%></button>
|
||||
<% else %>
|
||||
<button class="cbi-button cbi-button-negative" disabled="true"><%:Gogs is not running%></button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
if container_running then
|
||||
local port=util.trim(util.exec("/usr/libexec/istorec/gogs.sh port"))
|
||||
if port == "" then
|
||||
port="3001"
|
||||
end
|
||||
-%>
|
||||
<div class="cbi-value cbi-value-last">
|
||||
<label class="cbi-value-title"> </label>
|
||||
<div class="cbi-value-field">
|
||||
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open Gogs%>" onclick="window.open('http://'+location.hostname+':<%=port%>', '_blank')">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,42 +0,0 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
msgid "Official website:"
|
||||
msgstr "官方网站:"
|
||||
|
||||
msgid "Gogs is a painless self-hosted Git service."
|
||||
msgstr "Gogs 是一个轻松易用的 Git 服务。"
|
||||
|
||||
msgid "Config path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "HTTP Port"
|
||||
msgstr "HTTP 端口"
|
||||
|
||||
msgid "SSH Port"
|
||||
msgstr "SSH 端口"
|
||||
|
||||
msgid "Service Status"
|
||||
msgstr "服务状态"
|
||||
|
||||
msgid "Gogs status:"
|
||||
msgstr "Gogs 的状态信息如下:"
|
||||
|
||||
msgid "Setup"
|
||||
msgstr "安装配置"
|
||||
|
||||
msgid "The following parameters will only take effect during installation or upgrade:"
|
||||
msgstr "以下参数只在安装或者升级时才会生效:"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "Gogs is running"
|
||||
msgstr "Gogs 运行中"
|
||||
|
||||
msgid "Gogs is not running"
|
||||
msgstr "Gogs 未运行"
|
||||
|
||||
msgid "Open Gogs"
|
||||
msgstr "打开 Gogs"
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
config main
|
||||
option 'http_port' '3001'
|
||||
option 'ssh_port' '3022'
|
||||
option 'image_name' 'gogs/gogs:latest'
|
||||
option 'config_path' ''
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Author Xiaobao(xiaobao@linkease.com)
|
||||
|
||||
ACTION=${1}
|
||||
shift 1
|
||||
|
||||
do_install() {
|
||||
local http_port=`uci get gogs.@main[0].http_port 2>/dev/null`
|
||||
local ssh_port=`uci get gogs.@main[0].ssh_port 2>/dev/null`
|
||||
local image_name=`uci get gogs.@main[0].image_name 2>/dev/null`
|
||||
local config=`uci get gogs.@main[0].config_path 2>/dev/null`
|
||||
|
||||
[ -z "$image_name" ] && image_name="gogs/gogs:latest"
|
||||
echo "docker pull ${image_name}"
|
||||
docker pull ${image_name}
|
||||
docker rm -f gogs
|
||||
|
||||
if [ -z "$config" ]; then
|
||||
echo "config path is empty!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$http_port" ]; then
|
||||
http_port=3001
|
||||
fi
|
||||
if [ -z "$ssh_port" ]; then
|
||||
ssh_port=3022
|
||||
fi
|
||||
|
||||
local cmd="docker run --restart=unless-stopped -d -v \"$config:/data\" \
|
||||
--dns=172.17.0.1 \
|
||||
-p $http_port:3000 \
|
||||
-p $ssh_port:22 "
|
||||
|
||||
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
|
||||
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
|
||||
|
||||
cmd="$cmd -v /mnt:/mnt"
|
||||
mountpoint -q /mnt && cmd="$cmd:rslave"
|
||||
cmd="$cmd --name gogs \"$image_name\""
|
||||
|
||||
echo "$cmd"
|
||||
eval "$cmd"
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 sub-command"
|
||||
echo "where sub-command is one of:"
|
||||
echo " install Install the gogs"
|
||||
echo " upgrade Upgrade the gogs"
|
||||
echo " rm/start/stop/restart Remove/Start/Stop/Restart the gogs"
|
||||
echo " status Gogs status"
|
||||
echo " port Gogs port"
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
"install")
|
||||
do_install
|
||||
;;
|
||||
"upgrade")
|
||||
do_install
|
||||
;;
|
||||
"rm")
|
||||
docker rm -f gogs
|
||||
;;
|
||||
"start" | "stop" | "restart")
|
||||
docker ${ACTION} gogs
|
||||
;;
|
||||
"status")
|
||||
docker ps --all -f 'name=gogs' --format '{{.State}}'
|
||||
;;
|
||||
"port")
|
||||
uci -q get gogs.@main[0].http_port 2>/dev/null
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.1.2-20240105
|
||||
PKG_RELEASE:=
|
||||
|
||||
LUCI_TITLE:=LuCI support for heimdall
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+docker +luci-lib-taskd
|
||||
|
||||
define Package/luci-app-heimdall/conffiles
|
||||
/etc/config/heimdall
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
module("luci.controller.heimdall", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "heimdall"}, alias("admin", "services", "heimdall", "config"), _("Heimdall"), 30).dependent = true
|
||||
entry({"admin", "services", "heimdall", "config"}, cbi("heimdall"))
|
||||
end
|
||||
@@ -1,35 +0,0 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface
|
||||
]]--
|
||||
|
||||
local taskd = require "luci.model.tasks"
|
||||
local m, s, o
|
||||
|
||||
m = taskd.docker_map("heimdall", "heimdall", "/usr/libexec/istorec/heimdall.sh",
|
||||
translate("Heimdall"),
|
||||
translate("Heimdall is an elegant solution to organise all your web applications.")
|
||||
.. translate("Official website:") .. ' <a href=\"https://github.com/linuxserver/Heimdall\" target=\"_blank\">https://github.com/linuxserver/Heimdall</a>')
|
||||
|
||||
s = m:section(SimpleSection, translate("Service Status"), translate("Heimdall status:"))
|
||||
s:append(Template("heimdall/status"))
|
||||
|
||||
s = m:section(TypedSection, "heimdall", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Value, "http_port", translate("HTTP Port").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "8088"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "https_port", translate("HTTPS Port").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "8089"
|
||||
o.datatype = "port"
|
||||
|
||||
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
|
||||
o.rmempty = false
|
||||
o.default = "/root/heimdall/config"
|
||||
o.datatype = "string"
|
||||
|
||||
return m
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user