初始化仓库

This commit is contained in:
ling
2024-03-20 20:40:38 +08:00
parent f8d740cfdd
commit 0dfd6ccf4b
544 changed files with 53 additions and 69711 deletions

View File

@@ -1,6 +1,43 @@
# Openwrt-actions
# 中文 | [English](https://github.com/Siriling/istoreos-actions/blob/main/EngLish.md)
# 移动通信模组自动构建
[![Modem使用文档](https://img.shields.io/badge/使用文档-Modem-brightgreen?style=flat-square)](https://blog.siriling.com:1212/2023/03/18/openwrt-5g-modem) [![最新软件包下载](https://img.shields.io/github/v/release/Siriling/istoreos-actions?style=flat-square&label=最新软件包下载)](../../releases/latest)
![支持架构](https://img.shields.io/badge/支持架构:-blueviolet.svg?style=flat-square) ![X86](https://img.shields.io/badge/X86-blue.svg?style=flat-square) ![ARM](https://img.shields.io/badge/ARM-blue.svg?style=flat-square)
# 目录
[一、简介](#一简介)
[二、源代码地址 ](#二源代码地址)
[三、资源](#三资源)
[四、使用说明](#四使用说明)
# 一、简介
Modem插件自动构建
# 二、源代码地址
- luci-app-modemhttps://github.com/Siriling/5G-Modem-Support/tree/main/luci-app-modem
- sms-toolhttps://github.com/obsy/sms_tool
- quectel_cm_5Ghttps://github.com/Siriling/5G-Modem-Support/tree/main/quectel_cm_5G
- quectel_MHIhttps://github.com/Siriling/5G-Modem-Support/tree/main/quectel_MHI
# 三、资源
# 四、使用说明
## 在线构建
使用步骤
## 使用步骤
1. 选择actions标签选择Build IPKs![image](https://user-images.githubusercontent.com/1214708/153843131-615197e2-4ff4-4c0b-b30a-372e1c513158.png)
2. 点击run workflow输入要编译的插件名称空格隔开或者填“all”用来编译所有插件然后开始编译![image](https://user-images.githubusercontent.com/1214708/153843217-0591a7e6-4758-461e-8b2b-9bb830b87fb2.png)
@@ -8,8 +45,18 @@
3. 等待编译完成,点击任务进入详情页
4. 在详情页下载插件压缩包![image](https://user-images.githubusercontent.com/1214708/153843272-81843b45-6dc8-4945-871f-a9a467f63c33.png)
## 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
```

View File

@@ -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))

View File

@@ -1,5 +0,0 @@
config main
option 'enabled' '0'
option 'interface' 'lan'
option 'aircast' '1'
option 'airupnp' '1'

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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 &amp; 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

View File

@@ -1,23 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Use AirPlay to stream to UPnP/Sonos &amp; 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 设备就选中这个"

View File

@@ -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

View File

@@ -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();
}
});

View File

@@ -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位"

View File

@@ -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'

View File

@@ -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
}

View File

@@ -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 }
}
}
}

View File

@@ -1,11 +0,0 @@
{
"luci-app-ap-modem": {
"description": "Grant access to 'Access AP / Modem'",
"read": {
"uci": [ "ap_modem" ]
},
"write": {
"uci": [ "ap_modem" ]
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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 "唯一标识"

View File

@@ -1,4 +0,0 @@
config bmtedge
# option cache_path ''
# option image_name ''
# option uid ''

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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">&nbsp;</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 %>

View File

@@ -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 "可不填,所有硬盘都在"

View File

@@ -1,6 +0,0 @@
config main
option 'http_port' '19035'
option 'web_port' '19037'
option 'image_name' ''
option 'config_path' ''

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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">&nbsp;</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 %>

View File

@@ -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"

View File

@@ -1,6 +0,0 @@
config clouddrive2
option 'port' '19798'
option 'image' 'default'
# option 'config_path' ''
# option 'cache_path' ''
option 'share_mnt' '0'

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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">&nbsp;</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 %>

View File

@@ -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>

View File

@@ -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 "执行"

View File

@@ -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' ''

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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">&nbsp;</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 %>

View File

@@ -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 "请确保有足够空间"

View File

@@ -1,4 +0,0 @@
config main
option 'port' '8091'
option 'config_path' ''

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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">&nbsp;</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 %>

View File

@@ -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 冲突"

View File

@@ -1,6 +0,0 @@
config main
option 'hostnet' '0'
option 'http_port' '8097'
option 'image_name' 'emby/embyserver'
option 'config_path' ''

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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">&nbsp;</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 %>

View File

@@ -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 "请确保有足够空间"

View File

@@ -1,5 +0,0 @@
config main
option 'port' '8090'
option 'config_path' ''
option 'image_ver' ''

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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">&nbsp;</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 %>

View File

@@ -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 "请确保有足够空间"

View File

@@ -1,3 +0,0 @@
config main
option 'config_path' ''

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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">&nbsp;</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 %>

View File

@@ -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"

View File

@@ -1,6 +0,0 @@
config main
option 'http_port' '3001'
option 'ssh_port' '3022'
option 'image_name' 'gogs/gogs:latest'
option 'config_path' ''

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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