更新编译工作流 (#14)
* update sdk; use external git source; remove some feeds; support build all apps; multi-threads building; * update README
This commit is contained in:
parent
c475e517bb
commit
131b5f1c12
100
.github/workflows/main.yml
vendored
100
.github/workflows/main.yml
vendored
@ -1,17 +1,17 @@
|
||||
name: Build Meta
|
||||
name: Build IPKs
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
applications:
|
||||
description: 'build applications'
|
||||
description: 'build applications, eg: "luci-app-store luci-app-ddnsto". "all" means build all'
|
||||
required: true
|
||||
default: 'luci-app-jellyfin luci-app-kodexplorer'
|
||||
default: 'all'
|
||||
|
||||
env:
|
||||
SDK_NAME: openwrt-sdk-21.02.0-mvebu-cortexa53_gcc-8.4.0_musl.Linux-x86_64
|
||||
SDK_URL: https://downloads.openwrt.org/releases/21.02.0/targets/mvebu/cortexa53/
|
||||
SDK_NAME: openwrt-sdk-21.02.2-mvebu-cortexa53_gcc-8.4.0_musl.Linux-x86_64
|
||||
SDK_URL: https://downloads.openwrt.org/releases/21.02.2/targets/mvebu/cortexa53/
|
||||
TZ: Asia/Shanghai
|
||||
|
||||
jobs:
|
||||
@ -19,6 +19,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build IPKs
|
||||
steps:
|
||||
- name: Job Info
|
||||
run: |
|
||||
apps="${{ github.event.inputs.applications }}"
|
||||
echo "::notice title=Apps::$apps"
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@main
|
||||
with:
|
||||
@ -45,7 +50,11 @@ jobs:
|
||||
run: tar -xJf ${SDK_NAME}.tar.xz
|
||||
|
||||
- name: Clean Code
|
||||
run: rm -f ${SDK_NAME}/package/linux/modules/*
|
||||
run: |
|
||||
rm -f ${SDK_NAME}/package/linux/modules/*
|
||||
rm -f ${SDK_NAME}/package/kernel/linux/modules/*
|
||||
grep 'src-git base ' ${SDK_NAME}/feeds.conf.default > ${SDK_NAME}/feeds.conf
|
||||
grep 'src-git luci ' ${SDK_NAME}/feeds.conf.default >> ${SDK_NAME}/feeds.conf
|
||||
|
||||
- name: Write Config
|
||||
run: |
|
||||
@ -55,25 +64,69 @@ jobs:
|
||||
|
||||
- name: Load custom feeds
|
||||
run: |
|
||||
arr=("${{ github.event.inputs.applications }}")
|
||||
cd apps
|
||||
mkdir build
|
||||
for var in ${arr[@]}
|
||||
do
|
||||
echo $var
|
||||
cp -r applications/$var build/$var
|
||||
done
|
||||
cd ..
|
||||
echo "src-link apps `pwd`/apps/build" >> ${SDK_NAME}/feeds.conf.default
|
||||
echo "" >> ${SDK_NAME}/feeds.conf
|
||||
arr="${{ github.event.inputs.applications }}"
|
||||
if [ "$arr" = "all" ]; then
|
||||
echo "src-link apps `pwd`/apps/applications" >> ${SDK_NAME}/feeds.conf
|
||||
else
|
||||
cd apps
|
||||
mkdir build
|
||||
for var in ${arr}
|
||||
do
|
||||
echo add app $var
|
||||
cp -a applications/$var build/$var || true
|
||||
done
|
||||
ls -l build/
|
||||
cd ..
|
||||
echo "src-link apps `pwd`/apps/build" >> ${SDK_NAME}/feeds.conf
|
||||
fi
|
||||
cat apps/feeds.conf >> ${SDK_NAME}/feeds.conf
|
||||
echo "" >> ${SDK_NAME}/feeds.conf
|
||||
echo "Final feeds.conf:"
|
||||
cat ${SDK_NAME}/feeds.conf
|
||||
|
||||
- name: Update feeds
|
||||
run: |
|
||||
apps="${{ github.event.inputs.applications }}"
|
||||
cd ${SDK_NAME}
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a -p apps -d y
|
||||
if [ "$apps" = "all" ]; then
|
||||
./scripts/feeds install -a -p apps -d y
|
||||
for repo in `sed -e 's/src-[^ ]* \([^ ]*\) .*/\1/g' ../apps/feeds.conf`
|
||||
do
|
||||
echo add all in repo $repo
|
||||
./scripts/feeds install -a -p $repo -d y
|
||||
done
|
||||
else
|
||||
./scripts/feeds install ${apps} -d y
|
||||
fi
|
||||
|
||||
- name: Compile IPKs
|
||||
- name: Defconfig
|
||||
id: defconfig
|
||||
run: |
|
||||
cd ${SDK_NAME}
|
||||
make defconfig
|
||||
echo "::set-output name=status::success"
|
||||
|
||||
- name: Download sources
|
||||
id: download
|
||||
if: steps.defconfig.outputs.status == 'success'
|
||||
run: |
|
||||
cd ${SDK_NAME}
|
||||
make -j4 download
|
||||
echo "::set-output name=status::success"
|
||||
|
||||
- name: PreCompile IPKs
|
||||
id: precompile
|
||||
if: steps.download.outputs.status == 'success'
|
||||
run: |
|
||||
cd ${SDK_NAME}
|
||||
make -j4 package/compile
|
||||
echo "::set-output name=status::success"
|
||||
|
||||
- name: ReCompile IPKs
|
||||
id: compile
|
||||
if: steps.download.outputs.status == 'success' && steps.precompile.outputs.status != 'success'
|
||||
run: |
|
||||
cd ${SDK_NAME}
|
||||
bash -c 'set -o pipefail ; make -j1 V=s defconfig package/compile 2>&1 | tee /tmp/openwrt-sdk-build.log'
|
||||
@ -83,9 +136,16 @@ jobs:
|
||||
if: failure()
|
||||
run: tail -n 200 /tmp/openwrt-sdk-build.log
|
||||
|
||||
- name: PreUpload - Clean
|
||||
id: preupload
|
||||
if: steps.precompile.outputs.status == 'success' || steps.compile.outputs.status == 'success'
|
||||
run: |
|
||||
cd ${SDK_NAME}/bin/packages/aarch64_cortex-a53
|
||||
rm -rf base luci
|
||||
|
||||
- name: Upload bin directory
|
||||
uses: actions/upload-artifact@main
|
||||
if: steps.compile.outputs.status == 'success'
|
||||
if: steps.precompile.outputs.status == 'success' || steps.compile.outputs.status == 'success'
|
||||
with:
|
||||
name: apps
|
||||
path: ${{ env.SDK_NAME }}/bin/packages/aarch64_cortex-a53/apps
|
||||
path: ${{ env.SDK_NAME }}/bin/packages/aarch64_cortex-a53
|
||||
|
@ -1,9 +1,9 @@
|
||||
# Openwrt-actions
|
||||
|
||||
## 使用步骤
|
||||
1. 选择actions标签,选择build meta
|
||||
1. 选择actions标签,选择Build IPKs
|
||||
|
||||
2. 点击run workflow,输入要编译的插件名称,然后开始编译
|
||||
2. 点击run workflow,输入要编译的插件名称,空格隔开,或者填“all”用来编译所有插件,然后开始编译
|
||||
|
||||
3. 等待编译完成,点击任务进入详情页
|
||||
4. 在详情页下载插件压缩包
|
||||
|
@ -1,66 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2015-2016 OpenWrt.org
|
||||
# Copyright (C) 2020 jjm2473@gmail.com
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_ARCH_LINKEASE:=$(ARCH)
|
||||
|
||||
PKG_NAME:=linkease
|
||||
PKG_VERSION:=0.5.2
|
||||
PKG_RELEASE:=2
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://fw.koolcenter.com/binary/LinkEase/LinuxStorage/
|
||||
PKG_HASH:=82ebf3cc631885c92d82ace74830a54ad1a69b2224ff85dc298e6d9a591a4d56
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=LinkEase - the file cloud
|
||||
DEPENDS:=
|
||||
URL:=https://www.ddnsto.com/linkease/
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
LinkEase is a file cloud
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/linkease
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
[ -f /etc/uci-defaults/linkease ] && /etc/uci-defaults/linkease && rm -f /etc/uci-defaults/linkease
|
||||
fi
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin/linkease-plugins $(1)/etc/config $(1)/etc/init.d $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/linkease.$(PKG_ARCH_LINKEASE) $(1)/usr/sbin/linkease
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/heif-converter.$(PKG_ARCH_LINKEASE) $(1)/usr/sbin/heif-converter
|
||||
$(INSTALL_BIN) ./files/aria2.sh $(1)/usr/sbin/linkease-plugins/aria2.sh
|
||||
$(INSTALL_CONF) ./files/linkease.config $(1)/etc/config/linkease
|
||||
$(INSTALL_BIN) ./files/linkease.init $(1)/etc/init.d/linkease
|
||||
$(INSTALL_BIN) ./files/linkease.uci-default $(1)/etc/uci-defaults/linkease
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
@ -1,134 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
sh_ver="1.0.0"
|
||||
export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin
|
||||
aria2_conf_dir=/var/etc/aria2/
|
||||
#替换成你设备aria2.conf路径
|
||||
aria2_conf=${aria2_conf_dir}/aria2.conf.main
|
||||
#替换成你设备的aria2c路径
|
||||
aria2c=/usr/bin/aria2c
|
||||
Green_font_prefix="\033[32m"
|
||||
Red_font_prefix="\033[31m"
|
||||
Green_background_prefix="\033[42;37m"
|
||||
Red_background_prefix="\033[41;37m"
|
||||
Font_color_suffix="\033[0m"
|
||||
Info="[${Green_font_prefix}信息${Font_color_suffix}]"
|
||||
Error="[${Red_font_prefix}错误${Font_color_suffix}]"
|
||||
Tip="[${Green_font_prefix}注意${Font_color_suffix}]"
|
||||
error_code=11
|
||||
success_code=0
|
||||
|
||||
return_error(){
|
||||
echo 'Content-Type:application/json;charset=utf-8'
|
||||
echo
|
||||
echo "{
|
||||
"\"success\"":$error_code,
|
||||
"\"error\"":"\"$1\"",
|
||||
"\"result"\":null
|
||||
}"
|
||||
exit 1
|
||||
}
|
||||
return_ok(){
|
||||
echo 'Content-Type:application/json;charset=utf-8'
|
||||
echo
|
||||
echo "{
|
||||
"\"success\"":$success_code,
|
||||
"\"error\"":"\"$1\"",
|
||||
"\"result"\":null
|
||||
}"
|
||||
exit 0
|
||||
}
|
||||
return_result(){
|
||||
echo 'Content-Type:application/json;charset=utf-8'
|
||||
echo
|
||||
echo "{
|
||||
"\"success\"":$success_code,
|
||||
"\"error\"":"\"\"",
|
||||
"\"result"\":$1
|
||||
}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
#进程中是否运行aria2
|
||||
check_pid() {
|
||||
PID=$(ps -ef | grep "aria2c" | grep -v grep | grep -v "aria2.sh" | grep -v "init.d" | grep -v "service" | awk '{print $2}')
|
||||
}
|
||||
|
||||
#aria2是否正在运行
|
||||
aria2_work_status(){
|
||||
check_pid
|
||||
# [[ ! -z ${PID} ]] && echo -e "${Error} Aria2 正在运行,请检查 !" && exit 1
|
||||
[[ ! -z ${PID} ]] && return_ok "Aria2正在运行"
|
||||
return_error "Aria2未运行"
|
||||
}
|
||||
|
||||
#检测设备是否安装aria2
|
||||
check_installed_status() {
|
||||
[[ ! -e ${aria2c} ]] && return_error "Aria2 没有安装,请检查 !"
|
||||
[[ ! -e ${aria2_conf} ]] && return_error "Aria2 配置文件不存在,请检查 !"
|
||||
# return_ok "Aria2已安装"
|
||||
}
|
||||
#读取aria2配置信息
|
||||
read_config() {
|
||||
check_installed_status
|
||||
if [[ ! -e ${aria2_conf} ]]; then
|
||||
return_error "Aria2 配置文件不存在,请检查 !"
|
||||
else
|
||||
conf_text=$(cat ${aria2_conf} | grep -v '#')
|
||||
aria2_dir=$(echo -e "${conf_text}" | grep "^dir=" | awk -F "=" '{print $NF}')
|
||||
aria2_port=$(echo -e "${conf_text}" | grep "^rpc-listen-port=" | awk -F "=" '{print $NF}')
|
||||
aria2_passwd=$(echo -e "${conf_text}" | grep "^rpc-secret=" | awk -F "=" '{print $NF}')
|
||||
aria2_bt_port=$(echo -e "${conf_text}" | grep "^listen-port=" | awk -F "=" '{print $NF}')
|
||||
aria2_dht_port=$(echo -e "${conf_text}" | grep "^dht-listen-port=" | awk -F "=" '{print $NF}')
|
||||
|
||||
return_result "{
|
||||
"\"dir"\":"\"$aria2_dir"\",
|
||||
"\"rpc-listen-port"\":"\"$aria2_port"\",
|
||||
"\"rpc-secret"\":"\"$aria2_passwd"\",
|
||||
"\"listen-port"\":"\"$aria2_bt_port"\",
|
||||
"\"dht-listen-port"\":"\"$aria2_dht_port"\"}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#"Content-Type:text/html;charset=utf-8"
|
||||
#echo
|
||||
|
||||
#SERVER_SOFTWARE = $SERVER_SOFTWARE #服务器软件
|
||||
#SERVER_NAME = $SERVER_NAME #服务器主机名
|
||||
#GATEWAY_INTERFACE = $GATEWAY_INTERFACE #CGI版本
|
||||
#SERVER_PROTOCOL = $SERVER_PROTOCOL #通信使用的协议
|
||||
#SERVER_PORT = $SERVER_PORT #服务器的端口号
|
||||
#REQUEST_METHOD = $REQUEST_METHOD #请求方法(GET/POST/PUT/DELETE..)
|
||||
#HTTP_ACCEPT = $HTTP_ACCEPT #HTTP定义的浏览器能够接受的数据类型
|
||||
#SCRIPT_NAME = $SCRIPT_NAME #当前运行的脚本名称(包含路径)
|
||||
#QUERY_STRING = $QUERY_STRING #地址栏中传的数据(get方式)
|
||||
#REMOTE_ADDR = $REMOTE_ADDR #客户端的ip
|
||||
|
||||
#根据url QUERY调不同方法
|
||||
query(){
|
||||
aria2Query=${QUERY_STRING}
|
||||
parse(){
|
||||
echo $1 | sed 's/.*'$2'=\([[:alnum:]]*\).*/\1/'
|
||||
}
|
||||
value=$(parse $aria2Query "action")
|
||||
|
||||
if [ ! -z = "$value" ]
|
||||
then
|
||||
if [ "$value" = "status" ]
|
||||
then
|
||||
check_installed_status
|
||||
elif [ "$value" = "readConfig" ]
|
||||
then
|
||||
read_config
|
||||
elif [ "$value" = "workStatus" ]
|
||||
then
|
||||
aria2_work_status
|
||||
else
|
||||
echo
|
||||
fi
|
||||
else
|
||||
return_error "action不能为空"
|
||||
fi
|
||||
}
|
||||
query
|
@ -1,3 +0,0 @@
|
||||
config linkease
|
||||
option 'port' '8897'
|
||||
option 'enabled' '1'
|
@ -1,23 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
get_config() {
|
||||
config_get_bool enabled $1 enabled 1
|
||||
config_get_bool logger $1 logger
|
||||
config_get port $1 port 8897
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load linkease
|
||||
config_foreach get_config linkease
|
||||
[ $enabled != 1 ] && return 1
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/sbin/linkease
|
||||
[ -n "$port" ] && procd_append_param command --deviceAddr ":$port"
|
||||
[ "$logger" == 1 ] && procd_set_param stderr 1
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@linkease[-1]
|
||||
add ucitrack linkease
|
||||
set ucitrack.@linkease[-1].init=linkease
|
||||
commit ucitrack
|
||||
|
||||
delete firewall.linkease
|
||||
set firewall.linkease=rule
|
||||
set firewall.linkease.name="linkease"
|
||||
set firewall.linkease.target="ACCEPT"
|
||||
set firewall.linkease.src="wan"
|
||||
set firewall.linkease.proto="tcp"
|
||||
set firewall.linkease.dest_port="8897"
|
||||
commit firewall
|
||||
EOF
|
||||
|
||||
/etc/init.d/linkease enable
|
||||
/etc/init.d/linkease start
|
||||
|
||||
exit 0
|
@ -1,17 +0,0 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for linkease
|
||||
LUCI_DEPENDS:=+linkease
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=2.1.1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
@ -1,25 +0,0 @@
|
||||
module("luci.controller.linkease", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/linkease") then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "services", "linkease"}, cbi("linkease"), _("LinkEase"), 20).dependent = true
|
||||
|
||||
entry({"admin", "services", "linkease_status"}, call("linkease_status"))
|
||||
end
|
||||
|
||||
function linkease_status()
|
||||
local sys = require "luci.sys"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local port = tonumber(uci:get_first("linkease", "linkease", "port"))
|
||||
|
||||
local status = {
|
||||
running = (sys.call("pidof linkease >/dev/null") == 0),
|
||||
port = (port or 8897)
|
||||
}
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(status)
|
||||
end
|
@ -1,20 +0,0 @@
|
||||
--wulishui <wulishui@gmail.com> ,20200911
|
||||
--jjm2473 <jjm2473@gmail.com> ,20210127
|
||||
|
||||
local m, s
|
||||
|
||||
m = Map("linkease", translate("LinkEase"), translate("LinkEase is an efficient data transfer tool."))
|
||||
|
||||
m:section(SimpleSection).template = "linkease_status"
|
||||
|
||||
s=m:section(TypedSection, "linkease", translate("Global settings"))
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
s:option(Flag, "enabled", translate("Enable")).rmempty=false
|
||||
|
||||
s:option(Value, "port", translate("Port")).rmempty=false
|
||||
|
||||
return m
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
<%+linkease_status%>
|
@ -1,27 +0,0 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(5, '<%=url("admin/services/linkease_status")%>', null,
|
||||
function(x, st)
|
||||
{
|
||||
var tb = document.getElementById('linkease_status');
|
||||
if (st && tb)
|
||||
{
|
||||
if (st.running)
|
||||
{
|
||||
tb.innerHTML = '<br/><em style=\"color:green\"><%:The LinkEase service is running.%></em>'
|
||||
+ "<br/><br/><input class=\"btn cbi-button cbi-button-apply\" type=\"button\" value=\" <%:Click to open LinkEase%> \" onclick=\"window.open('http://" + window.location.hostname + ":" + st.port + "/')\"/>";
|
||||
}
|
||||
else
|
||||
{
|
||||
tb.innerHTML = '<br/><em style=\"color:red\"><%:The LinkEase service is not running.%></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<fieldset class="cbi-section">
|
||||
<legend><%:LinkEase Status%></legend>
|
||||
<p id="linkease_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
@ -1,27 +0,0 @@
|
||||
msgid "LinkEase"
|
||||
msgstr "易有云文件管理器"
|
||||
|
||||
msgid "Running state"
|
||||
msgstr "运行状态"
|
||||
|
||||
msgid "Click to open LinkEase"
|
||||
msgstr "点击打开易有云"
|
||||
|
||||
msgid "LinkEase is an efficient data transfer tool."
|
||||
msgstr "易有云是一个微型家庭数据服务中心,主要用于文件的集中存放、读取、备份及日常管理。释放用户终端设备空间,实现个人、家庭文件长久留存;支持家庭相册、视频文件随时随地多终端查看、播放,满足家庭文件的日常管理。"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "The LinkEase service is running."
|
||||
msgstr "易有云服务已启动"
|
||||
|
||||
msgid "The LinkEase service is not running."
|
||||
msgstr "易有云服务未启动"
|
||||
|
||||
msgid "LinkEase Status"
|
||||
msgstr "易有云服务状态"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "收集数据..."
|
||||
|
@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -1,17 +0,0 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for quickstart
|
||||
LUCI_DEPENDS:=+shadow-useradd
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=0.0.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
@ -1,172 +0,0 @@
|
||||
local http = require "luci.http"
|
||||
local nixio = require "nixio"
|
||||
local ltn12 = require "luci.ltn12"
|
||||
local table = require "table"
|
||||
local util = require "luci.util"
|
||||
|
||||
module("luci.controller.istore_backend", package.seeall)
|
||||
|
||||
local BLOCKSIZE = 2048
|
||||
local ISTOREOS_PORT = 3000
|
||||
|
||||
function index()
|
||||
entry({"istore"}, call("istore_backend")).leaf=true
|
||||
end
|
||||
|
||||
function sink_socket(sock, io_err)
|
||||
if sock then
|
||||
return function(chunk, err)
|
||||
if not chunk then
|
||||
return 1
|
||||
else
|
||||
return sock:send(chunk)
|
||||
end
|
||||
end
|
||||
else
|
||||
return ltn12.sink.error(io_err or "unable to send socket")
|
||||
end
|
||||
end
|
||||
|
||||
local function session_retrieve(sid, allowed_users)
|
||||
local sdat = util.ubus("session", "get", { ubus_rpc_session = sid })
|
||||
if type(sdat) == "table" and
|
||||
type(sdat.values) == "table" and
|
||||
type(sdat.values.token) == "string" and
|
||||
(not allowed_users or
|
||||
util.contains(allowed_users, sdat.values.username))
|
||||
then
|
||||
return sid, sdat.values
|
||||
end
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
function istore_backend()
|
||||
local sock = nixio.connect("127.0.0.1", ISTOREOS_PORT)
|
||||
if not sock then
|
||||
http.status(500, "connect failed")
|
||||
return
|
||||
end
|
||||
local input = {}
|
||||
input[#input+1] = http.getenv("REQUEST_METHOD") .. " " .. http.getenv("REQUEST_URI") .. " HTTP/1.1"
|
||||
local req = http.context.request
|
||||
local start = "HTTP_"
|
||||
local start_len = string.len(start)
|
||||
local ctype = http.getenv("CONTENT_TYPE")
|
||||
if ctype then
|
||||
input[#input+1] = "Content-Type: " .. ctype
|
||||
end
|
||||
for k, v in pairs(req.message.env) do
|
||||
if string.sub(k, 1, start_len) == start and not string.find(k, "FORWARDED") then
|
||||
input[#input+1] = string.sub(k, start_len+1, string.len(k)) .. ": " .. v
|
||||
end
|
||||
end
|
||||
local sid = http.getcookie("sysauth")
|
||||
if sid then
|
||||
local sid, sdat = session_retrieve(sid, nil)
|
||||
if sdat ~= nil then
|
||||
input[#input+1] = "X-Forwarded-Sid: " .. sid
|
||||
input[#input+1] = "X-Forwarded-Token: " .. sdat.token
|
||||
end
|
||||
end
|
||||
input[#input+1] = "X-Forwarded-For: " .. http.getenv("REMOTE_HOST") ..":".. http.getenv("REMOTE_PORT")
|
||||
local num = tonumber(http.getenv("CONTENT_LENGTH")) or 0
|
||||
input[#input+1] = "Content-Length: " .. tostring(num)
|
||||
input[#input+1] = "\r\n"
|
||||
local source = ltn12.source.cat(ltn12.source.string(table.concat(input, "\r\n")), http.source())
|
||||
local ret = ltn12.pump.all(source, sink_socket(sock, "write sock error"))
|
||||
if ret ~= 1 then
|
||||
sock:close()
|
||||
http.status(500, "proxy error")
|
||||
return
|
||||
end
|
||||
|
||||
local linesrc = sock:linesource()
|
||||
local line, code, error = linesrc()
|
||||
if not line then
|
||||
sock:close()
|
||||
http.status(500, "response parse failed")
|
||||
return
|
||||
end
|
||||
|
||||
local protocol, status, msg = line:match("^([%w./]+) ([0-9]+) (.*)")
|
||||
if not protocol then
|
||||
sock:close()
|
||||
http.status(500, "response protocol error")
|
||||
return
|
||||
end
|
||||
num = tonumber(status) or 0
|
||||
http.status(num, msg)
|
||||
|
||||
local chunked = 0
|
||||
line = linesrc()
|
||||
while line and line ~= "" do
|
||||
local key, val = line:match("^([%w-]+)%s?:%s?(.*)")
|
||||
if key and key ~= "Status" then
|
||||
if key == "Transfer-Encoding" and val == "chunked" then
|
||||
chunked = 1
|
||||
end
|
||||
if key ~= "Connection" and key ~= "Transfer-Encoding" then
|
||||
http.header(key, val)
|
||||
end
|
||||
end
|
||||
line = linesrc()
|
||||
end
|
||||
if not line then
|
||||
sock:close()
|
||||
http.status(500, "parse header failed")
|
||||
return
|
||||
end
|
||||
|
||||
local body_buffer = linesrc(true)
|
||||
if chunked == 1 then
|
||||
ltn12.pump.all(chunksource(sock, body_buffer), http.write)
|
||||
else
|
||||
local body_source = ltn12.source.cat(ltn12.source.string(body_buffer), sock:blocksource())
|
||||
ltn12.pump.all(body_source, http.write)
|
||||
end
|
||||
|
||||
sock:close()
|
||||
end
|
||||
|
||||
function chunksource(sock, buffer)
|
||||
buffer = buffer or ""
|
||||
return function()
|
||||
local output
|
||||
local _, endp, count = buffer:find("^([0-9a-fA-F]+);?.-\r\n")
|
||||
while not count and #buffer <= 1024 do
|
||||
local newblock, code = sock:recv(1024 - #buffer)
|
||||
if not newblock then
|
||||
return nil, code
|
||||
end
|
||||
buffer = buffer .. newblock
|
||||
_, endp, count = buffer:find("^([0-9a-fA-F]+);?.-\r\n")
|
||||
end
|
||||
count = tonumber(count, 16)
|
||||
if not count then
|
||||
return nil, -1, "invalid encoding"
|
||||
elseif count == 0 then
|
||||
return nil
|
||||
elseif count + 2 <= #buffer - endp then
|
||||
output = buffer:sub(endp+1, endp+count)
|
||||
buffer = buffer:sub(endp+count+3)
|
||||
return output
|
||||
else
|
||||
output = buffer:sub(endp+1, endp+count)
|
||||
buffer = ""
|
||||
if count - #output > 0 then
|
||||
local remain, code = sock:recvall(count-#output)
|
||||
if not remain then
|
||||
return nil, code
|
||||
end
|
||||
output = output .. remain
|
||||
count, code = sock:recvall(2)
|
||||
else
|
||||
count, code = sock:recvall(count+2-#buffer+endp)
|
||||
end
|
||||
if not count then
|
||||
return nil, code
|
||||
end
|
||||
return output
|
||||
end
|
||||
end
|
||||
end
|
@ -1,23 +0,0 @@
|
||||
local http = require "luci.http"
|
||||
|
||||
module("luci.controller.quickstart", package.seeall)
|
||||
|
||||
local page_index = {"admin", "quickstart", "pages"}
|
||||
|
||||
function index()
|
||||
entry({"admin", "quickstart"}, call("redirect_index"), _("QuickStart"), 1)
|
||||
entry({"admin", "network_guide"}, call("networkguide_index"), _("NetworkGuide"), 2)
|
||||
entry({"admin", "quickstart", "pages"}, call("quickstart_index")).leaf = true
|
||||
end
|
||||
|
||||
function networkguide_index()
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","quickstart","pages","network"))
|
||||
end
|
||||
|
||||
function redirect_index()
|
||||
luci.http.redirect(luci.dispatcher.build_url(unpack(page_index)))
|
||||
end
|
||||
|
||||
function quickstart_index()
|
||||
luci.template.render("quickstart/main", {prefix=luci.dispatcher.build_url(unpack(page_index))})
|
||||
end
|
@ -1,13 +0,0 @@
|
||||
<%+header%>
|
||||
<script>
|
||||
(function(){
|
||||
var vue_prefix="<%=prefix%>";
|
||||
window.vue_base = vue_prefix + '/';
|
||||
})();
|
||||
</script>
|
||||
<div id="app">
|
||||
</div>
|
||||
<script type="module" crossorigin src="/luci-static/quickstart/index.js"></script>
|
||||
<link rel="modulepreload" href="/luci-static/quickstart/vendor.js">
|
||||
<link rel="stylesheet" href="/luci-static/quickstart/style.css">
|
||||
<%+footer%>
|
@ -1,7 +0,0 @@
|
||||
msgid "NetworkGuide"
|
||||
msgstr "网络向导"
|
||||
|
||||
msgid "QuickStart"
|
||||
msgstr "首页"
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,141 +0,0 @@
|
||||
### 路由器端API:
|
||||
0. 获取csrfToken(用于POST请求)
|
||||
```
|
||||
GET /cgi-bin/luci/admin/store/token
|
||||
|
||||
|
||||
{"token":"xxx"}
|
||||
```
|
||||
1. 已安装软件列表
|
||||
```
|
||||
GET /cgi-bin/luci/admin/store/installed
|
||||
|
||||
|
||||
[
|
||||
{
|
||||
"description": "DDNS.TO内网穿透",
|
||||
"tags": [
|
||||
"net",
|
||||
"tool"
|
||||
],
|
||||
"entry": "/cgi-bin/luci/admin/services/ddnsto",
|
||||
"author": "xiaobao",
|
||||
"depends": [
|
||||
"ddnsto",
|
||||
"luci-app-ddnsto",
|
||||
"luci-i18n-ddnsto-zh-cn"
|
||||
],
|
||||
"title": "DDNS.TO",
|
||||
"time": 1629356347,
|
||||
"release": 1,
|
||||
"website": "https://www.ddnsto.com/",
|
||||
"name": "ddnsto",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
]
|
||||
```
|
||||
2. 安装软件
|
||||
```
|
||||
POST /cgi-bin/luci/admin/store/install
|
||||
token=xxx&package=upnp
|
||||
|
||||
|
||||
{"code":0, "stdout":"", "stderr":""}
|
||||
```
|
||||
3. 更新软件
|
||||
```
|
||||
POST /cgi-bin/luci/admin/store/upgrade
|
||||
token=xxx&package=upnp
|
||||
|
||||
|
||||
{"code":0, "stdout":"", "stderr":""}
|
||||
```
|
||||
4. 卸载软件
|
||||
```
|
||||
POST /cgi-bin/luci/admin/store/remove
|
||||
token=xxx&package=upnp
|
||||
|
||||
|
||||
{"code":0, "stdout":"", "stderr":""}
|
||||
```
|
||||
5. 刷新可用软件列表
|
||||
```
|
||||
POST /cgi-bin/luci/admin/store/update
|
||||
token=xxx
|
||||
|
||||
|
||||
{"code":0, "stdout":"", "stderr":""}
|
||||
```
|
||||
6. 查询特定软件状态
|
||||
```
|
||||
GET /cgi-bin/luci/admin/store/status?package=ddnsto
|
||||
|
||||
|
||||
{
|
||||
"description": "DDNS.TO内网穿透",
|
||||
"tags": [
|
||||
"net",
|
||||
"tool"
|
||||
],
|
||||
"entry": "/cgi-bin/luci/admin/services/ddnsto",
|
||||
"author": "xiaobao",
|
||||
"depends": [
|
||||
"ddnsto",
|
||||
"luci-app-ddnsto",
|
||||
"luci-i18n-ddnsto-zh-cn"
|
||||
],
|
||||
"installed": true,
|
||||
"title": "DDNS.TO",
|
||||
"time": "1629356347",
|
||||
"release": 1,
|
||||
"website": "https://www.ddnsto.com/",
|
||||
"name": "ddnsto",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
|
||||
|
||||
{"installed":false}
|
||||
```
|
||||
7. 任务状态(日志)
|
||||
```
|
||||
GET /cgi-bin/luci/admin/store/log
|
||||
|
||||
|
||||
{
|
||||
"stdout": "Installing app-meta-ddnsto (1.0.0) to root...\nDownloading http://192.168.9.168:9999/packages/aarch64_cortex-a53/meta/app-meta-ddnsto_1.0.0_all.ipk\nConfiguring app-meta-ddnsto.\n",
|
||||
"stderr": "",
|
||||
"code": 206
|
||||
}
|
||||
|
||||
{"stdout":"","stderr":"","code":0}
|
||||
```
|
||||
8. 上传安装
|
||||
```
|
||||
POST /cgi-bin/luci/admin/store/upload
|
||||
|
||||
|
||||
(文件上传表单,支持文件扩展名".ipk,.run")
|
||||
|
||||
|
||||
{"code":0, "stdout":"", "stderr":""}
|
||||
```
|
||||
|
||||
9. 检查iStore自身更新
|
||||
```
|
||||
GET /cgi-bin/luci/admin/store/check_self_upgrade
|
||||
|
||||
|
||||
{"code":500, "msg":"Internal Error"}
|
||||
{"code":200, "msg":"1.1.2"}
|
||||
{"code":304, "msg":""}
|
||||
```
|
||||
|
||||
1. 更新iStore自身
|
||||
> 检查iStore自身更新接口返回code为200时才调用这个接口
|
||||
```
|
||||
POST /cgi-bin/luci/admin/store/do_self_upgrade
|
||||
token=xxx
|
||||
|
||||
|
||||
{"code":0, "stdout":"", "stderr":""}
|
||||
```
|
@ -1,36 +0,0 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI based ipk store
|
||||
LUCI_DESCRIPTION:=luci-app-store is a ipk store developed by LinkEase team
|
||||
LUCI_DEPENDS:=+curl +opkg +luci-lib-ipkg +tar +coreutils +coreutils-stat +libuci-lua +mount-utils
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_VERSION:=0.1.8
|
||||
PKG_RELEASE:=3
|
||||
|
||||
ISTORE_UI_VERSION:=1.0
|
||||
ISTORE_UI_RELEASE:=10-beta
|
||||
PKG_HASH:=4c7e2e9d20fcb0fbc383a85d1d4dd99f796eb389263512879373dc826ef6b3d7
|
||||
|
||||
PKG_SOURCE_URL_FILE:=v$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE).tar.gz
|
||||
PKG_SOURCE:=istore-ui-$(PKG_SOURCE_URL_FILE)
|
||||
PKG_SOURCE_URL:=https://github.com/linkease/istore-ui/archive/refs/tags
|
||||
|
||||
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
|
||||
|
||||
TARGET_CONFIGURE_OPTS= FRONTEND_DIST="$(BUILD_DIR)/istore-ui-$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE)/app-store-ui/src/dist" APP_STORE_VERSION="$(PKG_VERSION)-$(PKG_RELEASE)"
|
||||
TARGET_CONFIGURE_OPTS+= SED="$(SED)"
|
||||
|
||||
define Package/luci-app-store/conffiles
|
||||
/etc/.app_store.id
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
@ -1,3 +0,0 @@
|
||||
# luci-app-store
|
||||
OpenWRT应用商店
|
||||
|
@ -1,626 +0,0 @@
|
||||
module("luci.controller.store", package.seeall)
|
||||
|
||||
local myopkg = "is-opkg"
|
||||
local page_index = {"admin", "store", "pages"}
|
||||
|
||||
function index()
|
||||
local function store_api(action, onlypost)
|
||||
local e = entry({"admin", "store", action}, onlypost and post("store_action", {action = action}) or call("store_action", {action = action}))
|
||||
e.dependent = false -- 父节点不是必须的
|
||||
e.leaf = true -- 没有子节点
|
||||
end
|
||||
|
||||
local action
|
||||
|
||||
entry({"admin", "store"}, call("redirect_index"), _("iStore"), 31)
|
||||
entry({"admin", "store", "pages"}, call("store_index")).leaf = true
|
||||
if nixio.fs.access("/usr/lib/lua/luci/view/store/main_dev.htm") then
|
||||
entry({"admin", "store", "dev"}, call("store_dev")).leaf = true
|
||||
end
|
||||
entry({"admin", "store", "token"}, call("store_token"))
|
||||
entry({"admin", "store", "log"}, call("store_log"))
|
||||
entry({"admin", "store", "uid"}, call("action_user_id"))
|
||||
entry({"admin", "store", "upload"}, post("store_upload"))
|
||||
entry({"admin", "store", "check_self_upgrade"}, call("check_self_upgrade"))
|
||||
entry({"admin", "store", "do_self_upgrade"}, post("do_self_upgrade"))
|
||||
|
||||
entry({"admin", "store", "get_support_backup_features"}, call("get_support_backup_features"))
|
||||
entry({"admin", "store", "light_backup"}, post("light_backup"))
|
||||
entry({"admin", "store", "get_light_backup_file"}, call("get_light_backup_file"))
|
||||
entry({"admin", "store", "local_backup"}, post("local_backup"))
|
||||
entry({"admin", "store", "light_restore"}, post("light_restore"))
|
||||
entry({"admin", "store", "local_restore"}, post("local_restore"))
|
||||
entry({"admin", "store", "get_backup_app_list_file_path"}, call("get_backup_app_list_file_path"))
|
||||
entry({"admin", "store", "get_backup_app_list"}, call("get_backup_app_list"))
|
||||
entry({"admin", "store", "get_available_backup_file_list"}, call("get_available_backup_file_list"))
|
||||
entry({"admin", "store", "set_local_backup_dir_path"}, post("set_local_backup_dir_path"))
|
||||
entry({"admin", "store", "get_local_backup_dir_path"}, call("get_local_backup_dir_path"))
|
||||
|
||||
for _, action in ipairs({"update", "install", "upgrade", "remove"}) do
|
||||
store_api(action, true)
|
||||
end
|
||||
for _, action in ipairs({"status", "installed"}) do
|
||||
store_api(action, false)
|
||||
end
|
||||
end
|
||||
|
||||
local function user_id()
|
||||
local jsonc = require "luci.jsonc"
|
||||
local json_parse = jsonc.parse
|
||||
local fs = require "nixio.fs"
|
||||
local data = fs.readfile("/etc/.app_store.id")
|
||||
|
||||
local id
|
||||
if data ~= nil then
|
||||
id = json_parse(data)
|
||||
end
|
||||
if id == nil then
|
||||
fs.unlink("/etc/.app_store.id")
|
||||
id = {arch="",uid=""}
|
||||
end
|
||||
|
||||
id.version = (fs.readfile("/etc/.app_store.version") or "?"):gsub("[\r\n]", "")
|
||||
|
||||
return id
|
||||
end
|
||||
|
||||
local function is_exec(cmd)
|
||||
local nixio = require "nixio"
|
||||
local os = require "os"
|
||||
local fs = require "nixio.fs"
|
||||
local rshift = nixio.bit.rshift
|
||||
|
||||
local oflags = nixio.open_flags("wronly", "creat")
|
||||
local lock, code, msg = nixio.open("/var/lock/istore.lock", oflags)
|
||||
if not lock then
|
||||
return 255, "", "Open lock failed: " .. msg
|
||||
end
|
||||
|
||||
-- Acquire lock
|
||||
local stat, code, msg = lock:lock("tlock")
|
||||
if not stat then
|
||||
lock:close()
|
||||
return 255, "", "Lock failed: " .. msg
|
||||
end
|
||||
|
||||
local r = os.execute(cmd .. " >/var/log/istore.stdout 2>/var/log/istore.stderr")
|
||||
local e = fs.readfile("/var/log/istore.stderr")
|
||||
local o = fs.readfile("/var/log/istore.stdout")
|
||||
|
||||
fs.unlink("/var/log/istore.stderr")
|
||||
fs.unlink("/var/log/istore.stdout")
|
||||
|
||||
lock:lock("ulock")
|
||||
lock:close()
|
||||
|
||||
e = e or ""
|
||||
if r == 256 and e == "" then
|
||||
e = "os.execute failed, is /var/log full or not existed?"
|
||||
end
|
||||
return rshift(r,8), o or "", e or ""
|
||||
end
|
||||
|
||||
function redirect_index()
|
||||
luci.http.redirect(luci.dispatcher.build_url(unpack(page_index)))
|
||||
end
|
||||
|
||||
function store_index()
|
||||
luci.template.render("store/main", {prefix=luci.dispatcher.build_url(unpack(page_index)),id=user_id()})
|
||||
end
|
||||
|
||||
function store_dev()
|
||||
luci.template.render("store/main_dev", {prefix=luci.dispatcher.build_url(unpack({"admin", "store", "dev"})),id=user_id()})
|
||||
end
|
||||
|
||||
function store_log()
|
||||
local fs = require "nixio.fs"
|
||||
local code = 0
|
||||
local e = fs.readfile("/var/log/istore.stderr")
|
||||
local o = fs.readfile("/var/log/istore.stdout")
|
||||
if o ~= nil then
|
||||
code = 206
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json({code=code,stdout=o or "",stderr=e or ""})
|
||||
end
|
||||
|
||||
function action_user_id()
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(user_id())
|
||||
end
|
||||
|
||||
function check_self_upgrade()
|
||||
local ret = {
|
||||
code = 500,
|
||||
msg = "Unknown"
|
||||
}
|
||||
local r,o,e = is_exec(myopkg .. " check_self_upgrade")
|
||||
if r ~= 0 then
|
||||
ret.msg = e
|
||||
else
|
||||
ret.code = o == "" and 304 or 200
|
||||
ret.msg = o:gsub("[\r\n]", "")
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(ret)
|
||||
end
|
||||
|
||||
function do_self_upgrade()
|
||||
local code, out, err, ret
|
||||
code,out,err = is_exec(myopkg .. " do_self_upgrade")
|
||||
ret = {
|
||||
code = code,
|
||||
stdout = out,
|
||||
stderr = err
|
||||
}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(ret)
|
||||
end
|
||||
|
||||
-- Internal action function
|
||||
local function _action(exe, cmd, ...)
|
||||
local os = require "os"
|
||||
local fs = require "nixio.fs"
|
||||
|
||||
local pkg = ""
|
||||
for k, v in pairs({...}) do
|
||||
pkg = pkg .. " '" .. v:gsub("'", "") .. "'"
|
||||
end
|
||||
|
||||
local c = "%s %s %s" %{ exe, cmd, pkg }
|
||||
|
||||
return is_exec(c)
|
||||
end
|
||||
|
||||
function store_action(param)
|
||||
local metadir = "/usr/lib/opkg/meta"
|
||||
local metapkgpre = "app-meta-"
|
||||
local code, out, err, ret, out0, err0
|
||||
local fs = require "nixio.fs"
|
||||
local ipkg = require "luci.model.ipkg"
|
||||
local jsonc = require "luci.jsonc"
|
||||
local json_parse = jsonc.parse
|
||||
local action = param.action or ""
|
||||
|
||||
if action == "status" then
|
||||
local pkg = luci.http.formvalue("package")
|
||||
local metapkg = metapkgpre .. pkg
|
||||
local meta = {}
|
||||
local metadata = fs.readfile(metadir .. "/" .. pkg .. ".json")
|
||||
|
||||
if metadata ~= nil then
|
||||
meta = json_parse(metadata)
|
||||
end
|
||||
meta.installed = false
|
||||
local status = ipkg.status(metapkg)
|
||||
if next(status) ~= nil then
|
||||
meta.installed=true
|
||||
meta.time=tonumber(status[metapkg]["Installed-Time"])
|
||||
end
|
||||
|
||||
ret = meta
|
||||
elseif action == "installed" then
|
||||
local itr = fs.dir(metadir)
|
||||
local data = {}
|
||||
if itr then
|
||||
local pkg
|
||||
for pkg in itr do
|
||||
if pkg:match("^.*%.json$") then
|
||||
local meta = json_parse(fs.readfile(metadir .. "/" .. pkg))
|
||||
local metapkg = metapkgpre .. meta.name
|
||||
local status = ipkg.status(metapkg)
|
||||
if next(status) ~= nil then
|
||||
meta.time = tonumber(status[metapkg]["Installed-Time"])
|
||||
data[#data+1] = meta
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
ret = data
|
||||
else
|
||||
local pkg = luci.http.formvalue("package")
|
||||
local metapkg = metapkgpre .. pkg
|
||||
if action == "update" or pkg then
|
||||
if action == "update" or action == "install" then
|
||||
code, out, err = _action(myopkg, action, metapkg)
|
||||
else
|
||||
local meta = json_parse(fs.readfile(metadir .. "/" .. pkg .. ".json"))
|
||||
local pkgs = meta.depends
|
||||
table.insert(pkgs, metapkg)
|
||||
if action == "upgrade" then
|
||||
code, out, err = _action(myopkg, action, unpack(pkgs))
|
||||
else -- remove
|
||||
code, out, err = _action(myopkg, action, unpack(pkgs))
|
||||
if code ~= 0 then
|
||||
code, out0, err0 = _action(myopkg, action, unpack(pkgs))
|
||||
out = out .. out0
|
||||
err = err .. err0
|
||||
end
|
||||
fs.unlink("/tmp/luci-indexcache")
|
||||
end
|
||||
end
|
||||
else
|
||||
code = 400
|
||||
err = "package is null"
|
||||
end
|
||||
|
||||
ret = {
|
||||
code = code,
|
||||
stdout = out,
|
||||
stderr = err
|
||||
}
|
||||
end
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(ret)
|
||||
end
|
||||
|
||||
function store_token()
|
||||
luci.http.prepare_content("application/json")
|
||||
require "luci.template".render_string("{\"token\":\"<%=token%>\"}")
|
||||
end
|
||||
|
||||
function store_upload()
|
||||
local fd
|
||||
local path
|
||||
local finished = false
|
||||
local tmpdir = "/tmp/is-root/tmp"
|
||||
luci.http.setfilehandler(
|
||||
function(meta, chunk, eof)
|
||||
if not fd then
|
||||
path = tmpdir .. "/" .. meta.file
|
||||
nixio.fs.mkdirr(tmpdir)
|
||||
fd = io.open(path, "w")
|
||||
end
|
||||
if chunk then
|
||||
fd:write(chunk)
|
||||
end
|
||||
if eof then
|
||||
fd:close()
|
||||
finished = true
|
||||
end
|
||||
end
|
||||
)
|
||||
local code, out, err
|
||||
out = ""
|
||||
if finished then
|
||||
if string.lower(string.sub(path, -4, -1)) == ".run" then
|
||||
code, out, err = _action("sh", "-c", "chmod 755 \"%s\" && \"%s\"" %{ path, path })
|
||||
else
|
||||
code, out, err = _action(myopkg, "install", path)
|
||||
end
|
||||
else
|
||||
code = 500
|
||||
err = "upload failed!"
|
||||
end
|
||||
nixio.fs.unlink(path)
|
||||
local ret = {
|
||||
code = code,
|
||||
stdout = out,
|
||||
stderr = err
|
||||
}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(ret)
|
||||
end
|
||||
|
||||
local function split(str,reps)
|
||||
local resultStrList = {}
|
||||
string.gsub(str,'[^'..reps..']+',function (w)
|
||||
table.insert(resultStrList,w)
|
||||
end)
|
||||
return resultStrList
|
||||
end
|
||||
|
||||
local function ltn12_popen(command)
|
||||
|
||||
local fdi, fdo = nixio.pipe()
|
||||
local pid = nixio.fork()
|
||||
|
||||
if pid > 0 then
|
||||
fdo:close()
|
||||
local close
|
||||
return function()
|
||||
local buffer = fdi:read(2048)
|
||||
local wpid, stat = nixio.waitpid(pid, "nohang")
|
||||
if not close and wpid and stat == "exited" then
|
||||
close = true
|
||||
end
|
||||
|
||||
if buffer and #buffer > 0 then
|
||||
return buffer
|
||||
elseif close then
|
||||
fdi:close()
|
||||
return nil
|
||||
end
|
||||
end
|
||||
elseif pid == 0 then
|
||||
nixio.dup(fdo, nixio.stdout)
|
||||
fdi:close()
|
||||
fdo:close()
|
||||
nixio.exec("/bin/sh", "-c", command)
|
||||
end
|
||||
end
|
||||
|
||||
-- call get_support_backup_features
|
||||
function get_support_backup_features()
|
||||
local jsonc = require "luci.jsonc"
|
||||
local error_ret = {code = 500, msg = "Unknown"}
|
||||
local success_ret = {code = 200,msg = "Unknown"}
|
||||
local r,o,e = is_exec(myopkg .. " get_support_backup_features")
|
||||
if r ~= 0 then
|
||||
error_ret.msg = e
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
else
|
||||
success_ret.code = 200
|
||||
success_ret.msg = jsonc.stringify(split(o,'\n'))
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(success_ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- post light_backup
|
||||
function light_backup()
|
||||
local jsonc = require "luci.jsonc"
|
||||
local error_ret = {code = 500, msg = "Unknown"}
|
||||
local success_ret = {code = 200,msg = "Unknown"}
|
||||
local r,o,e = is_exec(myopkg .. " backup")
|
||||
|
||||
if r ~= 0 then
|
||||
error_ret.msg = e
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
else
|
||||
success_ret.code = 200
|
||||
success_ret.msg = o:gsub("[\r\n]", "")
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(success_ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- call get_light_backup_file
|
||||
function get_light_backup_file()
|
||||
local light_backup_cmd = "tar -c %s | gzip 2>/dev/null"
|
||||
local loght_backup_filelist = "/etc/istore/app.list"
|
||||
local reader = ltn12_popen(light_backup_cmd:format(loght_backup_filelist))
|
||||
luci.http.header('Content-Disposition', 'attachment; filename="light-backup-%s-%s.tar.gz"' % {
|
||||
luci.sys.hostname(), os.date("%Y-%m-%d")})
|
||||
luci.http.prepare_content("application/x-targz")
|
||||
luci.ltn12.pump.all(reader, luci.http.write)
|
||||
end
|
||||
|
||||
local function update_local_backup_path(path)
|
||||
local uci = require "uci"
|
||||
local fs = require "nixio.fs"
|
||||
local x = uci.cursor()
|
||||
local local_backup_path
|
||||
|
||||
if fs.access("/etc/config/istore") then
|
||||
local_backup_path = x:get("istore","istore","local_backup_path")
|
||||
else
|
||||
--create config file
|
||||
local f=io.open("/etc/config/istore","a+")
|
||||
f:write("config istore \'istore\'\n\toption local_backup_path \'\'")
|
||||
f:flush()
|
||||
f:close()
|
||||
end
|
||||
|
||||
if path ~= local_backup_path then
|
||||
-- set uci config
|
||||
x:set("istore","istore","local_backup_path",path)
|
||||
x:commit("istore")
|
||||
end
|
||||
end
|
||||
|
||||
-- post local_backup
|
||||
function local_backup()
|
||||
local code, out, err, ret
|
||||
local error_ret
|
||||
local path = luci.http.formvalue("path")
|
||||
if path ~= "" then
|
||||
-- judge path
|
||||
code,out,err = is_exec("findmnt -T " .. path .. " -o TARGET|sed -n 2p")
|
||||
if out:gsub("[\r\n]", "") == "/" or out:gsub("[\r\n]", "") == "/tmp" then
|
||||
-- error
|
||||
error_ret = {code = 500, msg = "Path Error,Can not be / or tmp."}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
else
|
||||
-- update local backup path
|
||||
update_local_backup_path(path)
|
||||
code,out,err = is_exec(myopkg .. " backup " .. path)
|
||||
ret = {
|
||||
code = code,
|
||||
stdout = out,
|
||||
stderr = err
|
||||
}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(ret)
|
||||
end
|
||||
else
|
||||
-- error
|
||||
error_ret = {code = 500, msg = "Path Unknown"}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- post light_restore
|
||||
function light_restore()
|
||||
local fd
|
||||
local path
|
||||
local finished = false
|
||||
local tmpdir = "/tmp/"
|
||||
luci.http.setfilehandler(
|
||||
function(meta, chunk, eof)
|
||||
if not fd then
|
||||
path = tmpdir .. "/" .. meta.file
|
||||
fd = io.open(path, "w")
|
||||
end
|
||||
if chunk then
|
||||
fd:write(chunk)
|
||||
end
|
||||
if eof then
|
||||
fd:close()
|
||||
finished = true
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local code, out, err, ret
|
||||
|
||||
if finished then
|
||||
is_exec("rm /etc/istore/app.list;tar -xzf " .. path .. " -C /")
|
||||
if nixio.fs.access("/etc/istore/app.list") then
|
||||
code,out,err = is_exec(myopkg .. " restore")
|
||||
ret = {
|
||||
code = code,
|
||||
stdout = out,
|
||||
stderr = err
|
||||
}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(ret)
|
||||
else
|
||||
local error_ret = {code = 500, msg = "File is error!"}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
end
|
||||
-- remove file
|
||||
is_exec("rm " .. path)
|
||||
else
|
||||
ret = {code = 500, msg = "upload failed!"}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- post local_restore
|
||||
function local_restore()
|
||||
local path = luci.http.formvalue("path")
|
||||
local code, out, err, ret
|
||||
if path ~= "" then
|
||||
code,out,err = is_exec(myopkg .. " restore " .. path)
|
||||
ret = {
|
||||
code = code,
|
||||
stdout = out,
|
||||
stderr = err
|
||||
}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(ret)
|
||||
else
|
||||
-- error
|
||||
error_ret = {code = 500, msg = "Path Unknown"}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- call get_backup_app_list_file_path
|
||||
function get_backup_app_list_file_path()
|
||||
local jsonc = require "luci.jsonc"
|
||||
local error_ret = {code = 500, msg = "Unknown"}
|
||||
local success_ret = {code = 200,msg = "Unknown"}
|
||||
local r,o,e = is_exec(myopkg .. " get_backup_app_list_file_path")
|
||||
if r ~= 0 then
|
||||
error_ret.msg = e
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
else
|
||||
success_ret.code = 200
|
||||
success_ret.msg = o:gsub("[\r\n]", "")
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(success_ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- call get_backup_app_list
|
||||
function get_backup_app_list()
|
||||
local jsonc = require "luci.jsonc"
|
||||
local error_ret = {code = 500, msg = "Unknown"}
|
||||
local success_ret = {code = 200,msg = "Unknown"}
|
||||
local r,o,e = is_exec(myopkg .. " get_backup_app_list")
|
||||
if r ~= 0 then
|
||||
error_ret.msg = e
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
else
|
||||
success_ret.code = 200
|
||||
success_ret.msg = jsonc.stringify(split(o,'\n'))
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(success_ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- call get_available_backup_file_list
|
||||
function get_available_backup_file_list()
|
||||
local jsonc = require "luci.jsonc"
|
||||
local error_ret = {code = 500, msg = "Unknown"}
|
||||
local success_ret = {code = 200,msg = "Unknown"}
|
||||
local path = luci.http.formvalue("path")
|
||||
local r,o,e
|
||||
|
||||
if path ~= "" then
|
||||
-- update local backup path
|
||||
update_local_backup_path(path)
|
||||
r,o,e = is_exec(myopkg .. " get_available_backup_file_list " .. path)
|
||||
if r ~= 0 then
|
||||
error_ret.msg = e
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
else
|
||||
success_ret.code = 200
|
||||
success_ret.msg = jsonc.stringify(split(o,'\n'))
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(success_ret)
|
||||
end
|
||||
else
|
||||
-- set error code
|
||||
error_ret.msg = "Path Unknown"
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- post set_local_backup_dir_path
|
||||
function set_local_backup_dir_path()
|
||||
local path = luci.http.formvalue("path")
|
||||
local success_ret = {code = 200,msg = "Success"}
|
||||
local error_ret = {code = 500, msg = "Unknown"}
|
||||
|
||||
if path ~= "" then
|
||||
-- update local backup path
|
||||
update_local_backup_path(path)
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(success_ret)
|
||||
else
|
||||
-- set error code
|
||||
error_ret.msg = "Path Unknown"
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
end
|
||||
end
|
||||
|
||||
-- call get_local_backup_dir_path
|
||||
function get_local_backup_dir_path()
|
||||
local uci = require "uci"
|
||||
local fs = require "nixio.fs"
|
||||
local x = uci.cursor()
|
||||
local local_backup_path = nil
|
||||
local success_ret = {code = 200,msg = "Unknown"}
|
||||
local error_ret = {code = 500, msg = "Path Unknown"}
|
||||
|
||||
if fs.access("/etc/config/istore") then
|
||||
local_backup_path = x:get("istore","istore","local_backup_path")
|
||||
if local_backup_path == nil then
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
else
|
||||
success_ret.msg = local_backup_path:gsub("[\r\n]", "")
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(success_ret)
|
||||
end
|
||||
else
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(error_ret)
|
||||
end
|
||||
end
|
@ -1,24 +0,0 @@
|
||||
<%+header%>
|
||||
<link rel="stylesheet" href="/luci-static/istore/style.css?v=<%=id.version%>">
|
||||
<script>
|
||||
(function(){
|
||||
var vue_prefix="<%=prefix%>";
|
||||
var myurl = window.location.pathname;
|
||||
window.addEventListener('popstate', function(){
|
||||
if (myurl != window.location.pathname
|
||||
&& window.location.pathname != vue_prefix
|
||||
&& ! window.location.pathname.startsWith(vue_prefix+'/')) {
|
||||
window.location.href = window.location.pathname;
|
||||
}
|
||||
});
|
||||
window.vue_base = vue_prefix + '/';
|
||||
window.token = "<%=token%>";
|
||||
window.device_id = {arch:"<%=id.arch%>",uid:"<%=id.uid%>",version:"<%=id.version%>"};
|
||||
})();
|
||||
</script>
|
||||
<h2 name="content">应用商店 v<%=id.version%></h2>
|
||||
<div id="app">
|
||||
</div>
|
||||
<script type="module" crossorigin src="/luci-static/istore/index.js?v=<%=id.version%>"></script>
|
||||
<link rel="modulepreload" href="/luci-static/istore/vendor.js?v=<%=id.version%>">
|
||||
<%+footer%>
|
@ -1,200 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# ipkg-build -- construct a .ipk from a directory
|
||||
# Carl Worth <cworth@east.isi.edu>
|
||||
# based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
|
||||
# 2003-04-25 rea@sr.unh.edu
|
||||
# Updated to work on Familiar Pre0.7rc1, with busybox tar.
|
||||
# Note it Requires: binutils-ar (since the busybox ar can't create)
|
||||
# For UID debugging it needs a better "find".
|
||||
set -e
|
||||
|
||||
version=1.0
|
||||
FIND="$(command -v find)"
|
||||
FIND="${FIND:-$(command -v gfind)}"
|
||||
TAR="${TAR:-$(command -v tar)}"
|
||||
GZIP="$(command -v gzip)"
|
||||
|
||||
# try to use fixed source epoch
|
||||
if [ -n "$PKG_SOURCE_DATE_EPOCH" ]; then
|
||||
TIMESTAMP=$(date --date="@$PKG_SOURCE_DATE_EPOCH")
|
||||
elif [ -n "$SOURCE_DATE_EPOCH" ]; then
|
||||
TIMESTAMP=$(date --date="@$SOURCE_DATE_EPOCH")
|
||||
else
|
||||
TIMESTAMP=$(date)
|
||||
fi
|
||||
|
||||
ipkg_extract_value() {
|
||||
sed -e "s/^[^:]*:[[:space:]]*//"
|
||||
}
|
||||
|
||||
required_field() {
|
||||
field=$1
|
||||
|
||||
grep "^$field:" < $CONTROL/control | ipkg_extract_value
|
||||
}
|
||||
|
||||
pkg_appears_sane() {
|
||||
local pkg_dir=$1
|
||||
|
||||
local owd=$PWD
|
||||
cd $pkg_dir
|
||||
|
||||
PKG_ERROR=0
|
||||
pkg=`required_field Package`
|
||||
version=`required_field Version | sed 's/Version://; s/^.://g;'`
|
||||
arch=`required_field Architecture`
|
||||
|
||||
if echo $pkg | grep '[^a-zA-Z0-9_.+-]'; then
|
||||
echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
|
||||
PKG_ERROR=1;
|
||||
fi
|
||||
|
||||
if [ -f $CONTROL/conffiles ]; then
|
||||
rm -f $CONTROL/conffiles.resolved
|
||||
|
||||
for cf in `$FIND $(sed -e "s!^/!$pkg_dir/!" $CONTROL/conffiles) -type f`; do
|
||||
echo "${cf#$pkg_dir}" >> $CONTROL/conffiles.resolved
|
||||
done
|
||||
|
||||
rm $CONTROL/conffiles
|
||||
if [ -f $CONTROL/conffiles.resolved ]; then
|
||||
mv $CONTROL/conffiles.resolved $CONTROL/conffiles
|
||||
chmod 0644 $CONTROL/conffiles
|
||||
fi
|
||||
fi
|
||||
|
||||
cd $owd
|
||||
return $PKG_ERROR
|
||||
}
|
||||
|
||||
resolve_file_mode_id() {
|
||||
local var=$1 type=$2 name=$3 id
|
||||
|
||||
case "$name" in
|
||||
root)
|
||||
id=0
|
||||
;;
|
||||
*[!0-9]*)
|
||||
id=$(sed -ne "s#^$type $name \\([0-9]\\+\\)\\b.*\$#\\1#p" "$TOPDIR/tmp/.packageusergroup" 2>/dev/null)
|
||||
;;
|
||||
*)
|
||||
id=$name
|
||||
;;
|
||||
esac
|
||||
|
||||
export "$var=$id"
|
||||
|
||||
[ -n "$id" ]
|
||||
}
|
||||
|
||||
###
|
||||
# ipkg-build "main"
|
||||
###
|
||||
file_modes=""
|
||||
usage="Usage: $0 [-v] [-h] [-m] <pkg_directory> [<destination_directory>]"
|
||||
while getopts "hvm:" opt; do
|
||||
case $opt in
|
||||
v ) echo $version
|
||||
exit 0
|
||||
;;
|
||||
h ) echo $usage >&2 ;;
|
||||
m ) file_modes=$OPTARG ;;
|
||||
\? ) echo $usage >&2
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
shift $(($OPTIND - 1))
|
||||
|
||||
# continue on to process additional arguments
|
||||
|
||||
case $# in
|
||||
1)
|
||||
dest_dir=$PWD
|
||||
;;
|
||||
2)
|
||||
dest_dir=$2
|
||||
if [ "$dest_dir" = "." -o "$dest_dir" = "./" ] ; then
|
||||
dest_dir=$PWD
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo $usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
pkg_dir=$1
|
||||
|
||||
if [ ! -d $pkg_dir ]; then
|
||||
echo "*** Error: Directory $pkg_dir does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# CONTROL is second so that it takes precedence
|
||||
CONTROL=
|
||||
[ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
|
||||
if [ -z "$CONTROL" ]; then
|
||||
echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! pkg_appears_sane $pkg_dir; then
|
||||
echo >&2
|
||||
echo "ipkg-build: Please fix the above errors and try again." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp_dir=$dest_dir/IPKG_BUILD.$$
|
||||
mkdir $tmp_dir
|
||||
|
||||
echo $CONTROL > $tmp_dir/tarX
|
||||
cd $pkg_dir
|
||||
for file_mode in $file_modes; do
|
||||
case $file_mode in
|
||||
/*:*:*:*)
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: file modes must use absolute path and contain user:group:mode"
|
||||
echo "$file_mode"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
mode=${file_mode##*:}; path=${file_mode%:*}
|
||||
group=${path##*:}; path=${path%:*}
|
||||
user=${path##*:}; path=${path%:*}
|
||||
|
||||
if ! resolve_file_mode_id uid user "$user"; then
|
||||
echo "ERROR: unable to resolve uid of $user" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! resolve_file_mode_id gid group "$group"; then
|
||||
echo "ERROR: unable to resolve gid of $group" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chown "$uid:$gid" "$pkg_dir/$path"
|
||||
chmod "$mode" "$pkg_dir/$path"
|
||||
done
|
||||
$TAR -X $tmp_dir/tarX --format=gnu --sort=name -cpf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/data.tar.gz
|
||||
|
||||
installed_size=`stat -c "%s" $tmp_dir/data.tar.gz`
|
||||
sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
|
||||
$pkg_dir/$CONTROL/control
|
||||
|
||||
( cd $pkg_dir/$CONTROL && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/control.tar.gz )
|
||||
rm $tmp_dir/tarX
|
||||
|
||||
echo "2.0" > $tmp_dir/debian-binary
|
||||
|
||||
pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
|
||||
rm -f $pkg_file
|
||||
( cd $tmp_dir && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" ./debian-binary ./data.tar.gz ./control.tar.gz | $GZIP -n - > $pkg_file )
|
||||
|
||||
rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
|
||||
rmdir $tmp_dir
|
||||
|
||||
echo "Packaged contents of $pkg_dir into $pkg_file"
|
@ -1,477 +0,0 @@
|
||||
#!/bin/sh
|
||||
#set -x
|
||||
#IS_DEBUG=1
|
||||
|
||||
IS_ROOT=/tmp/is-root
|
||||
DL_DIR=${IS_ROOT}/tmp/dl
|
||||
LISTS_DIR_O=/tmp/opkg-lists
|
||||
LISTS_DIR=${IS_ROOT}${LISTS_DIR_O}
|
||||
OPKG_CONF_DIR=${IS_ROOT}/etc/opkg
|
||||
APP_LIST_FILE=/etc/istore/app.list
|
||||
BACKUP_CONFIG_FILE=/etc/config/istore
|
||||
FEEDS_SERVER=https://istore.linkease.com/repo
|
||||
ARCH=`jsonfilter -i /etc/.app_store.id -e '$.arch'`
|
||||
|
||||
# for istore self upgrade
|
||||
ISTORE_PKG=luci-app-store
|
||||
ISTORE_INDEX=https://istore.linkease.com/repo/all/store/Packages.gz
|
||||
|
||||
action=${1}
|
||||
shift
|
||||
|
||||
is_init() {
|
||||
mkdir -p ${DL_DIR} ${LISTS_DIR} ${IS_ROOT}/etc ${IS_ROOT}/var
|
||||
|
||||
cat /etc/opkg.conf | grep -v lists_dir | grep -v check_signature > ${IS_ROOT}/etc/opkg.conf
|
||||
|
||||
cp ${IS_ROOT}/etc/opkg.conf ${IS_ROOT}/etc/opkg_o.conf
|
||||
|
||||
echo >> ${IS_ROOT}/etc/opkg.conf
|
||||
echo "lists_dir ext ${LISTS_DIR}" >> ${IS_ROOT}/etc/opkg.conf
|
||||
echo >> ${IS_ROOT}/etc/opkg_o.conf
|
||||
echo "lists_dir ext ${LISTS_DIR_O}" >> ${IS_ROOT}/etc/opkg_o.conf
|
||||
|
||||
cp -au /etc/opkg ${IS_ROOT}/etc/
|
||||
[ -e ${IS_ROOT}/var/lock ] || ln -s /var/lock ${IS_ROOT}/var/lock
|
||||
}
|
||||
|
||||
opkg_wrap() {
|
||||
OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@"
|
||||
}
|
||||
|
||||
fcurl() {
|
||||
curl --fail --show-error "$@"
|
||||
}
|
||||
|
||||
update() {
|
||||
if [ -z "${ARCH}" ]; then
|
||||
echo "Get architecture failed" >&2
|
||||
echo "/etc/.app_store.id:" >&2
|
||||
cat /etc/.app_store.id >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
fcurl -o ${OPKG_CONF_DIR}/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \
|
||||
fcurl -o ${OPKG_CONF_DIR}/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \
|
||||
fcurl -o ${OPKG_CONF_DIR}/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" || \
|
||||
return 1
|
||||
|
||||
opkg -f ${IS_ROOT}/etc/opkg_o.conf --offline-root ${IS_ROOT} update
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
update_if_outdate() {
|
||||
local idle_t=$((`date '+%s'` - `date -r ${IS_ROOT}/.last_force_ts '+%s' 2>/dev/null || echo '0'`))
|
||||
[ $idle_t -gt ${1:-120} ] || return 2
|
||||
update || return 1
|
||||
touch ${IS_ROOT}/.last_force_ts
|
||||
return 0
|
||||
}
|
||||
|
||||
check_self_upgrade() {
|
||||
local newest=`curl --connect-timeout 2 --max-time 5 -s ${ISTORE_INDEX} | gunzip | grep -FA10 "Package: ${ISTORE_PKG}" | grep -Fm1 'Version: ' | sed 's/^Version: //'`
|
||||
local current=`grep -Fm1 'Version: ' /usr/lib/opkg/info/${ISTORE_PKG}.control | sed 's/^Version: //'`
|
||||
if [ "v$newest" = "v" -o "v$current" = "v" ]; then
|
||||
echo "Check version failed!" >&2
|
||||
exit 255
|
||||
fi
|
||||
if [ "$newest" != "$current" ]; then
|
||||
echo "$newest"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
do_self_upgrade() {
|
||||
check_mtime || return 1
|
||||
if opkg_wrap info ${ISTORE_PKG} | grep -qF not-installed ; then
|
||||
true
|
||||
else
|
||||
update_if_outdate
|
||||
local code=$?
|
||||
[ "$code" = 1 ] && return 1
|
||||
if [ "$code" = 2 ] || ! opkg_wrap info ${ISTORE_PKG} | grep -qF not-installed; then
|
||||
echo "already the latest version!" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
opkg_wrap upgrade ${ISTORE_PKG}
|
||||
}
|
||||
|
||||
check_mtime() {
|
||||
find ${OPKG_CONF_DIR}/arch.conf -mtime -1 2>/dev/null | grep -q . || update
|
||||
}
|
||||
|
||||
wrapped_in_update() {
|
||||
check_mtime || return 1
|
||||
opkg_wrap "$@" && return 0
|
||||
update_if_outdate || return 1
|
||||
opkg_wrap "$@"
|
||||
}
|
||||
|
||||
new_upgrade() {
|
||||
check_mtime || return 1
|
||||
local metapkg=`echo "$@" | sed 's/ /\n/g' | grep -F app-meta-`
|
||||
if [ -z "$metapkg" ] || opkg_wrap info $metapkg | grep -qF not-installed ; then
|
||||
true
|
||||
else
|
||||
update_if_outdate
|
||||
fi
|
||||
wrapped_in_update upgrade "$@"
|
||||
}
|
||||
|
||||
opkg_list_installed_packages() {
|
||||
target=$1
|
||||
case $target in
|
||||
"preinstalled")
|
||||
OPKG_INFO_DIR="/rom/usr/lib/opkg/info"
|
||||
;;
|
||||
"userinstalled")
|
||||
OPKG_INFO_DIR="/overlay/upper/usr/lib/opkg/info"
|
||||
;;
|
||||
"allinstalled")
|
||||
OPKG_INFO_DIR="/usr/lib/opkg/info"
|
||||
;;
|
||||
*)
|
||||
echo "invalid target"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
awk -v D="cd $OPKG_INFO_DIR &&" 'BEGIN {
|
||||
C=D"ls *.list"
|
||||
S="sort -n"
|
||||
while(C|getline>0) {
|
||||
P=substr(F=$1,1,length($1)-5)
|
||||
J=D"du -sk $(cat "F")"
|
||||
s=0
|
||||
while(J|getline>0) s+=$1
|
||||
close(J)
|
||||
t+=s
|
||||
print s" "P|S
|
||||
}
|
||||
close(S)
|
||||
}'
|
||||
}
|
||||
|
||||
ipk_build() {
|
||||
PKG_NAME_TEMP=$1
|
||||
IPK_OUTPUT_DIR=$2
|
||||
|
||||
UCI_BAK_DIR="/etc/istore/uci-defaults_bak/"
|
||||
UCI_DEF_DIR="etc/uci-defaults"
|
||||
OPKG_INFO_DIR="/usr/lib/opkg/info/"
|
||||
|
||||
[ -n "${PKG_NAME_TEMP}" ] || exit 1
|
||||
#get real pkg name in opkg
|
||||
PKG_NAME_TEMP=`cat ${IS_ROOT}/all_installed_package.list | sort -u | grep "^${PKG_NAME_TEMP}" | head -n 1`
|
||||
[ -n "${PKG_NAME_TEMP}" ] || exit 1
|
||||
|
||||
PKG_NAME=`cat ${OPKG_INFO_DIR}${PKG_NAME_TEMP}.control | grep "^Package: " | cut -d ' ' -f2`
|
||||
PKG_VER=`cat ${OPKG_INFO_DIR}${PKG_NAME}.control | grep "^Version: " | cut -d ' ' -f2`
|
||||
PKG_ARCH=`cat ${OPKG_INFO_DIR}${PKG_NAME}.control | grep "^Architecture: " | cut -d ' ' -f2`
|
||||
IPK_FILE_NAME="${PKG_NAME}_${PKG_VER}_${PKG_ARCH}"
|
||||
|
||||
rm -rf ${IS_ROOT}/${IPK_FILE_NAME}
|
||||
mkdir -p ${IS_ROOT}/${IPK_FILE_NAME}
|
||||
|
||||
#(1)make CONTROL dir; (2)copy control file to dir
|
||||
cd ${IS_ROOT}/${IPK_FILE_NAME}
|
||||
mkdir -p CONTROL
|
||||
for control_file in `ls ${OPKG_INFO_DIR}${PKG_NAME}.* | grep -v ".list$"`; do
|
||||
file=${control_file##*/}
|
||||
suffix=${file##*.}
|
||||
cp ${control_file} CONTROL/${suffix}
|
||||
done
|
||||
|
||||
#(1)make DATA depend dir; (2)copy uci-defaults_bak file to dir; (3)copy other file to dir
|
||||
for pkgfile in `cat ${OPKG_INFO_DIR}${PKG_NAME}.list | cut -b 2-`; do
|
||||
file=${pkgfile##*/}
|
||||
path=${pkgfile%/*}
|
||||
mkdir -p ${path}
|
||||
if [ `echo "${path}" | grep "^${UCI_DEF_DIR}"` ]; then
|
||||
cp "${UCI_BAK_DIR}${file}" "${pkgfile}"
|
||||
else
|
||||
cp "/${pkgfile}" "${pkgfile}"
|
||||
fi
|
||||
done
|
||||
|
||||
#call ipkg-build script to build ipk
|
||||
ipkg-build ${IS_ROOT}/${IPK_FILE_NAME} ${IPK_OUTPUT_DIR}
|
||||
echo "${IPK_FILE_NAME}.ipk" >> ${IPK_OUTPUT_DIR}/appdepipk.list
|
||||
|
||||
[ -n "${IS_DEBUG}" ] || rm -rf ${IS_ROOT}/${IPK_FILE_NAME}
|
||||
}
|
||||
|
||||
# if arg is NULL, use light backup, otherwise use local backup
|
||||
backup() {
|
||||
[ -n "$1" ] && BACKUP_PATH=$1
|
||||
|
||||
#1.add all istore self data to sysupgrade config file,
|
||||
#sysupgrade will backup/restore it auto when flash new firmware
|
||||
echo "/etc/.app_store.id" > /lib/upgrade/keep.d/luci-app-store
|
||||
cat /usr/lib/opkg/info/luci-app-store.list >> /lib/upgrade/keep.d/luci-app-store
|
||||
echo "/etc/rc.d/S45istore" >> /lib/upgrade/keep.d/luci-app-store
|
||||
echo "/etc/istore/uci-defaults_bak" >> /lib/upgrade/keep.d/luci-app-store
|
||||
echo "${APP_LIST_FILE}" >> /lib/upgrade/keep.d/luci-app-store
|
||||
echo "${BACKUP_CONFIG_FILE}" >> /lib/upgrade/keep.d/luci-app-store
|
||||
|
||||
#2.backup all installed package lists to config file
|
||||
update #if want not depend this, need record package list by istore to file when is-opkg update
|
||||
|
||||
#get feed list
|
||||
opkg_conf_list="meta all arch"
|
||||
feed_name_list=""
|
||||
for conf in ${opkg_conf_list}; do
|
||||
feed_name=`cat ${OPKG_CONF_DIR}/${conf}.conf | cut -d ' ' -f2`
|
||||
feed_name_list="${feed_name} ${feed_name_list}"
|
||||
done
|
||||
[ -n "${IS_DEBUG}" ] && echo ${feed_name_list}
|
||||
|
||||
istore_package_list=""
|
||||
#get istore package list
|
||||
for feed_name in ${feed_name_list}; do
|
||||
package_list=`cat ${LISTS_DIR}/${feed_name} | gunzip | grep "^Package: " | cut -d ' ' -f2`
|
||||
istore_package_list="${package_list} ${istore_package_list}"
|
||||
done
|
||||
[ -n "${IS_DEBUG}" ] && echo ${istore_package_list}
|
||||
|
||||
#write istore package list to file
|
||||
echo ${istore_package_list} | tr " " "\n" | sort -n | uniq > ${IS_ROOT}/istore_support_package.list
|
||||
|
||||
#write all installed package list to file
|
||||
opkg_list_installed_packages "allinstalled" 2>/dev/null | cut -d ' ' -f2 | sort -u > ${IS_ROOT}/all_installed_package.list
|
||||
|
||||
#write user installed package list to file
|
||||
opkg_list_installed_packages "userinstalled" 2>/dev/null | cut -d ' ' -f2 | sort -u > ${IS_ROOT}/user_installed_package.list
|
||||
|
||||
#write system pre installed package list to file
|
||||
opkg_list_installed_packages "preinstalled" 2>/dev/null | cut -d ' ' -f2 | sort -u > ${IS_ROOT}/pre_installed_package.list
|
||||
|
||||
#write installed package list by istore feed to file
|
||||
cat ${IS_ROOT}/istore_support_package.list ${IS_ROOT}/user_installed_package.list | \
|
||||
sort -n | uniq -d > ${IS_ROOT}/istore_installed_package.list
|
||||
|
||||
#if no input backup path, only back app.list
|
||||
mkdir -p /etc/istore
|
||||
cp ${IS_ROOT}/istore_installed_package.list ${APP_LIST_FILE}
|
||||
echo "backup installed package list to ${APP_LIST_FILE}"
|
||||
|
||||
if [ ! -n "${BACKUP_PATH}" ]; then
|
||||
echo "backup success"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#write installed packages and depends list by istore feed to file by depend sequence
|
||||
appdep_list=""
|
||||
temp_list=`cat ${IS_ROOT}/istore_installed_package.list | sed 's/^/\t/'`
|
||||
while [ -n "${temp_list}" ]
|
||||
do
|
||||
#get real pkg name
|
||||
for PKG_NAME_TEMP in ${temp_list}; do
|
||||
REAL_PKG_NAME=`cat ${IS_ROOT}/all_installed_package.list | sort -u | grep "^${PKG_NAME_TEMP}" | head -n 1`
|
||||
if [ "${REAL_PKG_NAME}" != "${PKG_NAME_TEMP}" ]; then
|
||||
temp_list=`echo "${temp_list}" | sed 's/^\t'"${PKG_NAME_TEMP}"'$/\t'"${REAL_PKG_NAME}"'/'`
|
||||
fi
|
||||
done
|
||||
|
||||
appdep_list=`echo -e "${temp_list}\n${appdep_list}"`
|
||||
[ -n "${IS_DEBUG}" ] && echo -e "temp_list:\n""${temp_list}"
|
||||
[ -n "${IS_DEBUG}" ] && echo -e "appdep_list:\n""${appdep_list}"
|
||||
|
||||
temp_list=`echo "${temp_list}" | xargs opkg depends | grep -v "depends on:" | grep -v " (>= " | grep -v " (= " | sort -u`
|
||||
done
|
||||
|
||||
appdep_list_all=`echo "${appdep_list}" | cut -f2 | grep -v "^$" | awk '!seen[$0]++'`
|
||||
[ -n "${IS_DEBUG}" ] && echo -e "appdep_list_all:\n""${appdep_list_all}"
|
||||
echo "${appdep_list_all}" > ${IS_ROOT}/appdep.list
|
||||
|
||||
|
||||
#3.rebuild all istore installed package to ipk and backup to userdata partation
|
||||
if [ ! -d "${BACKUP_PATH}" ];then
|
||||
echo "invalid backup path, can not backup ipk"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 4. create dir
|
||||
date=$(date +%Y-%m%d-%H%M)
|
||||
if [ ! -d "$BACKUP_PATH/backup_istore_$date" ];then
|
||||
mkdir $BACKUP_PATH/backup_istore_$date
|
||||
fi
|
||||
cp ${IS_ROOT}/istore_installed_package.list $BACKUP_PATH/backup_istore_$date/app.list
|
||||
cp ${IS_ROOT}/appdep.list $BACKUP_PATH/backup_istore_$date/appdep.list
|
||||
|
||||
#only backup non pre installed ipk
|
||||
cp ${IS_ROOT}/appdep.list ${IS_ROOT}/appdep_strip.list
|
||||
for pre_installed_pkg in `cat ${IS_ROOT}/appdep.list ${IS_ROOT}/pre_installed_package.list | sort -n | uniq -d`; do
|
||||
sed -i '/^'"$pre_installed_pkg"'$/d' ${IS_ROOT}/appdep_strip.list
|
||||
done
|
||||
|
||||
rm -f $BACKUP_PATH/backup_istore_$date/appdepipk.list
|
||||
echo "build ipk"
|
||||
for pkg_name in `cat ${IS_ROOT}/appdep_strip.list`; do
|
||||
ipk_build ${pkg_name} $BACKUP_PATH/backup_istore_$date
|
||||
done
|
||||
|
||||
# 5. create tar.gz file,and remove fir
|
||||
cd $BACKUP_PATH
|
||||
echo "write backup file to $BACKUP_PATH/backup_istore_$date.backup.tar.gz"
|
||||
tar -czf $BACKUP_PATH/backup_istore_$date.backup.tar.gz backup_istore_$date
|
||||
rm -rf $BACKUP_PATH/backup_istore_$date
|
||||
echo "backup success"
|
||||
}
|
||||
|
||||
# if arg is NULL, use light backup, otherwise use local backup
|
||||
restore() {
|
||||
if [ -n "$1" ]; then
|
||||
BACKUP_PATH_FILE=$1
|
||||
else
|
||||
echo "install package by ${APP_LIST_FILE}"
|
||||
update
|
||||
for app in `cat ${APP_LIST_FILE}`; do
|
||||
#skip resotre istore self
|
||||
[ "A${app}" == "A""luci-app-store" ] && continue
|
||||
opkg_wrap install ${app}
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -f "${BACKUP_PATH_FILE}" ];then
|
||||
echo "invalid backup file, can not restore ipk"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#1. Unzip file to dir
|
||||
BACKUP_PATH_FILE_NAME=${BACKUP_PATH_FILE##*/}
|
||||
BACKUP_PATH=/tmp/${BACKUP_PATH_FILE_NAME%.backup.tar.gz*}
|
||||
if [ -d "$BACKUP_PATH" ];then
|
||||
rm -rf $BACKUP_PATH
|
||||
fi
|
||||
mkdir -p $BACKUP_PATH
|
||||
echo "unpack input file..."
|
||||
# fix tar path error
|
||||
tar -zxf ${BACKUP_PATH_FILE} -C /tmp/
|
||||
|
||||
echo "check file"
|
||||
if [ ! -f "${BACKUP_PATH}/appdep.list" ];then
|
||||
echo "no available appdep.list, can not restore ipk"
|
||||
exit 1
|
||||
fi
|
||||
echo "check success"
|
||||
|
||||
#2. install ipk by backup path
|
||||
echo "restore begin"
|
||||
for app in `cat ${BACKUP_PATH}/appdepipk.list`; do
|
||||
opkg_wrap install ${BACKUP_PATH}/${app}
|
||||
done
|
||||
|
||||
#3. rm dir
|
||||
rm -rf ${BACKUP_PATH}
|
||||
echo "restore success"
|
||||
}
|
||||
|
||||
get_support_backup_features() {
|
||||
echo "light_backup"
|
||||
#istore custom img mean support local_backup
|
||||
if [ -f /etc/istore_img_flag ];then
|
||||
echo "local_backup"
|
||||
fi
|
||||
}
|
||||
|
||||
get_backup_app_list_file_path() {
|
||||
echo "${APP_LIST_FILE}"
|
||||
}
|
||||
|
||||
get_backup_app_list() {
|
||||
if [ ! -f "${APP_LIST_FILE}" ];then
|
||||
echo "no app.list, can not get backup app list"
|
||||
exit 1
|
||||
fi
|
||||
cat ${APP_LIST_FILE}
|
||||
}
|
||||
|
||||
get_available_backup_file_list() {
|
||||
if [ -n "$1" ]; then
|
||||
for backup_file in `ls $1/*.backup.tar.gz`; do
|
||||
filename=${backup_file##*/}
|
||||
echo "${filename}"
|
||||
done
|
||||
else
|
||||
echo "input backup path is null"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: is-opkg sub-command [arguments...]"
|
||||
echo "where sub-command is one of:"
|
||||
echo " update Update list of available packages"
|
||||
echo " upgrade <pkgs> Upgrade package(s)"
|
||||
echo " install <pkgs> Install package(s)"
|
||||
echo " remove <pkgs|regexp> Remove package(s)"
|
||||
echo " info [pkg|regexp] Display all info for <pkg>"
|
||||
echo " list-upgradable List installed and upgradable packages"
|
||||
echo " check_self_upgrade Check iStore upgrade"
|
||||
echo " do_self_upgrade Upgrade iStore"
|
||||
echo " backup [dir] Backup all installed package(s) to [directory]"
|
||||
echo " restore [dir] Restore package(s) by [directory]"
|
||||
echo " get_support_backup_features get device support backup features"
|
||||
echo " get_backup_app_list_file_path get light backup app list file path"
|
||||
echo " get_backup_app_list get light backup app list"
|
||||
echo " get_available_backup_file_list get local available backup file list"
|
||||
echo " opkg sys opkg wrap"
|
||||
}
|
||||
|
||||
is_init >/dev/null 2>&1
|
||||
|
||||
case $action in
|
||||
"update")
|
||||
update
|
||||
;;
|
||||
"install")
|
||||
wrapped_in_update install "$@"
|
||||
;;
|
||||
"upgrade")
|
||||
new_upgrade "$@"
|
||||
;;
|
||||
"remove")
|
||||
opkg_wrap --autoremove --force-removal-of-dependent-packages remove "$@"
|
||||
;;
|
||||
"info")
|
||||
opkg_wrap info "$@"
|
||||
;;
|
||||
"list-upgradable")
|
||||
opkg_wrap list-upgradable
|
||||
;;
|
||||
"check_self_upgrade")
|
||||
check_self_upgrade
|
||||
;;
|
||||
"do_self_upgrade")
|
||||
do_self_upgrade
|
||||
;;
|
||||
"get_support_backup_features")
|
||||
get_support_backup_features
|
||||
;;
|
||||
"backup")
|
||||
backup "$@"
|
||||
;;
|
||||
"restore")
|
||||
restore "$@"
|
||||
;;
|
||||
"get_backup_app_list_file_path")
|
||||
get_backup_app_list_file_path
|
||||
;;
|
||||
"get_backup_app_list")
|
||||
get_backup_app_list
|
||||
;;
|
||||
"get_available_backup_file_list")
|
||||
get_available_backup_file_list "$@"
|
||||
;;
|
||||
"opkg")
|
||||
opkg_wrap "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
@ -1,25 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2016 OpenWrt.org
|
||||
|
||||
START=45
|
||||
|
||||
boot() {
|
||||
[ -s /etc/.app_store.id ] && return 0
|
||||
|
||||
mkdir -p /tmp/is-inst/var/lock
|
||||
ARCH=`opkg -f /dev/null --offline-root /tmp/is-inst print-architecture | grep -v 'arch all' | grep -v 'arch noarch' | cut -d ' ' -f2`
|
||||
rm -rf /tmp/is-inst
|
||||
|
||||
for iface in eth0 br-lan; do
|
||||
if [ -e /sys/class/net/$iface/address ]; then
|
||||
HASH=`md5sum /sys/class/net/$iface/address | cut -d ' ' -f1`
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$HASH" ]; then
|
||||
HASH=`dd if=/dev/urandom bs=512 count=1 2>/dev/null | md5sum | cut -d ' ' -f1`
|
||||
fi
|
||||
|
||||
echo "{\"arch\":\"${ARCH}\", \"uid\":\"${HASH}\"}" > /etc/.app_store.id
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
/etc/init.d/istore boot
|
||||
|
||||
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
|
@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
for i in "$@"; do
|
||||
echo "$i" | grep -s -q "/etc/uci-defaults/" \
|
||||
&& mkdir -p /etc/istore/uci-defaults_bak \
|
||||
&& cp -f "$i" /etc/istore/uci-defaults_bak/
|
||||
done
|
||||
/bin/rm "$@"
|
@ -1,8 +0,0 @@
|
||||
clean:
|
||||
compile:
|
||||
install:
|
||||
mkdir -p "$(DESTDIR)/www/luci-static"
|
||||
cp -a "$(FRONTEND_DIST)/luci-static/istore" "$(DESTDIR)/www/luci-static/"
|
||||
$(SED) 's#\.js"#.js?v=$(APP_STORE_VERSION)"#g' "$(DESTDIR)/www/luci-static/istore/index.js"
|
||||
mkdir -p "$(DESTDIR)/etc"
|
||||
echo "$(APP_STORE_VERSION)" > "$(DESTDIR)/etc/.app_store.version"
|
@ -1,61 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2015-2016 OpenWrt.org
|
||||
# Copyright (C) 2020 jjm2473@gmail.com
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_ARCH_quickstart:=$(ARCH)
|
||||
|
||||
PKG_NAME:=quickstart
|
||||
PKG_VERSION:=0.0.1
|
||||
PKG_RELEASE:=1
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://fw.koolcenter.com/binary/quickstart/
|
||||
PKG_HASH:=13018d6d166e58f25d42ae3e4bbf882a1ce30315f432246fc6627558aefd658f
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=Quickstart, the quick start.
|
||||
DEPENDS:=
|
||||
URL:=https://easepi.linkease.com/
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
Quickstart is a dashboard & user guide
|
||||
endef
|
||||
|
||||
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
[ -f /etc/uci-defaults/quickstart ] && /etc/uci-defaults/quickstart && rm -f /etc/uci-defaults/quickstart
|
||||
fi
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/quickstart.$(PKG_ARCH_quickstart) $(1)/usr/sbin/quickstart
|
||||
$(INSTALL_BIN) ./files/quickstart.init $(1)/etc/init.d/quickstart
|
||||
$(INSTALL_BIN) ./files/quickstart.uci-default $(1)/etc/uci-defaults/quickstart
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
@ -1,13 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=98
|
||||
USE_PROCD=1
|
||||
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/sbin/quickstart
|
||||
procd_set_param stderr 1
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
/etc/init.d/quickstart enable
|
||||
/etc/init.d/quickstart start
|
||||
|
||||
exit 0
|
3
feeds.conf
Normal file
3
feeds.conf
Normal file
@ -0,0 +1,3 @@
|
||||
src-git nas https://github.com/linkease/nas-packages.git;master
|
||||
src-git nas_luci https://github.com/linkease/nas-packages-luci.git;main
|
||||
src-git istore https://github.com/linkease/istore.git;official-website-mod
|
Loading…
x
Reference in New Issue
Block a user