diff --git a/update/migrations/0007_remove_clientrelease_ver_time_clientrelease_main_ver_and_more.py b/update/migrations/0007_remove_clientrelease_ver_time_clientrelease_main_ver_and_more.py new file mode 100644 index 0000000..66df956 --- /dev/null +++ b/update/migrations/0007_remove_clientrelease_ver_time_clientrelease_main_ver_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 4.2.7 on 2024-01-08 06:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0006_updatecommand_process'), + ] + + operations = [ + migrations.RemoveField( + model_name='clientrelease', + name='ver_time', + ), + migrations.AddField( + model_name='clientrelease', + name='main_ver', + field=models.CharField(default='', help_text='主版本', max_length=100, verbose_name='主版本'), + ), + migrations.AddField( + model_name='clientrelease', + name='sub_ver', + field=models.CharField(default='', help_text='小版本', max_length=10, verbose_name='小版本'), + ), + migrations.AddField( + model_name='clientrelease', + name='type', + field=models.CharField(default='test', help_text='类型 test 测试 prd 线上', max_length=10, verbose_name='类型'), + ), + ] diff --git a/update/migrations/0008_alter_clientrelease_is_delete.py b/update/migrations/0008_alter_clientrelease_is_delete.py new file mode 100644 index 0000000..8d97d4d --- /dev/null +++ b/update/migrations/0008_alter_clientrelease_is_delete.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.7 on 2024-01-08 07:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0007_remove_clientrelease_ver_time_clientrelease_main_ver_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='clientrelease', + name='is_delete', + field=models.BooleanField(default=False, help_text='是否有效', verbose_name='是否有效'), + ), + ] diff --git a/update/migrations/0009_rename_type_clientrelease_client_type.py b/update/migrations/0009_rename_type_clientrelease_client_type.py new file mode 100644 index 0000000..d6d37aa --- /dev/null +++ b/update/migrations/0009_rename_type_clientrelease_client_type.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.7 on 2024-01-08 07:24 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0008_alter_clientrelease_is_delete'), + ] + + operations = [ + migrations.RenameField( + model_name='clientrelease', + old_name='type', + new_name='client_type', + ), + ] diff --git a/update/migrations/0010_clientrelease_client_ver.py b/update/migrations/0010_clientrelease_client_ver.py new file mode 100644 index 0000000..b66982e --- /dev/null +++ b/update/migrations/0010_clientrelease_client_ver.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.7 on 2024-01-08 07:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('update', '0009_rename_type_clientrelease_client_type'), + ] + + operations = [ + migrations.AddField( + model_name='clientrelease', + name='client_ver', + field=models.CharField(default='', help_text='客户端版本', max_length=100, verbose_name='客户端版本'), + ), + ] diff --git a/update/models.py b/update/models.py index 86fa616..d165a93 100644 --- a/update/models.py +++ b/update/models.py @@ -67,9 +67,12 @@ class ClientRelease(BaseModels): """ id = models.AutoField(primary_key=True) origin_name = models.CharField(verbose_name='原始名称', max_length=500, null=False, help_text='smb上的名称') - ver_time = models.CharField(verbose_name='版本发布时间', max_length=100, null=False, help_text='版本发布时间') + client_ver = models.CharField(verbose_name='客户端版本', max_length=100, null=False, default='', help_text='客户端版本') + main_ver = models.CharField(verbose_name='主版本', max_length=100, null=False, default='', help_text='主版本') + sub_ver = models.CharField(verbose_name='小版本', max_length=10, null=False, default='', help_text='小版本') upload_name = models.CharField(verbose_name='上传名称', max_length=200, null=False, help_text='上传名称') - is_delete = models.BooleanField(verbose_name='是否有效', default=True, help_text='是否有效') + client_type = models.CharField(verbose_name='类型', max_length=10, default='test', help_text='类型 test 测试 prd 线上') + is_delete = models.BooleanField(verbose_name='是否有效', default=False, help_text='是否有效') def __str__(self): return self.upload_name diff --git a/update/utils/client_util.py b/update/utils/client_util.py index e69de29..ae405d1 100644 --- a/update/utils/client_util.py +++ b/update/utils/client_util.py @@ -0,0 +1,116 @@ +import os +import paramiko +from smb.SMBConnection import SMBConnection +from update.models import ClientRelease, Cinema +import pymysql +from pymysql.cursors import DictCursor + + +class ClientUtil: + def __init__(self): + self.smb_conn = SMBConnection('admin', 'admin', '', '', use_ntlm_v2=True) + self.smb_host = '172.16.3.68' + + 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: + if ClientRelease.objects.filter(origin_name=file).first(): + continue + local_file = open(rf'../../dx/client/{file}', 'wb') + # 接收文件并写入本地文件 + self.smb_conn.retrieveFile('data1', rf'/客户端/测试专用/{file}', local_file) + # 关闭本地文件 + local_file.close() + self.write_db(file) + 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: + if ClientRelease.objects.filter(origin_name=file).first(): + continue + local_file = open(rf'../../dx/client/{file}', 'wb') + # 接收文件并写入本地文件 + self.smb_conn.retrieveFile('data1', rf'/客户端/结测常用客户端/{file}', local_file) + # 关闭本地文件 + local_file.close() + self.write_db(file) + + history_smb_files = self.smb_conn.listPath('data1', '/客户端/结测常用客户端/历史客户端', + pattern=r'client_v2.033*.7z') + for file in history_smb_files: + if ClientRelease.objects.filter(origin_name=file).first(): + continue + local_file = open(rf'../../dx/client/{file}', 'wb') + # 接收文件并写入本地文件 + self.smb_conn.retrieveFile('data1', rf'/客户端/结测常用客户端/历史客户端/{file}', local_file) + # 关闭本地文件 + local_file.close() + self.write_db(file) + self.smb_conn.close() + return prd_smb_files + history_smb_files + + @staticmethod + def write_db(_file): + # 写入数据库 + client_ver = _file[8:23] + main_ver = _file[8:18] + sub_ver = _file[19:23] + upload_ver = _file[:23] + '.7z' + _type = 'prd' + ClientRelease.objects.update(origin_name=_file, client_ver=client_ver, main_ver=main_ver, sub_ver=sub_ver, + upload_ver=upload_ver, client_type=_type) + + 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() diff --git a/update/utils/cmd_extcute.py b/update/utils/cmd_extcute.py index d049e00..2eb6f7f 100644 --- a/update/utils/cmd_extcute.py +++ b/update/utils/cmd_extcute.py @@ -17,22 +17,44 @@ class UpdateCommandUtil: self.client.close() def get_all_cmd(self): - return self.model.objects.order_by().all() + return self.model.objects.filter(is_delete='0').order_by(id).all() def get_sys_cmd(self): - return self.model.objects.filter(is_sys='1').order_by(id).all() + return self.model.objects.filter(Q(is_delete='0') & Q(is_sys='1')).order_by(id).all() def get_no_sys_cmd(self): - return self.model.objects.exclude(is_sys='1').order_by(id).all() + return self.model.objects.exclude(Q(is_delete='0') & Q(is_sys='0')).order_by(id).all() + + def get_no_sys_setup_cmd(self): + return self.model.objects.filter(Q(is_delete='0') & Q(is_sys='0') & Q(process='setup')).order_by(id).all() + + def get_no_sys_teardown_cmd(self): + return self.model.objects.filter(Q(is_delete='0') & Q(is_sys='0') & Q(process='teardown')).order_by(id).all() def get_checked_cmd(self, cmd_list): - sys_cmd = self.get_sys_cmd() - checked_cmd = self.model.objects.filter(id__in=cmd_list).order_by(id).all() - return sys_cmd + checked_cmd + sys_result = self.get_sys_cmd() + checked_setup_result = self.model.objects.filter( + Q(is_delete='0') & Q(id__in=cmd_list) & Q(process='setup')).order_by(id).all() + checked_teardown_result = self.model.objects.filter( + Q(is_delete='0') & Q(id__in=cmd_list) & Q(process='teardown')).order_by( + id).all() + sys_cmd = [sys['command'] for sys in sys_result] + checked_setup_cmd = [setup['command'] for setup in checked_setup_result] + checked_teardown_cmd = [teardown['command'] for teardown in checked_teardown_result] + return {'sys': sys_cmd, 'setup': checked_setup_cmd, 'teardown': checked_teardown_cmd} - def exec_cmd(self, cmd_list, _release): - exec_cmd_list = self.get_checked_cmd(cmd_list) - for cmd in cmd_list: + def exec_cmd(self, _exec_cmd_list): + self.connect() + for exec_cmd in _exec_cmd_list: + stdin, stdout, stderr = self.client.exec_command(exec_cmd) + print(stdout.read().decode('utf-8')) + self.disconnect() + + def exec_setup_cmd(self, cmd_list, _release): + exec_cmd_list = [] + exec_cmd_data = self.get_checked_cmd(cmd_list) + setup_cmd = exec_cmd_data['sys'] + exec_cmd_data['setup'] + for cmd in setup_cmd: if '' in cmd: cmd = cmd.replace('', _release) exec_cmd_list.append(cmd) @@ -42,8 +64,20 @@ class UpdateCommandUtil: exec_cmd_list.append(c) else: exec_cmd_list.append(cmd) - self.connect() - for exec_cmd in exec_cmd_list: - stdin, stdout, stderr = self.client.exec_command(exec_cmd) - print(stdout.read().decode('utf-8')) - self.disconnect() + self.exec_cmd(exec_cmd_list) + + def exec_teardown_cmd(self, cmd_list, _release): + exec_cmd_list = [] + exec_cmd_data = self.get_checked_cmd(cmd_list) + teardown_cmd = exec_cmd_data['teardown'] + for cmd in teardown_cmd: + if '' in cmd: + cmd = cmd.replace('', _release) + exec_cmd_list.append(cmd) + elif cmd.startswith(''): + cmd = cmd.replace('', _release) + for c in cmd.split('###'): + exec_cmd_list.append(c) + else: + exec_cmd_list.append(cmd) + self.exec_cmd(exec_cmd_list)