import os import paramiko from django.core.checks import database from smb.SMBConnection import SMBConnection from update.models import ClientRelease, Cinema import pymysql from pymysql.cursors import DictCursor from django.db.models import Q from dingxin_toolbox_drf.settings import BASE_DIR from update.utils.dingxin_sql import * class ClientUtil: 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.db_config = {'host': '172.16.3.139', 'port': 3306, 'user': 'clientdeploy', 'password': 'clientdeploy123456', 'database': 'yhz_tool'} def smb_connect(self): self.smb_conn.connect(self.smb_host, 445) def smb_disconnect(self): self.smb_conn.close() def get_all_smb_client(self): test_client_list = self.get_smb_file_list('data1', '/客户端/测试专用', r'client_v2.033*.7z') prd_client_list = self.get_smb_file_list('data1', '/客户端/结测常用客户端', r'client_v2.033*.7z') history_client_list = self.get_smb_file_list('data1', '/客户端/结测常用客户端/历史客户端', r'client_v2.033*.7z', ) return {'test': test_client_list, 'prd': prd_client_list, 'history': history_client_list} def get_smb_file_list(self, service_name, path, pattern): smb_files = self.smb_conn.listPath(service_name, path, pattern=pattern) file_list = [] for file in smb_files: file_name = file.filename file_list.append(file_name) return file_list def get_all_smb_file_list(self): test_client_list = self.get_smb_file_list('data1', '/客户端/测试专用', r'client_v2.033*.7z') prd_client_list = self.get_smb_file_list('data1', '/客户端/结测常用客户端', r'client_v2.033*.7z') history_client_list = self.get_smb_file_list('data1', '/客户端/结测常用客户端/历史客户端', r'client_v2.033*.7z', ) return test_client_list + prd_client_list + history_client_list def handle_client_db(self): client_data = self.get_all_smb_client() ClientRelease.objects.update(is_delete=True) self.write_db(client_data, 'test') self.write_db(client_data, 'prd') self.write_db(client_data, 'history') @staticmethod def write_db(_client_data, _type): for client in _client_data[_type]: file_name = client if ClientRelease.objects.filter(origin_name=file_name).first(): ClientRelease.objects.filter(origin_name=file_name).update(is_delete=False) else: # 写入数据库 origin_name = file_name main_ver = file_name[8:18] sub_ver = file_name[19:23] upload_name = file_name[:23] + '.7z' client_ver = file_name[8:23] ver_id = int(file_name[14:18]) ClientRelease.objects.create(origin_name=origin_name, main_ver=main_ver, sub_ver=sub_ver, upload_name=upload_name, client_type=_type, client_ver=client_ver, ver_id=ver_id) def clear_delete_file(self): all_delete = ClientRelease.objects.filter(is_delete=True).all() for delete in all_delete: file = os.path.join(self.local_path, delete.origin_name) if os.path.exists(file): os.remove(file) def get_client_info_from_deploy_db(self, short_ver): client_ver = short_ver.replace('0.33', '033') db_conn = pymysql.Connect(**self.db_config) db_cursor = db_conn.cursor(cursor=DictCursor) db_cursor.execute(GET_DEPLOY_CLIENT_INFO, (client_ver,)) result = db_cursor.fetchone() if result is None: return None return result['full_version'] @staticmethod def get_client_version_from_cine(cinema_ip): 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('SELECT client_version FROM cinema_version;') client_ver = db_cursor.fetchone()['client_version'] return client_ver def download_client_file(self, file_name, path): local_file = open(os.path.join(self.local_path, file_name), 'wb') # 接收文件并写入本地文件 print('从共享下载客户端文件到服务器 共享路径:', rf'{path}{file_name}', '服务器路径:', local_file) self.smb_conn.retrieveFile('data1', rf'{path}{file_name}', local_file) # 关闭本地文件 local_file.close() def get_client_version(self, cinema_ip, short_version): client_version = self.get_client_info_from_deploy_db(short_version) test_client_list = self.get_all_smb_file_list() # 客户端打包服务器上有,smb上没有 is_exist = False for test_client in test_client_list: if client_version in test_client: is_exist = True if is_exist is False: client = ClientRelease.objects.filter(ver_id=int(short_version[7:])).order_by('-sub_ver').first() client_version = client.client_ver # 新版本还没有对应的包 if client_version is None: client_version = self.get_client_version_from_cine(cinema_ip) return client_version def get_client(self, cinema_ip, short_version): client_version = self.get_client_version(cinema_ip, short_version) # 查看本地是否有此版本客户端 local_file_list = list(os.walk(self.local_path))[0][2] for local_file in local_file_list: if client_version in local_file: print('找到本地文件:', client_version) return # 如果本地没有则到服务器上拉取 client = ClientRelease.objects.filter(Q(client_ver=client_version) & Q(is_delete=False)).first() if client.client_type == 'test': self.download_client_file(client.origin_name, r'/客户端/测试专用/') elif client.client_type == 'prd': self.download_client_file(client.origin_name, r'/客户端/结测常用客户端/') elif client.client_type == 'history': self.download_client_file(client.origin_name, r'/客户端/结测常用客户端/历史客户端/') else: print('检查下载客户端逻辑') # 传输客户端的方法 def upload(self, 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, short_version): # 上传操作 client_version = self.get_client_version(cinema_ip, short_version) print(f'开始上传操作, 目标主机 {cinema_ip}, 客户端版本 {client_version}') client = ClientRelease.objects.filter(Q(client_ver=client_version) & Q(is_delete=False)).first() self.upload(cinema_ip, client.origin_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_version,)) db_conn.commit() db_cursor.close() db_conn.close() return client.upload_name def client_process(self, cinema_ip, short_release): self.smb_connect() short_version = short_release[:11] self.handle_client_db() self.clear_delete_file() self.get_client(cinema_ip, short_version) client_file_name = self.upload_client(cinema_ip, short_version) self.smb_disconnect() return client_file_name # # class ClientUtil: # 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') # # def get_test_client_file(self): # self.smb_conn.connect(self.smb_host, 445) # smb_files = self.smb_conn.listPath('data1', '/客户端/测试专用', pattern=r'client_v2.033*.7z') # for file in smb_files: # file_name = file.filename # print(file_name) # if ClientRelease.objects.filter(origin_name=file_name).first(): # continue # local_file = open(os.path.join(self.local_path, file_name), 'wb') # # 接收文件并写入本地文件 # self.smb_conn.retrieveFile('data1', rf'/客户端/测试专用/{file_name}', local_file) # # 关闭本地文件 # local_file.close() # self.write_db(file_name, 'test') # self.smb_conn.close() # # return smb_files # # def get_prd_client_file(self): # self.smb_conn.connect(self.smb_host, 445) # prd_smb_files = self.smb_conn.listPath('data1', '/客户端/结测常用客户端', pattern=r'client_v2.033*.7z') # for file in prd_smb_files: # file_name = file.filename # print(file_name) # if ClientRelease.objects.filter(origin_name=file_name).first(): # continue # local_file = open(os.path.join(self.local_path, file_name), 'wb') # # 接收文件并写入本地文件 # self.smb_conn.retrieveFile('data1', rf'/客户端/结测常用客户端/{file_name}', local_file) # # 关闭本地文件 # local_file.close() # self.write_db(file_name, 'prd') # # history_smb_files = self.smb_conn.listPath('data1', '/客户端/结测常用客户端/历史客户端', # pattern=r'client_v2.033*.7z') # for file in history_smb_files: # file_name = file.filename # print(file_name) # if ClientRelease.objects.filter(origin_name=file_name).first(): # continue # local_file = open(os.path.join(self.local_path, file_name), 'wb') # # 接收文件并写入本地文件 # self.smb_conn.retrieveFile('data1', rf'/客户端/结测常用客户端/历史客户端/{file_name}', local_file) # # 关闭本地文件 # local_file.close() # self.write_db(file_name, 'prd') # self.smb_conn.close() # # @staticmethod # def write_db(_file, _type): # # 写入数据库 # origin_name = _file # main_ver = _file[8:18] # sub_ver = _file[19:23] # upload_name = _file[:23] + '.7z' # client_ver = _file[8:23] # ver_id = int(_file[14:18]) # ClientRelease.objects.create(origin_name=origin_name, main_ver=main_ver, sub_ver=sub_ver, # upload_name=upload_name, client_type=_type, client_ver=client_ver, ver_id=ver_id) # # def update_client_file(self): # prd_clients = self.get_prd_client_file() # test_clients = self.get_test_client_file() # all_clients = prd_clients + test_clients # all_db_clients = ClientRelease.objects.filter(is_delete='0').all() # for db_client in all_db_clients: # if db_client['origin_name'] in all_clients: # continue # else: # ClientRelease.objects.filter(pk=db_client['id']).update(is_delete='1') # path = f'../../dx/client/{db_client["origin_name"]}' # os.remove(path) # # def upload_client_file(self, cinema_ip, _release): # cine = Cinema.objects.filter(ip=cinema_ip).first() # db_config = { # 'host': cinema_ip, # 'username': cine['db_user'], # 'password': cine['db_pwd'], # 'port': 3306, # 'database': 'cine' # } # db_conn = pymysql.Connect(**db_config) # db_cursor = db_conn.cursor(cursor=DictCursor) # # 获取客户端信息 # client = ClientRelease.objects.filter(main_ver=_release).order_by('-sub_ver').first() # print(client) # if client: # self.upload(cinema_ip, client['origin_name'], client['upload_name']) # db_cursor.execute('UPDATE cinema_version SET client_version = %s WHERE 1=1;', (client['client_ver'],)) # else: # db_cursor.execute('SELECT client_version FROM cinema_version;') # client_ver = db_cursor.fetchone()['client_version'] # client = ClientRelease.objects.filter(client_ver=client_ver).order_by('-sub_ver').first() # self.upload(cinema_ip, client['origin_name'], client['upload_name']) # # @staticmethod # def 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( # f"../../dx/client/{origin}", # f"/data0/cine/resource/upload/client/{target}") # # 关闭客户端 # trans.close()