Compare commits

..
2 Commits
3 changed files with 85 additions and 10 deletions
+6 -5
View File
@@ -20,20 +20,21 @@ jobs:
retry_wait_seconds: 15 retry_wait_seconds: 15
shell: python shell: python
command: | command: |
import requests
import json import json
import time import time
import urllib.request
input_data = json.loads('${{ inputs.zip_url_json }}') input_data = json.loads('${{ inputs.zip_url_json }}')
url = f"{input_data['url']}/get_zip?filename={input_data['file']}" url = f"{input_data['url']}/get_zip?filename={input_data['file']}"
for attempt in range(5): for attempt in range(5):
try: try:
print(f"Downloading (Attempt {attempt + 1})...") print(f"Downloading (Attempt {attempt + 1})...")
r = requests.get(url, timeout=20) # 仅使用标准库(urllib),兼容未预装 requests 的自建 runner 容器
r.raise_for_status() with urllib.request.urlopen(url, timeout=20) as r:
content = r.read()
with open('secrets.zip', 'wb') as f: with open('secrets.zip', 'wb') as f:
f.write(r.content) f.write(content)
break break
except Exception as e: except Exception as e:
if attempt < 4: if attempt < 4:
@@ -19,20 +19,21 @@ jobs:
retry_wait_seconds: 15 retry_wait_seconds: 15
shell: python shell: python
command: | command: |
import requests
import json import json
import time import time
import urllib.request
input_data = json.loads('${{ inputs.zip_url_json }}') input_data = json.loads('${{ inputs.zip_url_json }}')
url = f"{input_data['url']}/get_zip?filename={input_data['file']}" url = f"{input_data['url']}/get_zip?filename={input_data['file']}"
for attempt in range(5): for attempt in range(5):
try: try:
print(f"Downloading (Attempt {attempt + 1})...") print(f"Downloading (Attempt {attempt + 1})...")
r = requests.get(url, timeout=20) # 仅使用标准库(urllib),无需预装 requests,兼容各类 runner 环境
r.raise_for_status() with urllib.request.urlopen(url, timeout=20) as r:
content = r.read()
with open('secrets.zip', 'wb') as f: with open('secrets.zip', 'wb') as f:
f.write(r.content) f.write(content)
break break
except Exception as e: except Exception as e:
if attempt < 4: if attempt < 4:
+73
View File
@@ -29,3 +29,76 @@ Gitea 1.27+ and your own registered `act_runner` machines. Full setup: [setup.md
- Avoid special characters or non-English characters in app name and file name - Avoid special characters or non-English characters in app name and file name
- Build time is currently 30 - 45 minutes - Build time is currently 30 - 45 minutes
---
# 功能说明(中文)
RDGen 是一个基于 **Django + Docker** 的 RustDesk 客户端在线定制平台:用户在网页上填表选择版本、服务器、图标和各类高级选项,平台自动触发 CI(GitHub Actions 或自建 Gitea Actions)编译出专属客户端,并在构建完成后回收安装包供下载。支持多用户、任务管理、配置方案复用和开放 JSON API。
## 一、客户端定制功能
- **内置服务器信息**:预置 ID/中继服务器地址、端口、公钥(Key)、API 服务器地址,客户端开箱即连自建服务器
- **品牌定制**:自定义应用名称、可执行文件名、应用图标、界面 Logo、隐私声明页图片(建议 256×256 方形图标)
- **下载/文档链接**:可配置官网链接、下载链接、关于页链接,以及安卓包名(Android applicationId)
- **默认行为**:设置默认连接方向(接收/发起/双向)、是否显示安装程序、是否开放设置入口、浅色/深色/跟随系统主题
- **安全策略**:预设永久访问密码、密码审批方式(仅密码/仅点击/两者)、是否禁止局域网发现、是否允许 IP 直连、无操作自动断开
- **权限矩阵**:可逐项开关被控端的键鼠控制、剪贴板、文件传输、音频、TCP 隧道、远程重启、会话录制、屏蔽输入、远程改配置、打印机、摄像头、终端、移除壁纸等
- **高级设置**:修复第三方 API 延迟、离线设备标记、隐藏连接窗口、移除新版本通知、自定义默认/覆盖手册文案等,覆盖 RustDesk 官方 advanced settings 全部常用项
- **版本选择**:版本下拉自动跟随 `rustdesk/rustdesk` 官方 tags 更新(缓存 6 小时),网络不可用时回退内置版本列表,也支持手动指定 master/main
## 二、构建产物(目标平台)
一次构建可产出对应平台的多份安装包,构建耗时约 30~45 分钟:
- **Windows 64 位**:`.exe` 便携版 + `.msi` 安装版
- **Windows 32 位**:`.exe`
- **Linux**:deb / rpm / suse-rpm / pkg.tar.zst / AppImage / flatpak,含 x86_64 与 aarch64
- **Android**:aarch64(主流)、x86_64、armv7 三份 `.apk`
- **macOS**:Intel(x86_64)与 Apple 芯片(aarch64)两份 `.dmg`
## 三、双构建平台可切换
- 支持 **GitHub Actions**(云托管 Windows/macOS/Linux 构建机)与 **Gitea Actions**(自建、可全内网运行)两种后端
- 后台「构建平台配置」页一键切换(或环境变量 `BUILD_PLATFORM=github|gitea`),切换后新任务走新平台,**历史任务仍按原平台查询状态和跳转日志**
- Gitea 模式可独立配置服务器地址、属主、仓库、分支、令牌、代理,需 Gitea ≥ 1.23(建议 1.27+)并自行注册 act_runner(Linux/Windows/macOS 标签机)
- 后台提供「测试连接」按钮,即时验证令牌、仓库、Actions 权限和版本兼容性;配置缺失时顶部显示中文告警
- 触发参数以 AES 加密 ZIP 包传递给工作流(`ZIP_PASSWORD`),回调支持 `X-Webhook-Secret` 请求头签名校验(留空则兼容旧工作流)
## 四、构建任务管理
- 提交后进入构建进度页,页面每 30 秒自动轮询,状态含排队中/构建中/成功/失败/取消/超时等,中文状态徽章实时展示
- 「我的构建」列表:查看本人全部任务、目标平台、**构建平台徽章(GitHub 深色 / Gitea 绿色)**、状态、编号
- 任务详情(构建中/失败/成功三页)均标明构建平台,并提供对应平台的一键日志跳转链接
- 失败/终态任务可用原始配置快照**一键重试**,也可删除任务(同时清理服务器上的安装包产物)
- 构建产物经 CI 加密回传,页面按平台列出所有可下载文件,下载链接带 UUID 鉴权
## 五、用户、权限与配置方案
- 账号登录制,普通用户只能看到和操作自己的任务;管理员(is_staff)可访问后台、查看全部任务
- 管理员后台可新建/编辑用户:启停账号、授予/撤销管理员、重置密码
- **配置方案**:常用定制参数可保存为方案(与账号绑定),定制页一键载入,支持导出 JSON、查看方案数据和删除
- **API 令牌**:用户可创建命名个人令牌(记录最后使用时间、可停用/删除),用于命令行或第三方系统调用
## 六、开放 JSON API
- `POST /api/generate`:以 JSON 提交与网页表单完全等价的定制参数,通过 `Authorization: Token <key>` 认证,自动触发构建
- `GET /api/status`:按 UUID 查询构建状态与日志链接
- 兼容第三方自建 RustDesk API 服务的 `/startgh`、`/save_custom_client`、`/updategh` 等无会话回调端点(可选 Webhook 密钥校验)
- 可配合 [rdgen-cli](https://github.com/AlekseyLapunov/rdgen-cli) 在 Windows/Linux/macOS 命令行直接发起构建
## 七、后台运维能力
- **管理仪表盘**:任务总数、进行中、成功、失败、用户数、有效令牌数等统计,最近 100 条任务总览,可直接删除任务
- **站点配置存储**:后台配置 → 环境变量 → 默认值三级优先级,所有密钥类字段密文存储、可单独清除,无需改环境变量即可在线调整
- **定时维护**:容器内置维护守护进程(每小时巡检),按保留天数自动清理过期任务及产物、清理临时加密包;可在后台「维护设置」调整或「立即执行」
- **数据库备份**:SQLite 在线备份,默认每日一份、保留 7 份(可配 1~100),后台可下载备份文件
- **健康检查**:`/healthz/` 供容器编排探活
- **网络适配**:GitHub/Gitea 后端可分别配置 HTTP/SOCKS5 代理,适配内网通过代理出网或 Gitea 内网直连的混合环境
## 八、部署方式
- 一条 `docker compose up -d` 完成部署:Gunicorn 托管 Django,自动执行数据库迁移与静态文件收集,并启动维护守护进程
- 数据库(账号、任务记录、配置方案、站点设置)保存在独立命名卷 `rdgen-data`,重建镜像不丢数据;安装包/图片/临时文件走宿主机绑定挂载
- 首次启动按环境变量自动创建初始管理员;详细部署、Fork 仓库、Secrets 配置、Gitea act_runner 注册见 [setup.md](setup.md)