mirror of
https://github.com/cnk3x/xunlei.git
synced 2026-06-03 21:01:32 +08:00
-
This commit is contained in:
parent
dea0429297
commit
07d9228a4b
4
Makefile
4
Makefile
@ -39,3 +39,7 @@ debian:: amd64
|
||||
|
||||
test:: amd64
|
||||
wsl -d debian -- sshpass -p wan scp ./artifacts/xlp-amd64 cnk3x@192.168.99.9:~/apps/xunlei/xlp
|
||||
|
||||
xll::
|
||||
cd xll; GOOS=linux GOARCH=amd64 $(GBuild) -v -o ../artifacts/xll
|
||||
sshpass -p wan scp artifacts/xll cnk3x@192.168.99.9:~/apps/xll/xll
|
||||
|
||||
@ -44,6 +44,7 @@ words:
|
||||
- NOSUID
|
||||
- nsynobios
|
||||
- oldname
|
||||
- pgid
|
||||
- PKGDEST
|
||||
- PKGNAME
|
||||
- PKGROOT
|
||||
@ -54,6 +55,7 @@ words:
|
||||
- rootfs
|
||||
- shenzhen
|
||||
- softprops
|
||||
- sshpass
|
||||
- succ
|
||||
- SYNO
|
||||
- synobios
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6
go.sum
6
go.sum
@ -1,9 +1,3 @@
|
||||
github.com/cnk3x/flags v0.3.2 h1:zV4USqwimJmG3g5EyNV0T28VsAHd9uqYGOcOhpDXbOg=
|
||||
github.com/cnk3x/flags v0.3.2/go.mod h1:PXix1gE56E8XZA1ZBfWCGyFwZTPL4TkA3jA3D2AbrmQ=
|
||||
github.com/cnk3x/flags v0.4.1 h1:Y6cXiGLFByT4vw/PnjGZ37Io3oO9Dr8JhWT6bTdTB+M=
|
||||
github.com/cnk3x/flags v0.4.1/go.mod h1:O72yC9Pv2V98yI89VT43jcu1naG/JktM2Med/ZQ5+XE=
|
||||
github.com/cnk3x/flags v0.5.0 h1:YvXsauhC7ygXE+wJs2RwMWx+Rp+gcX3FdlNWnqNVATA=
|
||||
github.com/cnk3x/flags v0.5.0/go.mod h1:O72yC9Pv2V98yI89VT43jcu1naG/JktM2Med/ZQ5+XE=
|
||||
github.com/cnk3x/flags v0.5.1 h1:NVVjWbdMJy8vUc7kTUhbNBmt4rWlVyqKhfWIYgOvIhQ=
|
||||
github.com/cnk3x/flags v0.5.1/go.mod h1:O72yC9Pv2V98yI89VT43jcu1naG/JktM2Med/ZQ5+XE=
|
||||
github.com/go-chi/chi/v5 v5.2.4 h1:WtFKPHwlywe8Srng8j2BhOD9312j9cGUxG1SP4V2cR4=
|
||||
|
||||
32
spk/spk.go
32
spk/spk.go
@ -11,8 +11,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/cnk3x/xunlei/pkg/log"
|
||||
"github.com/cnk3x/xunlei/pkg/vms/sys"
|
||||
"github.com/ulikunitz/xz"
|
||||
)
|
||||
|
||||
@ -53,7 +51,17 @@ func Extract(ctx context.Context, src io.Reader, dstDir string) (err error) {
|
||||
return
|
||||
}()
|
||||
|
||||
slog.Log(ctx, log.ErrDebug(err), "extract package", "perm", sys.Perm2s(perm), "target_dir", dstDir, "name", h.Name, "err", err)
|
||||
msg := "extract package"
|
||||
attrs := []slog.Attr{
|
||||
slog.String("perm", perm2s(perm)),
|
||||
slog.String("target_dir", dstDir),
|
||||
slog.String("name", h.Name),
|
||||
}
|
||||
if err != nil {
|
||||
slog.LogAttrs(ctx, slog.LevelWarn, msg, append(attrs, slog.String("err", err.Error()))...)
|
||||
} else {
|
||||
slog.LogAttrs(ctx, slog.LevelDebug, msg, attrs...)
|
||||
}
|
||||
return
|
||||
}, Xz), io.EOF)
|
||||
}
|
||||
@ -99,3 +107,21 @@ func Xz(src io.Reader) (io.ReadCloser, error) {
|
||||
type Decoder func(io.Reader) (io.ReadCloser, error)
|
||||
|
||||
type WalkFunc func(r io.Reader, h *tar.Header) (err error)
|
||||
|
||||
func HasExt(name string, exts ...string) bool {
|
||||
for _, ext := range exts {
|
||||
if len(name) >= len(ext) && strings.EqualFold(name[len(name)-len(ext):], ext) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func StartWith(name string, prefixes ...string) bool {
|
||||
for _, prefix := range prefixes {
|
||||
if len(name) >= len(prefix) && strings.EqualFold(name[:len(prefix)], prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
40
spk/url.go
40
spk/url.go
@ -10,30 +10,22 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cnk3x/xunlei/pkg/fo"
|
||||
"github.com/cnk3x/xunlei/pkg/utils"
|
||||
"github.com/cnk3x/xunlei/pkg/vms/sys"
|
||||
)
|
||||
|
||||
var DownloadUrl = utils.Iif(runtime.GOARCH == "amd64",
|
||||
"https://down.sandai.net/nas/nasxunlei-DSM7-x86_64.spk",
|
||||
"https://down.sandai.net/nas/nasxunlei-DSM7-armv8.spk",
|
||||
)
|
||||
|
||||
// 检查并下载, 如果 force,忽略检查直接下载
|
||||
func Download(ctx context.Context, spkUrl string, dir string, force bool) (err error) {
|
||||
if !force && allExists(ctx, dir) {
|
||||
slog.InfoContext(ctx, "check spk all spk file exists")
|
||||
if !force && allExists(dir) {
|
||||
slog.Info("check spk all spk file exists")
|
||||
return
|
||||
}
|
||||
|
||||
switch {
|
||||
case utils.HasPrefix(spkUrl, "file://", true):
|
||||
case StartWith(spkUrl, "file://"):
|
||||
err = download_file(ctx, spkUrl, dir)
|
||||
case utils.HasPrefix(spkUrl, "http://", true) || utils.HasPrefix(spkUrl, "https://", true):
|
||||
case StartWith(spkUrl, "http://", "https://"):
|
||||
err = download_http(ctx, spkUrl, dir)
|
||||
default:
|
||||
err = fmt.Errorf("spk url is not support: %s", spkUrl)
|
||||
@ -43,7 +35,7 @@ func Download(ctx context.Context, spkUrl string, dir string, force bool) (err e
|
||||
|
||||
func download_file(ctx context.Context, spkUrl string, dir string) (err error) {
|
||||
spkUrl = strings.TrimPrefix(spkUrl, "file://")
|
||||
slog.InfoContext(ctx, "download spk file", "url", spkUrl)
|
||||
slog.Info("download spk file", "url", spkUrl)
|
||||
f, e := os.Open(spkUrl)
|
||||
if err = e; err != nil {
|
||||
return
|
||||
@ -55,7 +47,7 @@ func download_file(ctx context.Context, spkUrl string, dir string) (err error) {
|
||||
}
|
||||
|
||||
func download_http(ctx context.Context, spkUrl string, dir string) (err error) {
|
||||
slog.InfoContext(ctx, "download spk file", "url", spkUrl)
|
||||
slog.Info("download spk file", "url", spkUrl)
|
||||
var req *http.Request
|
||||
if req, err = http.NewRequestWithContext(ctx, http.MethodGet, spkUrl, nil); err != nil {
|
||||
return
|
||||
@ -91,7 +83,7 @@ func download_http(ctx context.Context, spkUrl string, dir string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func allExists(ctx context.Context, dir string) bool {
|
||||
func allExists(dir string) bool {
|
||||
files := []string{
|
||||
filepath.Join(dir, "bin/bin/version"),
|
||||
filepath.Join(dir, "bin/bin/xunlei-pan-cli-launcher.{arch}"),
|
||||
@ -99,22 +91,28 @@ func allExists(ctx context.Context, dir string) bool {
|
||||
filepath.Join(dir, "ui/index.cgi"),
|
||||
}
|
||||
|
||||
version := fo.Cat(files[0], true)
|
||||
d, _ := os.ReadFile(files[0])
|
||||
version := strings.TrimSpace(string(d))
|
||||
if version == "" {
|
||||
slog.DebugContext(ctx, "check spk fail, version not found")
|
||||
slog.Debug("check spk fail, version not found")
|
||||
return false
|
||||
}
|
||||
slog.DebugContext(ctx, "check spk", "version", version)
|
||||
slog.Debug("check spk", "version", version)
|
||||
|
||||
repl := strings.NewReplacer("{arch}", runtime.GOARCH, "{version}", version)
|
||||
for _, f := range files[1:] {
|
||||
f = repl.Replace(f)
|
||||
stat, err := os.Stat(f)
|
||||
if err != nil || !stat.Mode().IsRegular() {
|
||||
slog.DebugContext(ctx, "check spk fail", "file", f, "err", err)
|
||||
slog.Debug("check spk fail", "file", f, "err", err)
|
||||
return false
|
||||
}
|
||||
slog.DebugContext(ctx, "check spk", "perm", sys.Perm2s(stat.Mode()), "size", utils.HumanBytes(stat.Size()), "modtime", stat.ModTime(), "file", f)
|
||||
slog.Debug("check spk", "perm", perm2s(stat.Mode()), "modtime", stat.ModTime(), "file", f)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func perm2s(perm os.FileMode) string {
|
||||
// return fmt.Sprintf("%s(0%s)", perm.Perm().String(), strconv.FormatInt(int64(perm.Perm()), 8))
|
||||
return "0" + strconv.FormatInt(int64(perm.Perm()), 8)
|
||||
}
|
||||
|
||||
22
xlp.go
22
xlp.go
@ -6,7 +6,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
"github.com/cnk3x/xunlei/pkg/log"
|
||||
"github.com/cnk3x/xunlei/pkg/vms"
|
||||
@ -141,24 +140,3 @@ func mockEnv(dirData, dirDownload string) []string {
|
||||
// "LD_LIBRARY_PATH=/lib"+utils.Iif(ld_lib == "", "", ":")+ld_lib,
|
||||
)
|
||||
}
|
||||
|
||||
// NewnsRun 在unshare后执行 fn,执行完成后恢复
|
||||
//
|
||||
// 参数:
|
||||
// - ctx: 上下文
|
||||
// - fn: 要在新命名空间中执行的函数
|
||||
func NewnsRun(ctx context.Context, fn func()) {
|
||||
// 创建新的挂载命名空间、PID命名空间和UTS命名空间
|
||||
syscall.Unshare(syscall.CLONE_NEWNS | syscall.CLONE_NEWPID | syscall.CLONE_NEWUTS)
|
||||
// 设置根目录为私有挂载,防止影响父命名空间
|
||||
syscall.Mount("", "/", "", syscall.MS_PRIVATE|syscall.MS_REC, "")
|
||||
// 挂载新的proc文件系统
|
||||
syscall.Mount("none", "/proc", "proc", syscall.MS_NOSUID|syscall.MS_NOEXEC|syscall.MS_NODEV, "")
|
||||
// 执行指定函数
|
||||
fn()
|
||||
// 清理操作:卸载挂载的proc文件系统
|
||||
syscall.Unmount("/proc", syscall.MNT_DETACH)
|
||||
// 注意:由于CLONE_NEWPID的存在,子进程退出后会自动清理PID命名空间
|
||||
// 挂载命名空间会在进程结束时自动恢复到原始状态
|
||||
// 但由于我们设置了MS_PRIVATE,所以不会影响原始挂载树
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/cnk3x/xunlei/pkg/utils"
|
||||
"github.com/cnk3x/xunlei/spk"
|
||||
)
|
||||
|
||||
func Banner(fPrint func(string)) {
|
||||
@ -55,7 +54,7 @@ func ConfigCheck(cfg *Config) (err error) {
|
||||
|
||||
//设置默认值
|
||||
cfg.DashboardPort = cmp.Or(cfg.DashboardPort, 2345) //端口默认2345
|
||||
cfg.SpkUrl = cmp.Or(cfg.SpkUrl, spk.DownloadUrl) //下载链接
|
||||
cfg.SpkUrl = cmp.Or(cfg.SpkUrl, SPK_URL) //下载链接
|
||||
|
||||
cfg.Root = cmp.Or(cfg.Root, "xunlei") //根目录默认 ./xunlei
|
||||
cfg.DirData = cmp.Or(cfg.DirData, filepath.Join(cfg.Root, "data")) //数据默认 ${root}/data
|
||||
|
||||
@ -3,4 +3,5 @@ package xunlei
|
||||
const (
|
||||
SYNO_PLATFORM = "geminilake"
|
||||
SYNO_MODEL = "DS920+"
|
||||
SPK_URL = "https://down.sandai.net/nas/nasxunlei-DSM7-x86_64.spk"
|
||||
)
|
||||
|
||||
@ -3,4 +3,5 @@ package xunlei
|
||||
const (
|
||||
SYNO_PLATFORM = "rtd1296"
|
||||
SYNO_MODEL = "DS220j"
|
||||
SPK_URL = "https://down.sandai.net/nas/nasxunlei-DSM7-armv8.spk"
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user