From 693e33962cd22dfa8d3816474b7fa377b3bbb4aa Mon Sep 17 00:00:00 2001 From: wenfei6316 Date: Thu, 9 Jan 2025 09:19:44 +0800 Subject: [PATCH] refactor the task parse Signed-off-by: wenfei6316 --- rdms_system/config/settings.py | 3 + rdms_system/jenkins/README.md | 34 +++- rdms_system/jenkins/json/json_base.py | 137 +++++++++++++ rdms_system/jenkins/json/json_factory.py | 20 ++ .../v10/jenkins_tasks.json} | 4 +- rdms_system/jenkins/json/v10/json_parse.py | 180 +++++++++++++++++ .../jenkins/json/v20/jenkins_tasks.json | 101 ++++++++++ rdms_system/jenkins/json/v20/json_parse.py | 180 +++++++++++++++++ .../static/task/dayu210-v4.1-release.json | 32 +++ .../static/task/dayu800-v4.1-release.json | 39 ++++ .../static/task/duolun-v4.1-release.json | 32 +++ rdms_system/jenkins/task_parse.py | 187 ++++-------------- rdms_system/jenkins/views.py | 6 +- 13 files changed, 805 insertions(+), 150 deletions(-) create mode 100644 rdms_system/jenkins/json/json_base.py create mode 100644 rdms_system/jenkins/json/json_factory.py rename rdms_system/jenkins/{static/jenkins_board.json => json/v10/jenkins_tasks.json} (97%) create mode 100644 rdms_system/jenkins/json/v10/json_parse.py create mode 100644 rdms_system/jenkins/json/v20/jenkins_tasks.json create mode 100644 rdms_system/jenkins/json/v20/json_parse.py create mode 100644 rdms_system/jenkins/static/task/dayu210-v4.1-release.json create mode 100644 rdms_system/jenkins/static/task/dayu800-v4.1-release.json create mode 100644 rdms_system/jenkins/static/task/duolun-v4.1-release.json diff --git a/rdms_system/config/settings.py b/rdms_system/config/settings.py index e5c07cc..c8ef9d7 100644 --- a/rdms_system/config/settings.py +++ b/rdms_system/config/settings.py @@ -15,7 +15,10 @@ from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent +TASK_DIR = os.path.join(BASE_DIR, 'jenkins/static/task') +if not os.path.isdir(TASK_DIR): + os.makedirs(TASK_DIR) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ diff --git a/rdms_system/jenkins/README.md b/rdms_system/jenkins/README.md index 4d5c52a..bae20d1 100644 --- a/rdms_system/jenkins/README.md +++ b/rdms_system/jenkins/README.md @@ -21,4 +21,36 @@ ### 1.2 任务内部配置介绍 -任务创建提交后会调用后端检查接口:`check_task`,检查失败会将失败原因返回,如果检查成功会创建对应任务的数据库,如果配置了定时构建任务,同样会在定时构建任务列表中添加对应的产品。 \ No newline at end of file +任务创建提交后会调用后端检查接口:`check_task`,检查失败会将失败原因返回,如果检查成功会创建对应任务的数据库,如果配置了定时构建任务,同样会在定时构建任务列表中添加对应的产品。 + +## 二、方案代码设计 + +### 2.1 json配置文件版 + +所有的版本差异只是在tasks的格式中,每个版本都必须有以下条目: + +- version:用于确认解析的版本 +- author和email用于后期任务责任田划分 +- tasks:任务的详细信息,不同版本直接有差异 + +解析任务主要分为三大块:task_parse.py、json_factory.py和json_base.py + +**task_parse.py** + +该模块提供了TaskParse类,主要负责解析json文件中的task列表,并不负责具体的task解析。 +该模块提供以下接口 + +- parse:json数据解析流程,对外提供的接口 +- create_task:创建任务,对外提供的接口 +- _json_data_check:解析数据是否为json格式, 内部接口 +- _json_data_parse:解析出version、author、email和tasks, 内部接口 +- _task_parse:解析每条任务, 内部接口 + +**json_factory.py** + +根据传入的参数确定json解析的具体实现方法 + +**json_base.py** + +json解析的实现基类,每个版本的具体解析必须继承该基类,也必须实现其提供的抽象接口 +该类同时也提供了各个参数的基本检查方法,子类可以直接调用,除非特殊情况,一般不用重写。 diff --git a/rdms_system/jenkins/json/json_base.py b/rdms_system/jenkins/json/json_base.py new file mode 100644 index 0000000..d590cab --- /dev/null +++ b/rdms_system/jenkins/json/json_base.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +# _*_ coding:utf-8 _*_ + +import json +from abc import ABC +from typing import Tuple +from abc import abstractmethod + +BoardLevel = ["Mini", "Small", "Standard"] + +ScheduledList = [ + "no scheduled", + "daily", + "weekly", + "monthly", +] + +class ScheduledBuild: + def __init__(self): + self.scheduled = None + self.ip = None + self.board_id = None + +class Location: + def __init__(self): + self.ip = None + self.board_id = [] + +class JsonBase(ABC): + def __init__(self, version, author, email) -> None: + self.version = version + self.author = author + self.email = email + self.task_dict = {} + self.task_dict["version"] = version + self.task_dict["author"] = author + self.task_dict["email"] = email + self.data = None + + @abstractmethod + def parse_data(self, data) -> Tuple[bool, str]: + pass + + @abstractmethod + def show_task(self) -> None: + pass + + @abstractmethod + def check_data(self) -> Tuple[bool, str]: + pass + + @abstractmethod + def get_task(self): + pass + + @abstractmethod + def update_task(self): + pass + + @abstractmethod + def write_task(self, path) -> Tuple[bool, str]: + pass + + @abstractmethod + def create_task(self, path) -> Tuple[bool, str]: + pass + + @abstractmethod + def _repeat_check(self) -> Tuple[bool, str]: + pass + + @staticmethod + def _string_len_check(name, length) -> bool: + if len(name) > length: + return False + return True + + def _task_name_check(self, task_name) -> Tuple[bool, str]: + if not task_name: + return False, "Task name is not set" + if self._string_len_check(task_name, 32) == False: + return False, "Task name is larger than 32 character" + # Todo, 检查task_name的唯一性 + return True, None + + def _board_name_check(self, board_name) -> Tuple[bool, str]: + if not board_name: + return False, "Board name is not set" + if self._string_len_check(board_name, 32) == False: + return False, "Board name is larger than 32 character" + return True, None + + @staticmethod + def _board_level_check(level) -> Tuple[bool, str]: + if level not in BoardLevel: + return False, "Level is not in board list: Mini, Small, Standard" + return True, None + + def _manifest_check(self, manifest) -> Tuple[bool, str]: + if self._string_len_check(manifest, 256) == False: + return False, "Manifest is larger than 256 character" + return True, None + + def _branch_check(self, branch) -> Tuple[bool, str]: + if self._string_len_check(branch, 64) == False: + return False, "Branch is larger than 64 character" + return True, None + + def _xml_check(self, xml) -> Tuple[bool, str]: + if self._string_len_check(xml, 64) == False: + return False, "Xml is larger than 64 character" + return True, None + + @staticmethod + def _burn_script_check(burn_script) -> Tuple[bool, str]: + if not burn_script: + return False, "Burn Script is not set" + return True, None + + def _scheduled_build_check(self, scheduled_build) -> Tuple[bool, str]: + if not scheduled_build: + return False, "Scheduled build is not set" + if scheduled_build.scheduled != "no scheduled": + if scheduled_build.scheduled not in ScheduledList: + return False, "scheduled_build scheduled set error, scheduled list: no scheduled, daily, weekly, monthly", + if not scheduled_build.ip: + return False, "Scheduled_build ip is not set" + elif self._string_len_check(scheduled_build.ip, 16) == False: + return False, "Scheduled_build ip is larger than 16 character" + if not scheduled_build.board_id: + return False, "Scheduled_build board_id is not set" + elif self._string_len_check(scheduled_build.board_id, 32) == False: + return False, "Scheduled_build board_id is larger than 32 character" + return True, None + +if __name__ == '__main__': + pass diff --git a/rdms_system/jenkins/json/json_factory.py b/rdms_system/jenkins/json/json_factory.py new file mode 100644 index 0000000..9df9e27 --- /dev/null +++ b/rdms_system/jenkins/json/json_factory.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# _*_ coding:utf-8 _*_ + +import json +from jenkins.json.v10 import json_parse as v10 +from jenkins.json.v20 import json_parse as v20 + +def JsonParseFactory(version, author, email): + if version == "1.0": + print("start get v10.JsonParse") + return v10.JsonParse(author, email) + elif version == "2.0": + return v20.JsonParse(author, email) + else: + print("unknown version: {}, author: {}, email: {}".format(version, author, email)) + return None + +if __name__ == '__main__': + JsonParseFactory("2.0") + pass diff --git a/rdms_system/jenkins/static/jenkins_board.json b/rdms_system/jenkins/json/v10/jenkins_tasks.json similarity index 97% rename from rdms_system/jenkins/static/jenkins_board.json rename to rdms_system/jenkins/json/v10/jenkins_tasks.json index 4aa5763..cf10676 100644 --- a/rdms_system/jenkins/static/jenkins_board.json +++ b/rdms_system/jenkins/json/v10/jenkins_tasks.json @@ -1,6 +1,8 @@ { "version": "1.0", - "boards": [ + "author": "wen_fei", + "email": "wen_fei@runkaihong.com.cn", + "tasks": [ { "task_name": "dayu800-v4.1-release", "board_name": "dayu800", diff --git a/rdms_system/jenkins/json/v10/json_parse.py b/rdms_system/jenkins/json/v10/json_parse.py new file mode 100644 index 0000000..397931b --- /dev/null +++ b/rdms_system/jenkins/json/v10/json_parse.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +# _*_ coding:utf-8 _*_ + +import os +import json +from typing import Tuple +from jenkins.json.json_base import JsonBase, ScheduledBuild, Location + +class TaskInfo: + def __init__(self): + self.task_name = None + self.board_name = None + self.level = None + self.manifest = None + self.branch = None + self.xml = None + self.burn_script = None + self.image_path = None + self.build_cmd = None + self.build_script = None + self.test_script = None + self.scheduled_build = None + self.location = [] + +class JsonParse(JsonBase): + def __init__(self, author, email) -> None: + super().__init__("1.0", author, email) + self.task_info = TaskInfo() + + def parse_data(self, data) -> Tuple[bool, str]: + self.task_info.task_name = data["task_name"] + self.task_dict["task_name"] = self.task_info.task_name + + self.task_info.board_name = data["board_name"] + self.task_dict["board_name"] = self.task_info.board_name + + self.task_info.level = data["level"] + self.task_dict["level"] = self.task_info.level + + self.task_info.manifest = data["manifest"] + self.task_dict["manifest"] = self.task_info.manifest + + self.task_info.branch = data["branch"] + if not self.task_info.branch: + self.task_info.branch = "master" + self.task_dict["branch"] = self.task_info.branch + + self.task_info.xml = data["xml"] + if not self.task_info.xml: + self.task_info.xml = "default.xml" + self.task_dict["xml"] = self.task_info.xml + + self.task_info.burn_script = data["burn_script"] + self.task_dict["burn_script"] = self.task_info.burn_script + + self.task_info.image_path = data["image_path"] + if not self.task_info.image_path: + self.task_info.image_path = "out/{}/packages/phone/images".format(self.task_info.board_name) + self.task_dict["image_path"] = self.task_info.image_path + + self.task_info.build_cmd = data["build_cmd"] + if not self.task_info.build_cmd: + self.task_info.build_cmd = "./build.sh --product-name {} --ccache".format(self.task_info.board_name) + self.task_dict["build_cmd"] = self.task_info.build_cmd + + self.task_info.build_script = data["build_script"] + self.task_dict["build_script"] = self.task_info.build_script + + self.task_info.test_script = data["test_script"] + self.task_dict["test_script"] = self.task_info.test_script + + scheduled_build_data = data["scheduled_build"] + if len(scheduled_build_data) > 1: + return False, "scheduled_build must be one, current is {}".format(len(scheduled_build_data)) + for scheduled_build in scheduled_build_data: + temp = ScheduledBuild() + temp.scheduled = scheduled_build["scheduled"] + temp.ip = scheduled_build["ip"] + temp.board_id = scheduled_build["board_id"] + self.task_info.scheduled_build = temp + self.task_dict["scheduled_build"] = scheduled_build_data + + location_list = data["location"] + for location in location_list: + temp = Location() + temp.ip = location["ip"] + temp.board_id = location["board_list"] + self.task_info.location.append(temp) + self.task_dict["location"] = location_list + return True, None + + def show_task(self) -> None: + print("version: {}".format(self.version)) + print("author: {}".format(self.author)) + print("email: {}".format(self.email)) + print("task_name: {}".format(self.task_info.task_name)) + print("board_name: {}".format(self.task_info.board_name)) + print("level: {}".format(self.task_info.level)) + print("manifest: {}".format(self.task_info.manifest)) + print("branch: {}".format(self.task_info.branch)) + print("xml: {}".format(self.task_info.xml)) + print("burn_script: {}".format(self.task_info.burn_script)) + print("image_path: {}".format(self.task_info.image_path)) + print("build_cmd: {}".format(self.task_info.build_cmd)) + print("build_script: {}".format(self.task_info.build_script)) + print("test_script: {}".format(self.task_info.test_script)) + if self.task_info.scheduled_build: + print("scheduled_build.scheduled: {}".format(self.task_info.scheduled_build.scheduled)) + print("scheduled_build.ip: {}".format(self.task_info.scheduled_build.ip)) + print("scheduled_build.board_id: {}".format(self.task_info.scheduled_build.board_id)) + if self.task_info.location: + for location in self.task_info.location: + print("location ip: {}".format(location.ip)) + print("location board_id: {}".format(location.board_id)) + + def _repeat_check(self) -> Tuple[bool, str]: + # Todo + return True, None + + def check_data(self) -> Tuple[bool, str]: + ret, msg = self._task_name_check(self.task_info.task_name) + if ret == False: + return ret, msg + + ret, msg = self._board_name_check(self.task_info.board_name) + if ret == False: + return ret, msg + + ret, msg = self._board_level_check(self.task_info.level) + if ret == False: + return ret, msg + + ret, msg = self._manifest_check(self.task_info.manifest) + if ret == False: + return ret, msg + + ret, msg = self._branch_check(self.task_info.branch) + if ret == False: + return ret, msg + + ret, msg = self._xml_check(self.task_info.xml) + if ret == False: + return ret, msg + + ret, msg = self._burn_script_check(self.task_info.burn_script) + if ret == False: + return ret, msg + + ret, msg = self._scheduled_build_check(self.task_info.scheduled_build) + if ret == False: + return ret, msg + + ret, msg = self._repeat_check() + if ret == False: + return ret, msg + + return True, None + + def get_task(self) -> TaskInfo: + return self.task_info + + def update_task(self): + pass + + def write_task(self, path) -> Tuple[bool, str]: + task_file = os.path.join(path, "{}.json".format(self.task_info.task_name)) + try: + with open(task_file, 'w', encoding="utf-8") as fp: + json.dump(self.task_dict, fp, indent=2) + os.chmod(task_file, 0o444) + return True, None + except ValueError as e: + return False, str(e) + + def create_task(self, path) -> Tuple[bool, str]: + ret, err_msg = self.write_task(path) + if not ret: + return ret, err_msg + return True, None + diff --git a/rdms_system/jenkins/json/v20/jenkins_tasks.json b/rdms_system/jenkins/json/v20/jenkins_tasks.json new file mode 100644 index 0000000..cf10676 --- /dev/null +++ b/rdms_system/jenkins/json/v20/jenkins_tasks.json @@ -0,0 +1,101 @@ +{ + "version": "1.0", + "author": "wen_fei", + "email": "wen_fei@runkaihong.com.cn", + "tasks": [ + { + "task_name": "dayu800-v4.1-release", + "board_name": "dayu800", + "level": "Standard", + "manifest": "https://192.168.3.50:8088/gitlab.com/products/ohos/dayu800/manifest.git", + "branch": "Dayu800-v4.1-Release", + "xml": "dayu800_default.xml", + "burn_script": "dayu800-v4.1-release.bat", + "image_path": "", + "build_cmd": "", + "build_script": "", + "test_script": "", + "scheduled_build": [ + { + "scheduled": "daily", + "ip": "192.168.3.50", + "board_id": "11223344" + } + ], + "location": [ + { + "ip": "192.168.3.50", + "board_list": [ + "12345678", + "11223344" + ] + }, + { + "ip": "192.168.3.49", + "board_list": [ + "aabbccdd", + "abcd1234" + ] + } + ] + }, + { + "task_name": "dayu210-v4.1-release", + "board_name": "dayu210", + "level": "Standard", + "manifest": "https://10.20.72.31:8088/gitlab.com/products/spacechina/rk3588-ohos/manifest.git", + "branch": "Njdg-v4.1-Release", + "xml": "njdg_rk3588_default.xml", + "burn_script": "dayu210.bat", + "image_path": "out/rk3588/packages/phone/images", + "build_cmd": "", + "build_script": "", + "test_script": "", + "scheduled_build": [ + { + "scheduled": "no scheduled", + "ip": "", + "board_id": "" + } + ], + "location": [ + { + "ip": "192.168.3.50", + "board_list": [ + "abcdefgh", + "44332211" + ] + } + ] + }, + { + "task_name": "duolun-v4.1-release", + "board_name": "dayu800", + "level": "Standard", + "manifest": "https://192.168.3.50:8088/gitlab.com/products/ohos/dayu800/manifest.git", + "branch": "Dayu800-v4.1-Release", + "xml": "dayu800_default.xml", + "burn_script": "dayu800-v4.1-release.bat", + "image_path": "", + "build_cmd": "./build.sh --product-name dayu210b --gn-args duolun_enable=true --ccache", + "build_script": "", + "test_script": "", + "scheduled_build": [ + { + "scheduled": "daily", + "ip": "192.168.3.50", + "board_id": "11223344" + } + ], + "location": [ + { + "ip": "192.168.3.50", + "board_list": [ + "12345678", + "11223344" + ] + } + ] + } + ] +} diff --git a/rdms_system/jenkins/json/v20/json_parse.py b/rdms_system/jenkins/json/v20/json_parse.py new file mode 100644 index 0000000..397931b --- /dev/null +++ b/rdms_system/jenkins/json/v20/json_parse.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +# _*_ coding:utf-8 _*_ + +import os +import json +from typing import Tuple +from jenkins.json.json_base import JsonBase, ScheduledBuild, Location + +class TaskInfo: + def __init__(self): + self.task_name = None + self.board_name = None + self.level = None + self.manifest = None + self.branch = None + self.xml = None + self.burn_script = None + self.image_path = None + self.build_cmd = None + self.build_script = None + self.test_script = None + self.scheduled_build = None + self.location = [] + +class JsonParse(JsonBase): + def __init__(self, author, email) -> None: + super().__init__("1.0", author, email) + self.task_info = TaskInfo() + + def parse_data(self, data) -> Tuple[bool, str]: + self.task_info.task_name = data["task_name"] + self.task_dict["task_name"] = self.task_info.task_name + + self.task_info.board_name = data["board_name"] + self.task_dict["board_name"] = self.task_info.board_name + + self.task_info.level = data["level"] + self.task_dict["level"] = self.task_info.level + + self.task_info.manifest = data["manifest"] + self.task_dict["manifest"] = self.task_info.manifest + + self.task_info.branch = data["branch"] + if not self.task_info.branch: + self.task_info.branch = "master" + self.task_dict["branch"] = self.task_info.branch + + self.task_info.xml = data["xml"] + if not self.task_info.xml: + self.task_info.xml = "default.xml" + self.task_dict["xml"] = self.task_info.xml + + self.task_info.burn_script = data["burn_script"] + self.task_dict["burn_script"] = self.task_info.burn_script + + self.task_info.image_path = data["image_path"] + if not self.task_info.image_path: + self.task_info.image_path = "out/{}/packages/phone/images".format(self.task_info.board_name) + self.task_dict["image_path"] = self.task_info.image_path + + self.task_info.build_cmd = data["build_cmd"] + if not self.task_info.build_cmd: + self.task_info.build_cmd = "./build.sh --product-name {} --ccache".format(self.task_info.board_name) + self.task_dict["build_cmd"] = self.task_info.build_cmd + + self.task_info.build_script = data["build_script"] + self.task_dict["build_script"] = self.task_info.build_script + + self.task_info.test_script = data["test_script"] + self.task_dict["test_script"] = self.task_info.test_script + + scheduled_build_data = data["scheduled_build"] + if len(scheduled_build_data) > 1: + return False, "scheduled_build must be one, current is {}".format(len(scheduled_build_data)) + for scheduled_build in scheduled_build_data: + temp = ScheduledBuild() + temp.scheduled = scheduled_build["scheduled"] + temp.ip = scheduled_build["ip"] + temp.board_id = scheduled_build["board_id"] + self.task_info.scheduled_build = temp + self.task_dict["scheduled_build"] = scheduled_build_data + + location_list = data["location"] + for location in location_list: + temp = Location() + temp.ip = location["ip"] + temp.board_id = location["board_list"] + self.task_info.location.append(temp) + self.task_dict["location"] = location_list + return True, None + + def show_task(self) -> None: + print("version: {}".format(self.version)) + print("author: {}".format(self.author)) + print("email: {}".format(self.email)) + print("task_name: {}".format(self.task_info.task_name)) + print("board_name: {}".format(self.task_info.board_name)) + print("level: {}".format(self.task_info.level)) + print("manifest: {}".format(self.task_info.manifest)) + print("branch: {}".format(self.task_info.branch)) + print("xml: {}".format(self.task_info.xml)) + print("burn_script: {}".format(self.task_info.burn_script)) + print("image_path: {}".format(self.task_info.image_path)) + print("build_cmd: {}".format(self.task_info.build_cmd)) + print("build_script: {}".format(self.task_info.build_script)) + print("test_script: {}".format(self.task_info.test_script)) + if self.task_info.scheduled_build: + print("scheduled_build.scheduled: {}".format(self.task_info.scheduled_build.scheduled)) + print("scheduled_build.ip: {}".format(self.task_info.scheduled_build.ip)) + print("scheduled_build.board_id: {}".format(self.task_info.scheduled_build.board_id)) + if self.task_info.location: + for location in self.task_info.location: + print("location ip: {}".format(location.ip)) + print("location board_id: {}".format(location.board_id)) + + def _repeat_check(self) -> Tuple[bool, str]: + # Todo + return True, None + + def check_data(self) -> Tuple[bool, str]: + ret, msg = self._task_name_check(self.task_info.task_name) + if ret == False: + return ret, msg + + ret, msg = self._board_name_check(self.task_info.board_name) + if ret == False: + return ret, msg + + ret, msg = self._board_level_check(self.task_info.level) + if ret == False: + return ret, msg + + ret, msg = self._manifest_check(self.task_info.manifest) + if ret == False: + return ret, msg + + ret, msg = self._branch_check(self.task_info.branch) + if ret == False: + return ret, msg + + ret, msg = self._xml_check(self.task_info.xml) + if ret == False: + return ret, msg + + ret, msg = self._burn_script_check(self.task_info.burn_script) + if ret == False: + return ret, msg + + ret, msg = self._scheduled_build_check(self.task_info.scheduled_build) + if ret == False: + return ret, msg + + ret, msg = self._repeat_check() + if ret == False: + return ret, msg + + return True, None + + def get_task(self) -> TaskInfo: + return self.task_info + + def update_task(self): + pass + + def write_task(self, path) -> Tuple[bool, str]: + task_file = os.path.join(path, "{}.json".format(self.task_info.task_name)) + try: + with open(task_file, 'w', encoding="utf-8") as fp: + json.dump(self.task_dict, fp, indent=2) + os.chmod(task_file, 0o444) + return True, None + except ValueError as e: + return False, str(e) + + def create_task(self, path) -> Tuple[bool, str]: + ret, err_msg = self.write_task(path) + if not ret: + return ret, err_msg + return True, None + diff --git a/rdms_system/jenkins/static/task/dayu210-v4.1-release.json b/rdms_system/jenkins/static/task/dayu210-v4.1-release.json new file mode 100644 index 0000000..8ca80ef --- /dev/null +++ b/rdms_system/jenkins/static/task/dayu210-v4.1-release.json @@ -0,0 +1,32 @@ +{ + "version": "1.0", + "author": "wen_fei", + "email": "wen_fei@runkaihong.com.cn", + "task_name": "dayu210-v4.1-release", + "board_name": "dayu210", + "level": "Standard", + "manifest": "https://10.20.72.31:8088/gitlab.com/products/spacechina/rk3588-ohos/manifest.git", + "branch": "Njdg-v4.1-Release", + "xml": "njdg_rk3588_default.xml", + "burn_script": "dayu210.bat", + "image_path": "out/rk3588/packages/phone/images", + "build_cmd": "./build.sh --product-name dayu210 --ccache", + "build_script": "", + "test_script": "", + "scheduled_build": [ + { + "scheduled": "no scheduled", + "ip": "", + "board_id": "" + } + ], + "location": [ + { + "ip": "192.168.3.50", + "board_list": [ + "abcdefgh", + "44332211" + ] + } + ] +} \ No newline at end of file diff --git a/rdms_system/jenkins/static/task/dayu800-v4.1-release.json b/rdms_system/jenkins/static/task/dayu800-v4.1-release.json new file mode 100644 index 0000000..eb72c08 --- /dev/null +++ b/rdms_system/jenkins/static/task/dayu800-v4.1-release.json @@ -0,0 +1,39 @@ +{ + "version": "1.0", + "author": "wen_fei", + "email": "wen_fei@runkaihong.com.cn", + "task_name": "dayu800-v4.1-release", + "board_name": "dayu800", + "level": "Standard", + "manifest": "https://192.168.3.50:8088/gitlab.com/products/ohos/dayu800/manifest.git", + "branch": "Dayu800-v4.1-Release", + "xml": "dayu800_default.xml", + "burn_script": "dayu800-v4.1-release.bat", + "image_path": "out/dayu800/packages/phone/images", + "build_cmd": "./build.sh --product-name dayu800 --ccache", + "build_script": "", + "test_script": "", + "scheduled_build": [ + { + "scheduled": "daily", + "ip": "192.168.3.50", + "board_id": "11223344" + } + ], + "location": [ + { + "ip": "192.168.3.50", + "board_list": [ + "12345678", + "11223344" + ] + }, + { + "ip": "192.168.3.49", + "board_list": [ + "aabbccdd", + "abcd1234" + ] + } + ] +} \ No newline at end of file diff --git a/rdms_system/jenkins/static/task/duolun-v4.1-release.json b/rdms_system/jenkins/static/task/duolun-v4.1-release.json new file mode 100644 index 0000000..95593dc --- /dev/null +++ b/rdms_system/jenkins/static/task/duolun-v4.1-release.json @@ -0,0 +1,32 @@ +{ + "version": "1.0", + "author": "wen_fei", + "email": "wen_fei@runkaihong.com.cn", + "task_name": "duolun-v4.1-release", + "board_name": "dayu800", + "level": "Standard", + "manifest": "https://192.168.3.50:8088/gitlab.com/products/ohos/dayu800/manifest.git", + "branch": "Dayu800-v4.1-Release", + "xml": "dayu800_default.xml", + "burn_script": "dayu800-v4.1-release.bat", + "image_path": "out/dayu800/packages/phone/images", + "build_cmd": "./build.sh --product-name dayu210b --gn-args duolun_enable=true --ccache", + "build_script": "", + "test_script": "", + "scheduled_build": [ + { + "scheduled": "daily", + "ip": "192.168.3.50", + "board_id": "11223344" + } + ], + "location": [ + { + "ip": "192.168.3.50", + "board_list": [ + "12345678", + "11223344" + ] + } + ] +} \ No newline at end of file diff --git a/rdms_system/jenkins/task_parse.py b/rdms_system/jenkins/task_parse.py index 2870a69..94fd45d 100644 --- a/rdms_system/jenkins/task_parse.py +++ b/rdms_system/jenkins/task_parse.py @@ -2,128 +2,17 @@ # coding=utf-8 import json +import jenkins.json.json_factory from typing import Tuple -class ScheduledBuild: - def __init__(self): - self.scheduled = None - self.ip = None - self.board_id = None - -class Location: - def __init__(self): - self.ip = None - self.board_id = [] - -class BoardInfo: - def __init__(self): - self.task_name = None - self.board_name = None - self.level = None - self.manifest = None - self.branch = None - self.xml = None - self.burn_script = None - self.image_path = None - self.build_cmd = None - self.build_script = None - self.test_script = None - self.scheduled_build = None - self.location = [] - -class BoardParse: - def __init__(self) -> None: - self.board_info = BoardInfo() - - def show_data(self) -> None: - print("task_name: {}".format(self.board_info.task_name)) - print("board_name: {}".format(self.board_info.board_name)) - print("level: {}".format(self.board_info.level)) - print("manifest: {}".format(self.board_info.manifest)) - print("branch: {}".format(self.board_info.branch)) - print("xml: {}".format(self.board_info.xml)) - print("burn_script: {}".format(self.board_info.burn_script)) - print("image_path: {}".format(self.board_info.image_path)) - print("build_cmd: {}".format(self.board_info.build_cmd)) - print("build_script: {}".format(self.board_info.build_script)) - print("test_script: {}".format(self.board_info.test_script)) - if self.board_info.scheduled_build: - print("scheduled_build.scheduled: {}".format(self.board_info.scheduled_build.scheduled)) - print("scheduled_build.ip: {}".format(self.board_info.scheduled_build.ip)) - print("scheduled_build.board_id: {}".format(self.board_info.scheduled_build.board_id)) - if self.board_info.location: - for location in self.board_info.location: - print("location ip: {}".format(location.ip)) - print("location board_id: {}".format(location.board_id)) - - def parse(self, data) -> Tuple[bool, str]: - self.board_info.task_name = data["task_name"] - self.board_info.board_name = data["board_name"] - self.board_info.level = data["level"] - self.board_info.manifest = data["manifest"] - self.board_info.branch = data["branch"] - if not self.board_info.branch: - self.board_info.branch = "master" - self.board_info.xml = data["xml"] - if not self.board_info.xml: - self.board_info.xml = "default.xml" - self.board_info.burn_script = data["burn_script"] - self.board_info.image_path = data["image_path"] - if not self.board_info.image_path: - self.board_info.image_path = "out/{}/packages/phone/images".format(self.board_info.board_name) - self.board_info.build_cmd = data["build_cmd"] - if not self.board_info.build_cmd: - self.board_info.build_cmd = "./build.sh --product-name {} --ccache".format(self.board_info.board_name) - self.board_info.build_script = data["build_script"] - self.board_info.test_script = data["test_script"] - - scheduled_build_data = data["scheduled_build"] - if len(scheduled_build_data) > 1: - return False, "scheduled_build must be one, current is {}".format(len(scheduled_build_data)) - for scheduled_build in scheduled_build_data: - temp = ScheduledBuild() - temp.scheduled = scheduled_build["scheduled"] - temp.ip = scheduled_build["ip"] - temp.board_id = scheduled_build["board_id"] - self.board_info.scheduled_build = temp - - location_list = data["location"] - for location in location_list: - temp = Location() - temp.ip = location["ip"] - temp.board_id = location["board_list"] - self.board_info.location.append(temp) - - def check_board_info(self) -> Tuple[bool, str]: - if not self.board_info.task_name: - return False, "Task name is not set" - if not self.board_info.board_name: - return False, "Board name is not set" - if not self.board_info.level: - return False, "Level is not set" - if not self.board_info.manifest: - return False, "Manifest is not set" - if not self.board_info.burn_script: - return False, "Burn Script is not set" - if not self.board_info.scheduled_build: - return False, "Scheduled build is not set" - else: - if self.board_info.scheduled_build.scheduled != "no scheduled": - if not self.board_info.scheduled_build.ip: - return False, "Scheduled build ip is not set" - if not self.board_info.scheduled_build.board_id: - return False, "Scheduled build board_id is not set" - return True, None - - def get_board_info(self) -> BoardInfo: - return self.board_info - class TaskParse: def __init__(self) -> None: self.data = None self.version = None - self.boards_data = [] - self.board_list = [] + self.author = None + self.email = None + self.tasks_data = [] + self.task_list = [] def _json_data_check(self, data) -> Tuple[bool, str]: try: @@ -132,34 +21,38 @@ class TaskParse: return False, str(e) return True, None - def show_data(self) -> None: - print("version: {}".format(self.version)) - print() - for board in self.board_list: - board.show_data() + def _show_data(self) -> None: + for task in self.task_list: + task.show_task() print() - def board_parse(self) -> Tuple[bool, str]: - self.board_list = [] - for board in self.boards_data: - temp = BoardParse() - temp.parse(board) - ret, err_msg = temp.check_board_info() + def _task_parse(self) -> Tuple[bool, str]: + self.task_list = [] + for task in self.tasks_data: + temp = jenkins.json.json_factory.JsonParseFactory(version=self.version, author=self.author, email=self.email) + if not temp: + return False, "Unknown version, you can only set: 1.0 or 2.0" + temp.parse_data(task) + ret, err_msg = temp.check_data() if not ret: return ret, err_msg - self.board_list.append(temp) - if len(self.board_list) == 0: - return False, "board is empty" + self.task_list.append(temp) + if len(self.task_list) == 0: + return False, "task is empty" return True, None - def json_data_parse(self) -> Tuple[bool, str]: + def _json_data_parse(self) -> Tuple[bool, str]: for key, value in self.data.items(): if key == 'version': self.version = value - elif key == 'boards': - self.boards_data = value - if self.version == None or len(self.boards_data) == 0: - return False, "data is incomplete, version is none or board is none" + elif key == 'author': + self.author = value + elif key == 'email': + self.email = value + elif key == 'tasks': + self.tasks_data = value + if self.version == None or self.author == None or self.email == None or len(self.tasks_data) == 0: + return False, "data is incomplete, version、author、email or tasks maybe empty" return True, None def parse(self, data) -> Tuple[bool, str]: @@ -167,22 +60,22 @@ class TaskParse: if not ret: return ret, err_msg self.version = None - self.boards_data = [] - ret, err_msg = self.json_data_parse() + self.author = None + self.email = None + self.tasks_data = [] + ret, err_msg = self._json_data_parse() if not ret: return ret, err_msg - ret, err_msg = self.board_parse() + ret, err_msg = self._task_parse() if not ret: return ret, err_msg - self.show_data() + # self._show_data() + return True, None + + def create_task(self, path) -> Tuple[bool, str]: + for task in self.task_list: + ret, err_msg = task.create_task(path) return True, None if __name__ == '__main__': - with open("/home/wen_fei/django5/rdms_system/jenkins/static/jenkins_board.json", "r", encoding="utf-8") as file: - taskParse = TaskParse() - print("type(file) is {}".format(type(file))) - ret, err_msg = taskParse.parse(file.read()) - if not ret: - print("task parse failed: {}".format(err_msg)) - else: - print("task parse success") + pass \ No newline at end of file diff --git a/rdms_system/jenkins/views.py b/rdms_system/jenkins/views.py index c57f89b..407a3a9 100644 --- a/rdms_system/jenkins/views.py +++ b/rdms_system/jenkins/views.py @@ -1,12 +1,13 @@ import os import json from jenkins import task_parse +from config.settings import BASE_DIR, TASK_DIR from django.shortcuts import render, redirect, HttpResponse # Create your views here. -BASE_DIR = os.path.abspath(os.path.dirname(__file__)) BOARDS_JSON_FILE = os.path.join(BASE_DIR, 'static', 'jenkins_board.json') + JENKINS_DICT = {} def json_parse(json_file=BOARDS_JSON_FILE): @@ -24,6 +25,9 @@ def create_task(request, *args, **kwargs): if jenkins_json: task = task_parse.TaskParse() ret, err_msg = task.parse(jenkins_json.read()) + if not ret: + return HttpResponse(err_msg) + ret, err_msg = task.create_task(TASK_DIR) if not ret: return HttpResponse(err_msg) return HttpResponse("task create success") -- Gitee