修改可在config文件自定义运行时间
This commit is contained in:
168
README.md
168
README.md
@@ -4,8 +4,9 @@ Vmware 虚拟机自动化程序:自动化导出虚拟机和快照信息,自
|
|||||||
|
|
||||||
## Todo List
|
## Todo List
|
||||||
|
|
||||||
- [x] 连接vCenter/Esxi/Hyper-V
|
- [x] Yaml 文件保存配置信息
|
||||||
- [x] 获取所有 vms
|
- [x] 通过 Yaml 文件信息连接vCenter/Esxi
|
||||||
|
- [x] 文件获取所有 vms
|
||||||
- [x] 获取所有 snapshots
|
- [x] 获取所有 snapshots
|
||||||
- [x] 筛选出15天(半个月)前的 snapshots
|
- [x] 筛选出15天(半个月)前的 snapshots
|
||||||
- [x] 以上内容以 Excel 表格的形式导出,超出 15 天的快照蓝色底填充标识
|
- [x] 以上内容以 Excel 表格的形式导出,超出 15 天的快照蓝色底填充标识
|
||||||
@@ -14,7 +15,7 @@ Vmware 虚拟机自动化程序:自动化导出虚拟机和快照信息,自
|
|||||||
- [ ] 增加排除不能删除的 snapshots 信息,用红色底填充标识
|
- [ ] 增加排除不能删除的 snapshots 信息,用红色底填充标识
|
||||||
- [ ] 删除快照前/后发送邮件通知
|
- [ ] 删除快照前/后发送邮件通知
|
||||||
- [ ] 多线程删除(控制每台 vCenter 不可以同时删除超过 4 个快照)
|
- [ ] 多线程删除(控制每台 vCenter 不可以同时删除超过 4 个快照)
|
||||||
- [ ] 使用数据库保存管理节点账号密码(加密)
|
- [ ] 改用数据库保存管理节点账号密码(加密)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -395,6 +396,12 @@ pip install -r requirements.txt
|
|||||||
|
|
||||||
## 构建 Docker 镜像
|
## 构建 Docker 镜像
|
||||||
|
|
||||||
|
### 新建数据目录
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
mkdir -p ~/removeweeklysnapshot/{config,logs,output} && cd ~/removeweeklysnapshot
|
||||||
|
```
|
||||||
|
|
||||||
### 安装 Docker
|
### 安装 Docker
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
@@ -413,14 +420,16 @@ ENV TZ=Asia/Shanghai
|
|||||||
RUN ln -fs /usr/share/zoneinfo/$TZ /etc/localtime && dpkg-reconfigure -f noninteractive tzdata
|
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/
|
ADD https://gitcode.junlan.site/junlan/RemoveWeeklyShapshot/archive/Dev.tar.gz /app/
|
||||||
# 解压压缩文件
|
# 解压压缩文件(最后 mv 命令改名)
|
||||||
RUN tar -xzf /app/Dev.tar.gz -C /app/ && rm /app/Dev.tar.gz
|
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 库
|
# 安装必要的软件和 python 库
|
||||||
RUN apt-get update && apt-get install procps tzdata -y && pip install -r requirements.txt && chmod +x main.py
|
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
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -439,9 +448,9 @@ services:
|
|||||||
container_name: removeweeklysnapshot
|
container_name: removeweeklysnapshot
|
||||||
image: removeweeklysnapshot
|
image: removeweeklysnapshot
|
||||||
volumes:
|
volumes:
|
||||||
- '/var/removeweeklysnapshot/logs:/removeweeklysnapshot/logs'
|
- /home/junlan/removeweeklysnapshot/logs:/app/removeweeklysnapshot/logs
|
||||||
- '/var/removeweeklysnapshot/output:/removeweeklysnapshot/output'
|
- /home/junlan/removeweeklysnapshot/output:/app/removeweeklysnapshot/output
|
||||||
# - '/var/removeweeklysnapshot/config/:/removeweeklysnapshot/config'
|
# - /home/junlan/removeweeklysnapshot/config/config.yaml:/app/removeweeklysnapshot/config/config.yaml
|
||||||
restart: always
|
restart: always
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
tty: 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
|
- 修改 config.yaml 文件
|
||||||
> yaml_output_path: /removeweeklysnapshot/output/old_snapshots.yaml # 可选
|
- ==snapshot_retention_days: 0== :定义删除多少天前的快照
|
||||||
>
|
- ==schedule==:schedule 自定义改参数下定义的时间
|
||||||
> ```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) # 修改时间进行测试
|
|
||||||
> ```
|
|
||||||
|
|
||||||
|
|
||||||
|
``` yaml
|
||||||
``` shell
|
cat << 'EOF' > ~/removeweeklysnapshot/config/config.yaml
|
||||||
root@07c30da6408a:/removeweeklysnapshot# cat << 'EOF' > config/config.yaml
|
# 管理节点配置(包含vCenter和ESXi)
|
||||||
management_nodes:
|
management_nodes:
|
||||||
- type: esxi # 标记类型为esxi
|
# vCenter节点
|
||||||
name: esxi1
|
- type: vcenter # 标记类型为vcenter
|
||||||
host: 192.168.40.133
|
name: vc1 # 节点名称(用于日志)
|
||||||
user: root # ESXi默认用root
|
host: vcsa8.xxx.com # 地址
|
||||||
password: Root@2025
|
user: administrator@vcsa.local
|
||||||
max_delete_concurrent: 2 # ESXi性能较弱,并发数可设小些
|
password: Root@2020
|
||||||
|
max_delete_concurrent: 4 # 该节点最大并发删除数
|
||||||
- type: esxi
|
|
||||||
name: esxi2
|
|
||||||
host: 192.168.40.135
|
|
||||||
user: root
|
|
||||||
password: Root@2025
|
|
||||||
max_delete_concurrent: 2
|
|
||||||
|
|
||||||
|
# 全局策略配置
|
||||||
global:
|
global:
|
||||||
disable_ssl_verify: true # ESXi连接特殊配置(禁用SSL验证,ESXi默认自签证书)
|
disable_ssl_verify: true # ESXi连接特殊配置(禁用SSL验证,ESXi默认自签证书)
|
||||||
snapshot_retention_days: 0 # 可选,默认值 15 天
|
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
|
EOF
|
||||||
|
|
||||||
|
==================================================================================================
|
||||||
|
|
||||||
root@75ce49380cc0:/removeweeklysnapshot# cat << 'EOF' > main.py
|
cat << 'EOF' > compose.yaml
|
||||||
import time
|
services:
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
removeweeklysnapshot:
|
||||||
from utils.logger import logger
|
container_name: removeweeklysnapshot
|
||||||
from config.settings import YAML_OUTPUT_PATH
|
image: removeweeklysnapshot
|
||||||
from core.get_vm_snapshots import get_all_vms
|
volumes:
|
||||||
from core.data_exporter import create_excel_report, export_yaml
|
- ~/removeweeklysnapshot/logs:/app/removeweeklysnapshot/logs
|
||||||
from core.remove_snapshots import load_old_snapshots, remove_snapshot
|
- ~/removeweeklysnapshot/output:/app/removeweeklysnapshot/output
|
||||||
|
- ~/removeweeklysnapshot/config/config.yaml:/app/removeweeklysnapshot/config/config.yaml
|
||||||
|
restart: always
|
||||||
def export_files():
|
stdin_open: true
|
||||||
"""导出Excel和Yaml文件的函数"""
|
tty: true
|
||||||
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()
|
|
||||||
EOF
|
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,070 - INFO - ✅ 成功加载配置,共 2 个管理节点
|
||||||
2026-02-21 15:42:56,556 - INFO - 定时任务已设置:每周六凌晨4点导出文件,晚上7点删除快照
|
2026-02-21 15:42:56,556 - INFO - 定时任务已设置:每周六凌晨4点导出文件,晚上7点删除快照
|
||||||
2026-02-21 15:43:00,000 - INFO - 🔍 开始收集VM和快照信息...
|
2026-02-21 15:43:00,000 - INFO - 🔍 开始收集VM和快照信息...
|
||||||
|
|||||||
@@ -30,3 +30,16 @@ global:
|
|||||||
# excel_output_path: ./vm_snapshots_report.xlsx # 可选,使用默认值,如:/logs/2026-02-20_14-00-21-VMsSnapShots_report.xlsx
|
# excel_output_path: ./vm_snapshots_report.xlsx # 可选,使用默认值,如:/logs/2026-02-20_14-00-21-VMsSnapShots_report.xlsx
|
||||||
# yaml_output_path: ./yaml_snapshots_report.yaml # 可选
|
# 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
|
||||||
@@ -11,6 +11,12 @@ def load_config():
|
|||||||
|
|
||||||
# 全局配置
|
# 全局配置
|
||||||
global_config = raw_config.get('global', {})
|
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 = {
|
config = {
|
||||||
# vCenter/ESXi节点列表
|
# vCenter/ESXi节点列表
|
||||||
"MANAGEMENT_NODES": raw_config.get('management_nodes', []),
|
"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')),
|
"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')),
|
"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),
|
"DISABLE_SSL_VERIFY": global_config.get('disable_ssl_verify', True),
|
||||||
|
"SCHEDULE_EXPORT": export_schedule,
|
||||||
|
"SCHEDULE_DELETE": delete_schedule,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 验证配置
|
# 验证配置
|
||||||
if not config["MANAGEMENT_NODES"]:
|
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']
|
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"]
|
EXCEL_OUTPUT_PATH = config["EXCEL_OUTPUT_PATH"]
|
||||||
YAML_OUTPUT_PATH = config["YAML_OUTPUT_PATH"]
|
YAML_OUTPUT_PATH = config["YAML_OUTPUT_PATH"]
|
||||||
DISABLE_SSL_VERIFY = config["DISABLE_SSL_VERIFY"]
|
DISABLE_SSL_VERIFY = config["DISABLE_SSL_VERIFY"]
|
||||||
|
# 调度配置
|
||||||
|
SCHEDULE_EXPORT = config["SCHEDULE_EXPORT"]
|
||||||
|
SCHEDULE_DELETE = config["SCHEDULE_DELETE"]
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 打印全局配置
|
# 打印全局配置
|
||||||
|
|||||||
20
main.py
20
main.py
@@ -1,7 +1,7 @@
|
|||||||
import time
|
import time
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
from utils.logger import logger
|
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.get_vm_snapshots import get_all_vms
|
||||||
from core.data_exporter import create_excel_report, export_yaml
|
from core.data_exporter import create_excel_report, export_yaml
|
||||||
from core.remove_snapshots import load_old_snapshots, remove_snapshot
|
from core.remove_snapshots import load_old_snapshots, remove_snapshot
|
||||||
@@ -32,19 +32,14 @@ def delete_old_snapshots():
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""主执行函数"""
|
"""主执行函数"""
|
||||||
|
export_conf = SCHEDULE_EXPORT # 从配置读取导出任务时间
|
||||||
|
delete_conf = SCHEDULE_DELETE # 从配置读取删除任务时间
|
||||||
|
|
||||||
# 设置定时任务
|
scheduler = BackgroundScheduler() # 设置定时任务调度器
|
||||||
scheduler = BackgroundScheduler()
|
scheduler.start() # 开始调度器
|
||||||
|
|
||||||
# 每周六凌晨4点导出Excel和Yaml文件
|
logger.info(f"✓ 导出任务已设置: 每周 {export_conf['day_of_week']} {export_conf['hour']:02d}:{export_conf['minute']:02d}") # :02d 数字格式化选项,用于让数字显示为至少2位,不足补零。
|
||||||
scheduler.add_job(export_files, 'cron', day_of_week='sat', hour=4, minute=0)
|
logger.info(f"✓ 删除任务已设置: 每周 {delete_conf['day_of_week']} {delete_conf['hour']:02d}:{delete_conf['minute']:02d}")
|
||||||
|
|
||||||
# 每周六晚上7点执行删除快照任务
|
|
||||||
scheduler.add_job(delete_old_snapshots, 'cron', day_of_week='sat', hour=19, minute=0)
|
|
||||||
|
|
||||||
scheduler.start()
|
|
||||||
|
|
||||||
logger.info("定时任务已设置:每周六凌晨4点导出文件,晚上7点删除快照")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 保持主程序运行,以便调度器能正常工作
|
# 保持主程序运行,以便调度器能正常工作
|
||||||
@@ -57,3 +52,4 @@ def main():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user