diff --git a/Docker/Dockerfile/Drone-Images/Dockerfile-minio b/Docker/Dockerfile/Drone-Images/Dockerfile-mc similarity index 100% rename from Docker/Dockerfile/Drone-Images/Dockerfile-minio rename to Docker/Dockerfile/Drone-Images/Dockerfile-mc diff --git a/Docker/Dockerfile/Drone-Images/README.md b/Docker/Dockerfile/Drone-Images/README.md index 52831b3..e3862e5 100644 --- a/Docker/Dockerfile/Drone-Images/README.md +++ b/Docker/Dockerfile/Drone-Images/README.md @@ -6,9 +6,9 @@ > Dockerfile示例 -| 文件名 | 镜像功能 | 构建示例 | -| :--------------: | :-------------------------: | :-----------------------------------------------: | -| Dockerfile-git | 最小化 Git 容器 | docker build -t 镜像名:标签 -f Dockerfile-git . | -| Dockerfile-minio | 容器内自带 Minio 客户端命令 | docker build -t 镜像名:标签 -f Dockerfile-minio . | -| Dockerfile-oss | 容器内自带 oss 客户端命令 | docker build -t 镜像名:标签 -f Dockerfile-oss . | +| 文件名 | 镜像功能 | 构建示例 | +| :------------: | :-----------------------: | :---------------------------------------------: | +| Dockerfile-git | 最小化 Git 容器 | docker build -t 镜像名:标签 -f Dockerfile-git . | +| Dockerfile-mc | 容器内自带 S3 客户端命令 | docker build -t 镜像名:标签 -f Dockerfile-mc . | +| Dockerfile-oss | 容器内自带 oss 客户端命令 | docker build -t 镜像名:标签 -f Dockerfile-oss . | diff --git a/File/Python/clean-gitea-user-concurrency.py b/File/Python/clean-gitea-user-concurrency.py new file mode 100644 index 0000000..6e7dccb --- /dev/null +++ b/File/Python/clean-gitea-user-concurrency.py @@ -0,0 +1,101 @@ +import requests +import argparse +import time +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry +from concurrent.futures import ThreadPoolExecutor, as_completed + +# 使用方法: python clean-gitea-user.py --keep-users admin user1 --gitea-url http://gitea.example.com --api-token your_token + +# 解析命令行参数 +parser = argparse.ArgumentParser(description='清理 Gitea 用户和仓库,保留指定的用户及其仓库。') +parser.add_argument('--keep-users', nargs='+', required=True, help='要保留的用户列表,例如 --keep-users user1 user2') +parser.add_argument('--gitea-url', required=True, help='Gitea 服务器的 URL,例如 http://localhost:3000') +parser.add_argument('--api-token', required=True, help='Gitea API Token') + +args = parser.parse_args() + +# Gitea服务器 URL 和 API 访问 token +gitea_url = args.gitea_url +api_token = args.api_token + +# 获取所有用户的API请求 +users_api = f'{gitea_url}/api/v1/admin/users' # 获取所有用户的 API URL +headers = { + 'Authorization': f'token {api_token}' # 设置认证头,使用 API Token +} + +# 创建带有重试机制的会话 +session = requests.Session() +retry = Retry(total=5, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504]) +adapter = HTTPAdapter(max_retries=retry) +session.mount('http://', adapter) +session.mount('https://', adapter) + +# 删除指定用户的仓库(并发版本) +def delete_user_repositories(username): + """ + 获取并删除指定用户的所有仓库。 + :param username: 用户名 + """ + # 获取用户的仓库 + repos_api = f'{gitea_url}/api/v1/users/{username}/repos' # 用户仓库 API URL + response = session.get(repos_api, headers=headers) + + if response.status_code == 200: + repos = response.json() + with ThreadPoolExecutor(max_workers=5) as executor: # 并发删除仓库 + futures = [] + for repo in repos: + repo_name = repo['name'] + futures.append(executor.submit(delete_single_repo, username, repo_name)) + for future in as_completed(futures): + try: + future.result() + except Exception as e: + print(f'Error deleting repo: {e}') + else: + print(f'Failed to fetch repositories for {username}. Status code: {response.status_code}') + +def delete_single_repo(username, repo_name): + delete_repo_api = f'{gitea_url}/api/v1/repos/{username}/{repo_name}' + delete_response = session.delete(delete_repo_api, headers=headers) + if delete_response.status_code == 204: + print(f'Repository {repo_name} deleted successfully.') + else: + print(f'Failed to delete repository {repo_name}. Status: {delete_response.status_code}') + time.sleep(0.1) # 减少延迟 + +# 删除用户 +def delete_user(username): + delete_user_api = f'{gitea_url}/api/v1/admin/users/{username}' + delete_response = session.delete(delete_user_api, headers=headers) + if delete_response.status_code == 204: + print(f'User {username} deleted successfully.') + else: + print(f'Failed to delete user {username}. Status: {delete_response.status_code}') + time.sleep(0.1) + +# 获取所有用户并删除除指定用户外的用户及其仓库 +response = session.get(users_api, headers=headers) + +if response.status_code == 200: + users = response.json() + with ThreadPoolExecutor(max_workers=3) as executor: # 并发处理用户 + futures = [] + for user in users: + username = user['username'] + if username not in args.keep_users: + print(f'Processing user: {username}') + # 先删除仓库,再删除用户 + delete_user_repositories(username) + futures.append(executor.submit(delete_user, username)) + else: + print(f'User {username} is being kept.') + for future in as_completed(futures): + try: + future.result() + except Exception as e: + print(f'Error deleting user: {e}') +else: + print('Failed to fetch users. Status code:', response.status_code) \ No newline at end of file diff --git a/File/Python/clean-gitea-user.py b/File/Python/clean-gitea-user.py new file mode 100644 index 0000000..874c1df --- /dev/null +++ b/File/Python/clean-gitea-user.py @@ -0,0 +1,82 @@ +import requests +import argparse +import time +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry + +# 使用方法: python clean-gitea-user.py --keep-users admin user1 --gitea-url http://gitea.example.com --api-token your_token + +# 解析命令行参数 +parser = argparse.ArgumentParser(description='清理 Gitea 用户和仓库,保留指定的用户及其仓库。') +parser.add_argument('--keep-users', nargs='+', required=True, help='要保留的用户列表,例如 --keep-users user1 user2') +parser.add_argument('--gitea-url', required=True, help='Gitea 服务器的 URL,例如 http://localhost:3000') +parser.add_argument('--api-token', required=True, help='Gitea API Token') + +args = parser.parse_args() + +# Gitea服务器 URL 和 API 访问 token +gitea_url = args.gitea_url +api_token = args.api_token + +# 获取所有用户的API请求 +users_api = f'{gitea_url}/api/v1/admin/users' # 获取所有用户的 API URL +headers = { + 'Authorization': f'token {api_token}' # 设置认证头,使用 API Token +} + +# 创建带有重试机制的会话 +session = requests.Session() +retry = Retry(total=5, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504]) +adapter = HTTPAdapter(max_retries=retry) +session.mount('http://', adapter) +session.mount('https://', adapter) + +# 删除指定用户的仓库 +def delete_user_repositories(username): + """ + 获取并删除指定用户的所有仓库。 + :param username: 用户名 + """ + # 获取用户的仓库 + repos_api = f'{gitea_url}/api/v1/users/{username}/repos' # 用户仓库 API URL + response = session.get(repos_api, headers=headers) + + if response.status_code == 200: + # 如果请求成功,遍历该用户的所有仓库 + repos = response.json() + for repo in repos: + repo_name = repo['name'] # 获取仓库的名字 + # 删除仓库 + delete_repo_api = f'{gitea_url}/api/v1/repos/{username}/{repo_name}' # 删除仓库的 API URL + delete_response = session.delete(delete_repo_api, headers=headers) + if delete_response.status_code == 204: + print(f'Repository {repo_name} deleted successfully.') + else: + print(f'Failed to delete repository {repo_name}.') # 删除仓库失败 + time.sleep(0.5) # 添加延迟以避免速率限制 + else: + print(f'Failed to fetch repositories for {username}. Status code:', response.status_code) # 请求仓库失败 + +# 获取所有用户并删除除指定用户外的用户及其仓库 +response = session.get(users_api, headers=headers) # 获取所有用户 + +if response.status_code == 200: + users = response.json() # 将响应的 JSON 数据转换为 Python 对象 + for user in users: + username = user['username'] # 获取用户名 + if username not in args.keep_users: # 如果用户不在保留列表中 + print(f'Processing user: {username}') + # 先删除该用户的仓库 + delete_user_repositories(username) # 删除仓库 + # 然后删除用户 + delete_user_api = f'{gitea_url}/api/v1/admin/users/{username}' # 删除用户的 API URL + delete_response = session.delete(delete_user_api, headers=headers) + if delete_response.status_code == 204: + print(f'User {username} deleted successfully.') + else: + print(f'Failed to delete user {username}. Status code: {delete_response.status_code}') # 删除用户失败 + time.sleep(0.5) # 添加延迟以避免速率限制 + else: + print(f'User {username} is being kept.') # 用户被保留 +else: + print('Failed to fetch users. Status code:', response.status_code) # 获取用户失败 \ No newline at end of file diff --git a/Helm/Helm部署Gitea.md b/Helm/Helm部署Gitea.md index d1dab6d..515788d 100644 --- a/Helm/Helm部署Gitea.md +++ b/Helm/Helm部署Gitea.md @@ -9,7 +9,7 @@ ## 开始部署 -[Chart仓库](https://dl.gitea.com/charts/) +[Chart文件下载](https://dl.gitea.com/charts/) [官方仓库](https://gitea.com/gitea/helm-gitea/src/branch/main/values.yaml) 1. 添加 Helm 仓库 @@ -89,6 +89,14 @@ DOMAIN: "gitea.com" SSH_LISTEN_PORT: "22" SSH_PORT: "30000" + # https://docs.gitea.com/zh-cn/administration/config-cheat-sheet#service-service + service: # 别问我为什么要加上这些 + # 禁用注册,启用后只能用管理员添加用户 + DISABLE_REGISTRATION: false + # 启用此项以对注册使用验证码验证 + ENABLE_CAPTCHA: true + # 启用此项以要求登录使用验证码验证,您还必须启用 ENABLE_CAPTCHA + REQUIRE_CAPTCHA_FOR_LOGIN: true # 关闭 redis 集群 redis-cluster: @@ -129,4 +137,34 @@ kubectl delete namespace gitea ``` - + +## 批量清理用户和仓库 + +1. 下载脚本 + + - 普通删除 + + ```bash + wget https://gitee.com/offends/Kubernetes/raw/main/File/Python/clean-gitea-user.py + ``` + + - 并发删除(具有速度优势但需要根据自己服务器资源调整 `max_workers` 参数) + + ```bash + wget https://gitee.com/offends/Kubernetes/raw/main/File/Python/clean-gitea-user-concurrency.py + ``` + +2. 指定参数并运行 + + ```bash + python clean-gitea-user.py --keep-users user1 user2 --gitea-url http://gitea.example.com --api-token your_token + ``` + + **参数解释** + + `--gitea-url`:指定 Gitea 访问地址 + + `--api-token`:指定应用 Access Token + + `--keep-users`:指定不想删除仓库的用户 + diff --git a/Helm/Helm部署Minio替代品RustFS.md b/Helm/Helm部署Minio替代品RustFS.md index 2b6ef91..8d0ffc2 100644 --- a/Helm/Helm部署Minio替代品RustFS.md +++ b/Helm/Helm部署Minio替代品RustFS.md @@ -97,4 +97,10 @@ kubectl delete pvc -n rustfs --all ``` - \ No newline at end of file + +## 数据迁移工具 + +数据迁移实现 Minio > RustFS + +- [Rclone官网](https://rclone.org/) +- [Mc官网](https://github.com/minio/mc) \ No newline at end of file