Skip to content

Commit

Permalink
add luci-app-clouddrive2
Browse files Browse the repository at this point in the history
  • Loading branch information
jjm2473 committed Jan 17, 2024
1 parent cb24310 commit 96350eb
Show file tree
Hide file tree
Showing 9 changed files with 339 additions and 0 deletions.
19 changes: 19 additions & 0 deletions applications/luci-app-clouddrive2/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@


include $(TOPDIR)/rules.mk

PKG_VERSION:=1.0.0-1
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

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

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
56 changes: 56 additions & 0 deletions applications/luci-app-clouddrive2/luasrc/model/cbi/clouddrive2.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
--[[
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.default = default_path

return m
55 changes: 55 additions & 0 deletions applications/luci-app-clouddrive2/luasrc/model/clouddrive2.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<%
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 %>
53 changes: 53 additions & 0 deletions applications/luci-app-clouddrive2/po/zh-cn/clouddrive2.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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 "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"
5 changes: 5 additions & 0 deletions applications/luci-app-clouddrive2/root/etc/config/clouddrive2
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
config clouddrive2
option 'port' '19798'
option 'image' 'default'
# option 'config_path' ''
# option 'cache_path' ''
13 changes: 13 additions & 0 deletions applications/luci-app-clouddrive2/root/etc/init.d/clouddrive2
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/bin/sh
# Author [email protected]

ACTION=${1}
shift 1

IMAGE_NAME='default'

get_image() {
IMAGE_NAME=`uci 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 get clouddrive2.@clouddrive2[0].config_path 2>/dev/null`
local cache=`uci get clouddrive2.@clouddrive2[0].cache_path 2>/dev/null`
local port=`uci get clouddrive2.@clouddrive2[0].port 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 get system.@system[0].zonename | sed 's/ /_/g'`"
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"

# make sure shared mount point
/etc/init.d/clouddrive2 boot

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

0 comments on commit 96350eb

Please sign in to comment.