From 375a54187db07b6f40f52f3d4c30b6e371800689 Mon Sep 17 00:00:00 2001 From: panjunlan Date: Sun, 22 Feb 2026 14:44:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=AF=E5=9C=A8config?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 168 ++++++++++++++++++--------------------------- config/config.yaml | 13 ++++ config/settings.py | 14 +++- main.py | 20 +++--- 4 files changed, 100 insertions(+), 115 deletions(-) diff --git a/README.md b/README.md index 310a165..e906e82 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,9 @@ Vmware 虚拟机自动化程序:自动化导出虚拟机和快照信息,自 ## Todo List -- [x] 连接vCenter/Esxi/Hyper-V -- [x] 获取所有 vms +- [x] Yaml 文件保存配置信息 +- [x] 通过 Yaml 文件信息连接vCenter/Esxi +- [x] 文件获取所有 vms - [x] 获取所有 snapshots - [x] 筛选出15天(半个月)前的 snapshots - [x] 以上内容以 Excel 表格的形式导出,超出 15 天的快照蓝色底填充标识 @@ -14,7 +15,7 @@ Vmware 虚拟机自动化程序:自动化导出虚拟机和快照信息,自 - [ ] 增加排除不能删除的 snapshots 信息,用红色底填充标识 - [ ] 删除快照前/后发送邮件通知 - [ ] 多线程删除(控制每台 vCenter 不可以同时删除超过 4 个快照) -- [ ] 使用数据库保存管理节点账号密码(加密) +- [ ] 改用数据库保存管理节点账号密码(加密) @@ -395,6 +396,12 @@ pip install -r requirements.txt ## 构建 Docker 镜像 +### 新建数据目录 + +``` shell +mkdir -p ~/removeweeklysnapshot/{config,logs,output} && cd ~/removeweeklysnapshot +``` + ### 安装 Docker ``` shell @@ -413,14 +420,16 @@ ENV TZ=Asia/Shanghai RUN ln -fs /usr/share/zoneinfo/$TZ /etc/localtime && dpkg-reconfigure -f noninteractive tzdata # 下载代码 ADD https://gitcode.junlan.site/junlan/RemoveWeeklyShapshot/archive/Dev.tar.gz /app/ -# 解压压缩文件 -RUN tar -xzf /app/Dev.tar.gz -C /app/ && rm /app/Dev.tar.gz +# 解压压缩文件(最后 mv 命令改名) +RUN tar -xzf /app/Dev.tar.gz -C /app/ && rm /app/Dev.tar.gz && mv /app/removeweeklyshapshot /app/removeweeklysnapshot # 设置工作目录 -WORKDIR /app/removeweeklyshapshot +WORKDIR /app/removeweeklysnapshot # 安装必要的软件和 python 库 RUN apt-get update && apt-get install procps tzdata -y && pip install -r requirements.txt && chmod +x main.py +# 添加项目根目录到 Python 路径 +ENV PYTHONPATH=/app/removeweeklysnapshot # 容器内执行启动程序 -CMD ["python3", "/app/removeweeklyshapshot/main.py"] +CMD ["python3", "/app/removeweeklysnapshot/main.py"] EOF ``` @@ -439,9 +448,9 @@ services: container_name: removeweeklysnapshot image: removeweeklysnapshot volumes: - - '/var/removeweeklysnapshot/logs:/removeweeklysnapshot/logs' - - '/var/removeweeklysnapshot/output:/removeweeklysnapshot/output' - # - '/var/removeweeklysnapshot/config/:/removeweeklysnapshot/config' + - /home/junlan/removeweeklysnapshot/logs:/app/removeweeklysnapshot/logs + - /home/junlan/removeweeklysnapshot/output:/app/removeweeklysnapshot/output + # - /home/junlan/removeweeklysnapshot/config/config.yaml:/app/removeweeklysnapshot/config/config.yaml restart: always stdin_open: true tty: true @@ -503,109 +512,66 @@ root 17 11 0 15:15 pts/1 00:00:00 ps -ef ### 修改代码进行临时测试 -> excel_output_path: /removeweeklysnapshot/output/vm_snapshots_report.xlsx # 可选,使用默认值,如:/logs/2026-02-20_14-00-21-VMsSnapShots_report.xlsx -> yaml_output_path: /removeweeklysnapshot/output/old_snapshots.yaml # 可选 -> -> ```python -> # 每周六凌晨4点导出Excel和Yaml文件 -> scheduler.add_job(export_files, 'cron', day_of_week='sat', hour=15, minute=43) # 修改时间进行测试 -> -> # 每周六晚上7点执行删除快照任务 -> scheduler.add_job(delete_old_snapshots, 'cron', day_of_week='sat', hour=15, minute=44) # 修改时间进行测试 -> ``` +- 修改 config.yaml 文件 + - ==snapshot_retention_days: 0== :定义删除多少天前的快照 + - ==schedule==:schedule 自定义改参数下定义的时间 - -``` shell -root@07c30da6408a:/removeweeklysnapshot# cat << 'EOF' > config/config.yaml +``` yaml +cat << 'EOF' > ~/removeweeklysnapshot/config/config.yaml +# 管理节点配置(包含vCenter和ESXi) management_nodes: - - type: esxi # 标记类型为esxi - name: esxi1 - host: 192.168.40.133 - user: root # ESXi默认用root - password: Root@2025 - max_delete_concurrent: 2 # ESXi性能较弱,并发数可设小些 - - - type: esxi - name: esxi2 - host: 192.168.40.135 - user: root - password: Root@2025 - max_delete_concurrent: 2 + # vCenter节点 + - type: vcenter # 标记类型为vcenter + name: vc1 # 节点名称(用于日志) + host: vcsa8.xxx.com # 地址 + user: administrator@vcsa.local + password: Root@2020 + max_delete_concurrent: 4 # 该节点最大并发删除数 +# 全局策略配置 global: disable_ssl_verify: true # ESXi连接特殊配置(禁用SSL验证,ESXi默认自签证书) snapshot_retention_days: 0 # 可选,默认值 15 天 - excel_output_path: /removeweeklysnapshot/output/vm_snapshots_report.xlsx # 可选,使用默认值,如:/logs/2026-02-20_14-00-21-VMsSnapShots_report.xlsx - yaml_output_path: /removeweeklysnapshot/output/old_snapshots.yaml # 可选 + # 定时任务配置 + schedule: + export: # 导出 Excel 和 Yaml 文件的时间 + day_of_week: 'sat' # 星期几:mon,tue,wed,thu,fri,sat,sun + hour: 6 # 小时 (0-23) + minute: 0 # 分钟 (0-59) + second: 0 # 秒 (可选) + + delete: # 删除快照的时间 + day_of_week: 'sat' + hour: 19 + minute: 0 + second: 0 EOF +================================================================================================== -root@75ce49380cc0:/removeweeklysnapshot# cat << 'EOF' > main.py -import time -from apscheduler.schedulers.background import BackgroundScheduler -from utils.logger import logger -from config.settings import YAML_OUTPUT_PATH -from core.get_vm_snapshots import get_all_vms -from core.data_exporter import create_excel_report, export_yaml -from core.remove_snapshots import load_old_snapshots, remove_snapshot - - -def export_files(): - """导出Excel和Yaml文件的函数""" - logger.info("🔍 开始收集VM和快照信息...") - vms = get_all_vms() # 主函数入口,获取虚拟机信息 - - # 导出Excel报表 - logger.info("📝 开始导出Excel报表...") - old_snapshots = create_excel_report(vms) # 生成Excel报告并获取旧快照 - - # 导出Yaml文件 - logger.info("📝 开始导出 Yaml 文件...") - export_yaml(old_snapshots) - logger.info("========== Excel和Yaml文件导出完成 ==========") - - -def delete_old_snapshots(): - """删除旧快照的函数""" - logger.info("🗑️ 开始删除过旧快照...") - old_snapshots = load_old_snapshots(YAML_OUTPUT_PATH) - remove_snapshot(old_snapshots) - logger.info("========== VM快照清理任务执行完成 ==========") - - -def main(): - """主执行函数""" - - # 设置定时任务 - scheduler = BackgroundScheduler() - - # 每周六凌晨4点导出Excel和Yaml文件 - scheduler.add_job(export_files, 'cron', day_of_week='sat', hour=15, minute=43) # 修改时间进行测试 - - # 每周六晚上7点执行删除快照任务 - scheduler.add_job(delete_old_snapshots, 'cron', day_of_week='sat', hour=15, minute=44) # 修改时间进行测试 - - scheduler.start() - - logger.info("定时任务已设置:每周六凌晨4点导出文件,晚上7点删除快照") - - try: - # 保持主程序运行,以便调度器能正常工作 - while True: - time.sleep(1) - - except (KeyboardInterrupt, SystemExit): - scheduler.shutdown() - - -if __name__ == "__main__": - main() +cat << 'EOF' > compose.yaml +services: + removeweeklysnapshot: + container_name: removeweeklysnapshot + image: removeweeklysnapshot + volumes: + - ~/removeweeklysnapshot/logs:/app/removeweeklysnapshot/logs + - ~/removeweeklysnapshot/output:/app/removeweeklysnapshot/output + - ~/removeweeklysnapshot/config/config.yaml:/app/removeweeklysnapshot/config/config.yaml + restart: always + stdin_open: true + tty: true EOF +``` -# 进入容器进行测试 -[junlan@localhost removeweeklyshapshot]$ sudo docker exec -it removeweeklysnapshot bash -root@75ce49380cc0:/removeweeklysnapshot# python main.py +#### 进入容器测试 + +手动执行 ==main.py== 运行 + +``` shell +[junlan@localhost removeweeklysnapshot]$ sudo docker exec -it removeweeklysnapshot bash +root@63869672d333:/app/removeweeklyshapshot# python main.py 2026-02-21 15:42:56,070 - INFO - ✅ 成功加载配置,共 2 个管理节点 2026-02-21 15:42:56,556 - INFO - 定时任务已设置:每周六凌晨4点导出文件,晚上7点删除快照 2026-02-21 15:43:00,000 - INFO - 🔍 开始收集VM和快照信息... diff --git a/config/config.yaml b/config/config.yaml index 9d57d1c..5324a97 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -30,3 +30,16 @@ global: # excel_output_path: ./vm_snapshots_report.xlsx # 可选,使用默认值,如:/logs/2026-02-20_14-00-21-VMsSnapShots_report.xlsx # yaml_output_path: ./yaml_snapshots_report.yaml # 可选 + # 定时任务配置 + schedule: + export: # 导出 Excel 和 Yaml 文件的时间 + day_of_week: 'sat' # 星期几:mon,tue,wed,thu,fri,sat,sun + hour: 6 # 小时 (0-23) + minute: 0 # 分钟 (0-59) + second: 0 # 秒 (可选) + + delete: # 删除快照的时间 + day_of_week: 'sat' + hour: 19 + minute: 0 + second: 0 \ No newline at end of file diff --git a/config/settings.py b/config/settings.py index e81c9e0..ac6deec 100644 --- a/config/settings.py +++ b/config/settings.py @@ -11,6 +11,12 @@ def load_config(): # 全局配置 global_config = raw_config.get('global', {}) + + # 读取定时任务配置(带默认值) + schedule_config = global_config.get('schedule', {}) + export_schedule = schedule_config.get('export', {'day_of_week': 'sat','hour': 4,'minute': 0, 'second': 0}) + delete_schedule = schedule_config.get('delete', {'day_of_week': 'sat', 'hour': 19, 'minute': 0, 'second': 0}) + config = { # vCenter/ESXi节点列表 "MANAGEMENT_NODES": raw_config.get('management_nodes', []), @@ -18,11 +24,13 @@ def load_config(): "EXCEL_OUTPUT_PATH": global_config.get('excel_output_path', os.path.join(DATA_DIR, f'vm_snapshots_report-{datetime.now().strftime('%Y-%m-%d')}.xlsx')), "YAML_OUTPUT_PATH": global_config.get('yaml_output_path', os.path.join(DATA_DIR, f'old_snapshots-{datetime.now().strftime('%Y-%m-%d')}.yaml')), "DISABLE_SSL_VERIFY": global_config.get('disable_ssl_verify', True), + "SCHEDULE_EXPORT": export_schedule, + "SCHEDULE_DELETE": delete_schedule, } # 验证配置 if not config["MANAGEMENT_NODES"]: - raise ValueError("未配置任何管理节点(vCenter 或 ESXi),只少要有一台 management_nodes 节点。") + raise ValueError("未配置任何管理节点(vCenter 或 ESXi),至少要有一台 management_nodes 节点。") # 检查每个节点的必填字段 required_fields = ['type', 'name', 'host', 'user', 'password', 'max_delete_concurrent'] @@ -54,7 +62,9 @@ SNAPSHOT_RETENTION_DAYS = config["SNAPSHOT_RETENTION_DAYS"] EXCEL_OUTPUT_PATH = config["EXCEL_OUTPUT_PATH"] YAML_OUTPUT_PATH = config["YAML_OUTPUT_PATH"] DISABLE_SSL_VERIFY = config["DISABLE_SSL_VERIFY"] - +# 调度配置 +SCHEDULE_EXPORT = config["SCHEDULE_EXPORT"] +SCHEDULE_DELETE = config["SCHEDULE_DELETE"] if __name__ == "__main__": # 打印全局配置 diff --git a/main.py b/main.py index e13db24..cd296ba 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,7 @@ import time from apscheduler.schedulers.background import BackgroundScheduler from utils.logger import logger -from config.settings import YAML_OUTPUT_PATH +from config.settings import YAML_OUTPUT_PATH,SCHEDULE_EXPORT, SCHEDULE_DELETE from core.get_vm_snapshots import get_all_vms from core.data_exporter import create_excel_report, export_yaml from core.remove_snapshots import load_old_snapshots, remove_snapshot @@ -32,19 +32,14 @@ def delete_old_snapshots(): def main(): """主执行函数""" + export_conf = SCHEDULE_EXPORT # 从配置读取导出任务时间 + delete_conf = SCHEDULE_DELETE # 从配置读取删除任务时间 - # 设置定时任务 - scheduler = BackgroundScheduler() + scheduler = BackgroundScheduler() # 设置定时任务调度器 + scheduler.start() # 开始调度器 - # 每周六凌晨4点导出Excel和Yaml文件 - scheduler.add_job(export_files, 'cron', day_of_week='sat', hour=4, minute=0) - - # 每周六晚上7点执行删除快照任务 - scheduler.add_job(delete_old_snapshots, 'cron', day_of_week='sat', hour=19, minute=0) - - scheduler.start() - - logger.info("定时任务已设置:每周六凌晨4点导出文件,晚上7点删除快照") + logger.info(f"✓ 导出任务已设置: 每周 {export_conf['day_of_week']} {export_conf['hour']:02d}:{export_conf['minute']:02d}") # :02d 数字格式化选项,用于让数字显示为至少2位,不足补零。 + logger.info(f"✓ 删除任务已设置: 每周 {delete_conf['day_of_week']} {delete_conf['hour']:02d}:{delete_conf['minute']:02d}") try: # 保持主程序运行,以便调度器能正常工作 @@ -57,3 +52,4 @@ def main(): if __name__ == "__main__": main() +