import os import json import paramiko from smb.SMBConnection import SMBConnection from update.models import ClientRelease, Cinema import pymysql from pymysql.cursors import DictCursor from django.db.models import Q, Max from dingxin_toolbox_drf.settings import BASE_DIR from update.utils.dingxin_sql import * # 定义客户端读取路径 TEST_CLIENT_PATH = r'/客户端/测试专用/' TEST_HISTORY_CLIENT_PATH = r'/客户端/测试专用/历史测试测客户端/' PRD_CLIENT_PATH = r'/客户端/结测常用客户端/' PRD_HISTORY_CLIENT_PATH = r'/客户端/结测常用客户端/历史客户端——通用/' class ClientUtilCustom: def __init__(self): self.smb_conn = SMBConnection('admin', 'admin', '', '', use_ntlm_v2=True) self.smb_host = '172.16.3.68' self.local_path = os.path.join(BASE_DIR, 'dx', 'client') self.deploy_db_config = {'host': '10.10.0.80', 'port': 3306, 'user': 'clientdeploy', 'password': 'clientdeploy123456', 'database': 'yhz_tool'} self.deploy_id = 0 self.client_data = [] self.client_file_list = [] def smb_connect(self): self.smb_conn.connect(self.smb_host, 445) def smb_disconnect(self): self.smb_conn.close() def sync_client_db(self): # 获取本地数据库最大的同步ID self.deploy_id = ClientRelease.objects.all().aggregate(Max('deploy_id'))['deploy_id__max'] print('deploy_id', self.deploy_id) # 连接到deploy库获取大于deploy_id的数据 db_conn = pymysql.connect(**self.deploy_db_config) cursor = db_conn.cursor(cursor=DictCursor) cursor.execute(GET_NEW_DEPLOY_CLIENT_INFO, (self.deploy_id,)) cursor.close() # 获取未同步的客户端信息 client_info_list = cursor.fetchall() print(client_info_list) # 将客户端信息转化为本地数据库格式 self.handle_client_data_format(client_info_list) # 启动smb服务 self.smb_connect() # 获取smb服务器上的文件列表 self.get_client_file_list() # 将文件写入本地服务器 self.get_client_file() # 将数据信息写人本地数据库 self.update_client_db() # 关闭smb服务 self.smb_disconnect() # 关闭数据库 db_conn.close() return self.client_data def download_client_manual(self, file_name, server_path): # 启动smb服务 self.smb_connect() # 下载文件到本地 with open(os.path.join(self.local_path, file_name), 'wb') as local_file: # 接收文件并写入本地文件 print('从共享下载客户端文件到服务器 共享路径:', rf"{server_path}{file_name}", '服务器路径:', os.path.join(self.local_path, file_name)) self.smb_conn.retrieveFile('data1', rf"{server_path}{file_name}", local_file) # 关闭本地文件 local_file.close() # 关闭smb服务 self.smb_disconnect() return True def handle_client_data_format(self, client_data_list): print('handle_client_data_format') for data in client_data_list: print(data) main_ver = data['version_full'][:-5] upload_name = data['zip_full_name'][0:23] + '.7z' ver_id = int(data['version_full'][7:10]) self.client_data.append( {'origin_name': data['zip_full_name'], 'main_ver': main_ver, 'sub_ver': data['version_revise'], 'upload_name': upload_name, 'client_ver': data['version_full'], 'ver_id': ver_id, 'deploy_id': data['id'], 'is_cached': '0', 'file_name': '', 'md5': data['zip_md5'], } ) print(self.client_data) def update_client_db(self): for d in self.client_data: if not ClientRelease.objects.filter(deploy_id=d['deploy_id']).exists(): ClientRelease.objects.create(**d) def get_client_file_list(self): print('get_client_file_list') path_list = [TEST_CLIENT_PATH, TEST_HISTORY_CLIENT_PATH, PRD_CLIENT_PATH, PRD_HISTORY_CLIENT_PATH] for path in path_list: smb_files = self.smb_conn.listPath('data1', path, pattern=r'client_v*.7z') for file in smb_files: self.client_file_list.append({'path': path, 'name': file.filename}) print(json.dumps(self.client_file_list)) def get_client_file(self): print('get_client_file') local_file_list = list(os.walk(self.local_path))[0][2] for client in self.client_data: for file in self.client_file_list: if client['origin_name'][:23] == file['name'][:23]: # 查看本地是否有此版本客户端 if file['name'] in local_file_list: print('找到本地文件:', file['name']) continue # 下载文件到本地 with open(os.path.join(self.local_path, file['name']), 'wb') as local_file: # 接收文件并写入本地文件 print('从共享下载客户端文件到服务器 共享路径:', rf"{file['path']}{file['name']}", '服务器路径:', os.path.join(self.local_path, file['name'])) self.smb_conn.retrieveFile('data1', rf"{file['path']}{file['name']}", local_file) # 更新数据 client['is_cached'] = '1' client['file_name'] = file['name'] # 关闭本地文件 local_file.close() print(self.client_data) # 传输客户端的方法 def upload(self, cine_ip, origin, target): print('upload', cine_ip, origin, target) # 创建Transport客户端 trans = paramiko.Transport((cine_ip, 22)) # 使用密码连接服务器 trans.connect(username='root', password='cine123456') # 创建SFTP客户端 sftp = paramiko.SFTPClient.from_transport(trans) # 上传文件 参数(本地文件路径, 远程文件路径) sftp.put( os.path.join(self.local_path, origin), f"/data0/cine/resource/upload/client/{target}") # 关闭客户端 print(f'完成上传,路径/data0/cine/resource/upload/client/{target}') trans.close() def upload_client(self, cinema_ip, client_ver, server_release): print('upload_client', cinema_ip, client_ver, server_release) # 上传操作 print(f'开始上传操作, 目标主机 {cinema_ip}, 客户端版本 {client_ver}') release_ver = server_release[8:11] if server_release.startswith('2') else server_release[7:10] if client_ver is None or client_ver == '': print('1'*100) client = ClientRelease.objects.filter(Q(ver_id=release_ver) & Q(is_cached=True)).order_by('-id').first() else: print('2' * 100) print(client_ver[7:10]) client = ClientRelease.objects.filter(Q(client_ver=client_ver) & Q(is_cached=True)).order_by('-id').first() print("client", client) print('最终上传版本:', client.file_name, client.upload_name) if not client: return False self.upload(cinema_ip, client.file_name, client.upload_name) # 更新数据库 cine = Cinema.objects.filter(ip=cinema_ip).first() db_config = { 'host': cinema_ip, 'user': cine.db_user, 'password': cine.db_pwd, 'port': 3306, 'database': 'cine' } db_conn = pymysql.Connect(**db_config) db_cursor = db_conn.cursor(cursor=DictCursor) db_cursor.execute('UPDATE cinema_version SET client_version = %s WHERE 1=1;', (client.client_ver,)) db_conn.commit() db_cursor.close() db_conn.close() return client.origin_name