From 1848f1aa5d0aea55a6d162b6862284a1b41eb769 Mon Sep 17 00:00:00 2001
From: dongjie110 <17621827400@163.com>
Date: Thu, 18 Jul 2024 16:54:59 +0800
Subject: [PATCH] adapt new format yaml sync pckg mgmt task
---
core/check_release_management.py | 10 +-
core/sync_pckg_mgmt.py | 385 +++++++++++++++++++++++++------
2 files changed, 325 insertions(+), 70 deletions(-)
diff --git a/core/check_release_management.py b/core/check_release_management.py
index e607cdd..dd1b987 100644
--- a/core/check_release_management.py
+++ b/core/check_release_management.py
@@ -782,12 +782,12 @@ class CheckReleaseManagement(object):
check the key and brach from in your yaml compliance with rules
"""
error_flag = False
- keylist = ['source_dir', 'obs_from', 'name', 'destination_dir', 'obs_to', 'date', 'quality_level', 'c_dir']
+ keylist = ['source_dir', 'obs_from', 'name', 'destination_dir', 'obs_to', 'date', 'quality_level']
for branch,info in change_info.items():
if info:
log.info("branch:{} yaml key check".format(branch))
for msg in info:
- if len(msg.keys()) == 7 or len(msg.keys()) == 6:
+ if len(msg.keys()) == 7 or len(msg.keys()) == 6 or len(msg.keys()) == 4:
for key in msg.keys():
if key not in keylist:
error_flag = True
@@ -1019,7 +1019,6 @@ class CheckReleaseManagement(object):
else:
branch_infos = yaml_path.split('/')
branch = branch_infos[0]
- #if 'delete' in branch_infos:
if branch_infos[1] == 'delete':
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
@@ -1051,7 +1050,7 @@ class CheckReleaseManagement(object):
with open(release_path, 'r', encoding='utf-8') as f:
result = yaml.load(f, Loader=yaml.FullLoader)
for pkg in result['packages']:
- pkg['c_dir'] = c_dir
+ # pkg['c_dir'] = c_dir
all_branch_pkgs.append(pkg)
# all_branch_pkgs.extend(result['packages'])
return all_branch_pkgs
@@ -1112,8 +1111,9 @@ class CheckReleaseManagement(object):
comment_tips = []
jp = JenkinsProxy("https://openeulerjenkins.osinfra.cn/", self.jenkins_user, self.jenkins_api_token)
build_url = self.jenkins_build_url
+ log_build_url = "{}/console".format(build_url)
job_name, job_id = jp.get_job_path_build_no_from_build_url(build_url)
- comment_tips.append("1)本次构建号为{2}/{1},点击可查看构建详情: #{1}\n".format(build_url,job_id,job_name))
+ comment_tips.append("1)本次构建号为{2}/{1},点击可查看构建详情: #{1}\n".format(log_build_url,job_id,job_name))
comment_tips.append("2)若有检查失败项目,请勿合入")
comment_tips.append("3)若您对如何创建提交PR有疑问," \
"可参考" \
diff --git a/core/sync_pckg_mgmt.py b/core/sync_pckg_mgmt.py
index e6fc08c..c21f833 100644
--- a/core/sync_pckg_mgmt.py
+++ b/core/sync_pckg_mgmt.py
@@ -23,6 +23,7 @@ import sys
import yaml
import shutil
import datetime
+import subprocess
now_path = os.path.join(os.path.split(os.path.realpath(__file__))[0])
sys.path.append(os.path.join(now_path, ".."))
from common.log_obs import log
@@ -467,10 +468,9 @@ class SyncPckgMgmt(object):
"""
if release_delete_changes:
for release_changes in release_delete_changes:
- for pkgs_path, pkgs in release_changes.items():
+ for complete_path, pkgs in release_changes.items():
result = {}
change_flag = False
- complete_path = os.path.join(pkgs_path, 'pckg-mgmt.yaml')
old_yaml = self._get_yaml_file_msg(complete_path)
pkgs_list = old_yaml['packages']
for i in range(len(pkgs_list)-1, -1, -1):
@@ -555,6 +555,42 @@ class SyncPckgMgmt(object):
self._add_pkg_service(temp)
+ def run(self, cmd, timeout=600):
+ """run shell cmd"""
+ ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8",
+ timeout=timeout)
+ log.info("cmd: {}".format(cmd))
+ if ret.stdout:
+ log.info("ret.stdout: {}".format(ret.stdout))
+ if ret.stderr:
+ log.info("ret.stderr: {}".format(ret.stderr))
+ return ret.returncode, ret.stdout, ret.stderr
+
+ def clone_repo(self, repo):
+ """clone package"""
+ log.info("start clone repo: {}".format(repo))
+ clone_flag = False
+ _, temp_path, _ = self.run("mktemp -d")
+ temp_path = temp_path.strip()
+ release_path = os.path.join(temp_path, repo)
+ clone_cmd = "git clone --depth=1 https://%s:%s@gitee.com/openeuler/%s -b %s %s" % (
+ self.giteeuser, self.giteeuserpwd, repo, 'master', release_path)
+ pull_cmd = "git -C %s pull" % release_path
+ try:
+ for i in range(5):
+ self.run(clone_cmd)
+ _, out, err = self.run(pull_cmd)
+ if ("Already up to date" in out) or ("Already up to date" in err):
+ clone_flag = True
+ break
+ else:
+ self.run("rm -rf {}".format(pkg_path))
+ except Exception as e:
+ self.run("rm -rf {}".format(temp_path))
+ log.info("finish clone repo: {}".format(repo))
+ return clone_flag, release_path
+
+
def _push_code(self, repo):
"""
push code to gitee repo
@@ -580,6 +616,12 @@ class SyncPckgMgmt(object):
log.error("%s not exist!" % repo)
return -1
+ def _parse_change_infos(self, change_infos):
+ for branch, pkgs in change_infos.items():
+ if pkgs:
+ add_pkgs = [pkg['name'] for pkg in pkgs]
+ self._collect_release_change_pkgs(branch, add_pkgs)
+
def _collect_release_change_pkgs(self, branch, pkgs):
"""
record change pkgs in dict
@@ -590,11 +632,11 @@ class SyncPckgMgmt(object):
else:
self.release_change_pkgs[branch] = pkgs
- def _do_git_pull(self):
+ def _do_git_pull(self, current_release_path):
"""
makesure local repo same with origin master
"""
- os.chdir(self.release_management_path)
+ os.chdir(current_release_path)
commit_cmd = 'git rev-parse HEAD'
commitid = os.popen(commit_cmd).read().split('\n')[0]
content_cmd = "git log --oneline -1"
@@ -602,7 +644,7 @@ class SyncPckgMgmt(object):
reg=re.compile(r"(?<=!)\d+")
match=reg.search(content)
try:
- pull_cmd = "cd {} && git pull".format(self.release_management_path)
+ pull_cmd = "cd {} && git pull".format(current_release_path)
if os.system(pull_cmd) == 0:
log.info("git pull repo success")
code = 0
@@ -618,7 +660,7 @@ class SyncPckgMgmt(object):
pull_result = {'match':match, 'content':content}
return pull_result
- def _write_release_yaml(self, pull_request):
+ def _write_release_yaml(self, pull_request, current_release_path):
'''
write change info to release_change.yaml
'''
@@ -632,7 +674,7 @@ class SyncPckgMgmt(object):
for branch, change_pkgs in self.release_change_pkgs.items():
if len(change_pkgs) < 50:
change_str = " ".join(change_pkgs)
- release_change_yaml = os.path.join(self.release_management_path, branch, "release-change.yaml")
+ release_change_yaml = os.path.join(current_release_path, branch, "release-change.yaml")
with open(release_change_yaml, encoding='utf-8') as file:
result = yaml.load(file, Loader=yaml.FullLoader)
change_dic = {
@@ -650,74 +692,287 @@ class SyncPckgMgmt(object):
else:
log.info("ignore write release change yaml file success")
+ def _check_rpms_complete_and_repeat(self, old_msg, new_msg):
+ '''
+ compare with old and new yaml msg, make sure package exist
+ '''
+ old_pkg = {}
+ new_pkg = {}
+ same_pkg = {}
+ error_pkg = {}
+ change_infos = {}
+ for branch,new_msgs in new_msg.items():
+ if old_msg.get(branch, []):
+ old_pkg[branch] = []
+ new_pkg[branch] = []
+ same_pkg[branch] = []
+ change_pkgs = []
+ old_msgs = old_msg[branch]
+ for old in old_msgs:
+ old_pkg[branch].append(old['name'])
+ for new in new_msgs:
+ if new['name'] in new_pkg[branch]:
+ same_pkg[branch].append(new['name'])
+ new_pkg[branch].append(new['name'])
+ error_branch_pkgs = list(set(old_pkg[branch]).difference(set(new_pkg[branch])))
+ if error_branch_pkgs:
+ error_pkg[branch] = error_branch_pkgs
+ add_pkgs = list(set(new_pkg[branch]).difference(set(old_pkg[branch])))
+ for new in new_msgs:
+ if new['name'] in add_pkgs:
+ change_pkgs.append(new)
+ change_infos[branch] = change_pkgs
+ else:
+ new_pkg[branch] = []
+ for new in new_msgs:
+ if new['name'] in new_pkg[branch]:
+ same_pkg[branch].append(new['name'])
+ new_pkg[branch].append(new['name'])
+ change_infos[branch] = new_msgs
+ for branch,pkgs in change_infos.items():
+ if pkgs:
+ log.info("change in:{}".format(branch))
+ for pkg in pkgs:
+ log.info(pkg)
+ return change_infos
- def sync_yaml_meta(self):
+ def _get_complete_yaml_pkgs(self, branch):
+ all_branch_pkgs = []
+ if os.path.exists(os.path.join(self.release_management_path, branch)):
+ standard_dirs = os.listdir(os.path.join(self.release_management_path, branch))
+ for standard_dir in standard_dirs:
+ file_path = os.path.join(self.release_management_path, branch, standard_dir)
+ if not os.path.isdir(file_path):
+ standard_dirs.remove(standard_dir)
+ if 'delete' in standard_dirs:
+ standard_dirs.remove('delete')
+ for c_dir in standard_dirs:
+ release_path = os.path.join(self.release_management_path, branch, c_dir, 'pckg-mgmt.yaml')
+ if os.path.exists(release_path):
+ with open(release_path, 'r', encoding='utf-8') as f:
+ result = yaml.load(f, Loader=yaml.FullLoader)
+ for pkg in result['packages']:
+ # pkg['c_dir'] = c_dir
+ all_branch_pkgs.append(pkg)
+ # all_branch_pkgs.extend(result['packages'])
+ return all_branch_pkgs
+
+ def _rollback_get_msg(self, repo_path):
"""
- integration of functions
+ rollback to last commit
"""
- change_file = self._get_change_file()
- yaml_dict = {}
- release_delete_changes = []
- for line in change_file:
- log.info("line:%s" % line)
- name = list(line.split())[1]
- file_path = os.path.join(self.release_management_path, name)
- yaml_dict = self._get_yaml_file_msg(file_path)
- branch_infos = name.split('/')
- if 'master' in branch_infos:
+ os.chdir(repo_path)
+ roll = os.system("git reset --hard HEAD^")
+ if roll == 0:
+ log.info("Already rollback to last commit")
+ else:
+ raise SystemExit("Error: fail to rollback to last commit")
+
+ def _get_new_version_yaml_msg(self, yaml_path_list, manage_path,vtype='master'):
+ '''
+ get new version yaml msg content
+ '''
+ all_pack_msg = {}
+ all_del_msg = {}
+ for yaml_path in yaml_path_list:
+ result = {}
+ file_path = os.path.join(manage_path, yaml_path)
+ if vtype == 'master':
+ branch_infos = yaml_path.split('/')
branch = branch_infos[1]
- if branch != 'delete':
- msg, del_msg, prj_pkg = self._parse_yaml_msg(yaml_dict, "master")
- pkg_names = self._add_prj_meta_pkgs_service(msg, branch_infos)
- msg = self._clear_msg_delete(msg, branch_infos[0])
- move_change_pkgs = self._move_master_pkg_service(msg)
- self._collect_release_change_pkgs(branch_infos[0],move_change_pkgs)
+ if os.path.exists(file_path):
+ with open(file_path, 'r', encoding='utf-8') as f:
+ result = yaml.load(f, Loader=yaml.FullLoader)
+ yaml_packages = [pkg for pkg in result['packages']]
+ if 'delete' in branch_infos:
+ all_del_msg[branch] = yaml_packages
+ else:
+ if all_pack_msg.get(branch,''):
+ full_packags = all_pack_msg[branch] + yaml_packages
+ all_pack_msg[branch] = full_packags
+ else:
+ all_pack_msg[branch] = yaml_packages
else:
- msg, del_msg, prj_pkg = self._parse_yaml_msg(yaml_dict, "multi-new-delete")
- pkgs = [tmp['pkgname'] for tmp in msg]
- del_change_pkgs, yaml_changes = self._del_pkg_new(pkgs, '{}'.format(branch_infos[0]))
- release_delete_changes.append(yaml_changes)
- self._collect_release_change_pkgs(branch_infos[0], del_change_pkgs)
- elif 'multi_version' in branch_infos:
- log.info("******ignore multi_version change yaml file*********")
- continue
- msg, del_msg, prj_pkg = self._parse_yaml_msg(yaml_dict, "multi-new")
- pkg_names = self._add_prj_meta_pkgs_service(msg, branch_infos)
- del_change_pkgs = self._verify_meta_file(prj_pkg)
- change_pkgs = pkg_names + del_change_pkgs
- complete_path = os.path.join(branch_infos[0], branch_infos[1])
- self._collect_release_change_pkgs(complete_path, change_pkgs)
+ if 'delete' in branch_infos:
+ all_del_msg[branch] = []
+ else:
+ all_pack_msg[branch] = []
else:
- if not yaml_dict:
- log.info("%s file content is empty!" % name)
- elif isinstance(yaml_dict['packages'], list):
- if 'delete' not in branch_infos:
- msg, del_msg, prj_pkg = self._parse_yaml_msg(yaml_dict, "multi-new")
- msg = self._clear_msg_delete(msg, branch_infos[0])
- pkg_names = self._add_prj_meta_pkgs_service(msg, branch_infos)
- self._collect_release_change_pkgs(branch_infos[0], pkg_names)
+ branch_infos = yaml_path.split('/')
+ branch = branch_infos[0]
+ if branch_infos[1] == 'delete':
+ if os.path.exists(file_path):
+ with open(file_path, 'r', encoding='utf-8') as f:
+ result = yaml.load(f, Loader=yaml.FullLoader)
+ yaml_packages = [pkg for pkg in result['packages']]
+ all_del_msg[branch] = yaml_packages
else:
- msg, del_msg, prj_pkg = self._parse_yaml_msg(yaml_dict, "multi-new-delete")
- pkgs = [tmp['pkgname'] for tmp in msg]
- del_change_pkgs, yaml_changes = self._del_pkg_new(pkgs, branch_infos[0])
- release_delete_changes.append(yaml_changes)
- self._collect_release_change_pkgs(branch_infos[0], del_change_pkgs)
+ all_del_msg[branch] = []
else:
- if "everything" in yaml_dict['packages'].keys():
- msg, del_msg, prj_pkg = self._parse_yaml_msg(yaml_dict, "new")
- pkg_names = self._add_prj_meta_pkgs_service(msg, branch_infos)
+ if not all_pack_msg.get(branch,''):
+ all_branch_pkgs = self._get_complete_yaml_pkgs(branch)
+ if all_branch_pkgs:
+ all_pack_msg[branch] = all_branch_pkgs
+ return all_pack_msg,all_del_msg
+
+ def _parse_commit_file(self, change_file):
+ """
+ get the change file for latest commit
+ """
+ new_file_path = []
+ new_versin_file_path = []
+ master_new_file_path = []
+ multi_version_file_path = []
+ for line in change_file:
+ log.info("line:%s" % line)
+ log_list = list(line.split())
+ temp_log_type = log_list[0]
+ if len(log_list) == 3:
+ if "pckg-mgmt.yaml" in log_list[2]:
+ if 'master' in log_list[2]:
+ master_new_file_path.append(log_list[2])
+ elif 'multi_version' in log_list[2]:
+ master_new_file_path.append(log_list[2])
else:
- msg, del_msg, prj_pkg = self._parse_yaml_msg(yaml_dict, "old")
- pkg_names = self._add_prj_meta_pkgs_service(msg, branch_infos)
- for tmp in del_msg:
- self._del_pkg(tmp)
- del_change_pkgs = self._verify_meta_file(prj_pkg)
- pull_result = self._do_git_pull()
+ branch_infos = log_list[2].split('/')
+ if len(branch_infos) == 3:
+ new_versin_file_path.append(log_list[2])
+ else:
+ new_file_path.append(log_list[2])
+ elif len(log_list) == 2:
+ if temp_log_type != "D" and "pckg-mgmt.yaml" in log_list[1]:
+ if 'master' in log_list[1]:
+ master_new_file_path.append(log_list[1])
+ elif 'multi_version' in log_list[1]:
+ master_new_file_path.append(log_list[1])
+ else:
+ branch_infos = log_list[1].split('/')
+ if len(branch_infos) == 3:
+ new_versin_file_path.append(log_list[1])
+ else:
+ new_file_path.append(log_list[1])
+ if new_file_path or master_new_file_path or new_versin_file_path:
+ return new_file_path, master_new_file_path, new_versin_file_path
+ else:
+ log.info("There are no file change exit!!!")
+ sys.exit()
+
+ def find_pkg_in_yaml(self, current_release_path, yaml_packages):
+ branch_pkgs = {}
+ for branch, pkgs in yaml_packages.items():
+ delete_pkgs = [tmp['name'] for tmp in pkgs]
+ if os.path.exists(os.path.join(current_release_path, branch)):
+ standard_dirs = os.listdir(os.path.join(current_release_path, branch))
+ for standard_dir in standard_dirs:
+ file_path = os.path.join(current_release_path, branch, standard_dir)
+ if not os.path.isdir(file_path) or standard_dir == 'delete':
+ standard_dirs.remove(standard_dir)
+ for c_dir in standard_dirs:
+ release_path = os.path.join(current_release_path, branch, c_dir, 'pckg-mgmt.yaml')
+ if os.path.exists(release_path):
+ with open(release_path, 'r', encoding='utf-8') as f:
+ result = yaml.load(f, Loader=yaml.FullLoader)
+ c_dir_pkgs = [tmp['name'] for tmp in result['packages']]
+ find_pkg = list(set(delete_pkgs).intersection(set(c_dir_pkgs)))
+ if find_pkg:
+ if branch_pkgs.get(release_path):
+ branch_pkgs[release_path].extend(find_pkg)
+ else:
+ branch_pkgs[release_path] = find_pkg
+ self._collect_release_change_pkgs(branch, find_pkg)
+ return branch_pkgs
+
+
+ def _get_move_and_add(self,old_msg,new_msg):
+ '''
+ get master project add and delete pkgs by compare old and new
+ '''
+ add_infos = {}
+ delete_infos = {}
+ add_pkgs = []
+ for branch,old_pkgs in old_msg.items():
+ if old_pkgs:
+ new_pkgs = new_msg[branch]
+ old_pkgs_names = [info['name'] for info in old_pkgs]
+ new_pkgs_names = [info['name'] for info in new_pkgs]
+ del_names = list(set(old_pkgs_names).difference(set(new_pkgs_names)))
+ add_names = list(set(new_pkgs_names).difference(set(old_pkgs_names)))
+ if del_names:
+ for old in old_pkgs:
+ if old['name'] in del_names:
+ if delete_infos.get(branch,[]):
+ delete_infos[branch].append(old)
+ else:
+ delete_infos[branch] = [old]
+ if add_names:
+ for new in new_pkgs:
+ if new['name'] in add_names:
+ add_pkgs.append(new['name'])
+ if add_infos.get(branch,[]):
+ add_infos[branch].append(new)
+ else:
+ add_infos[branch] = [new]
+ else:
+ add_infos[branch] = new_msg[branch]
+ if add_pkgs:
+ self._collect_release_change_pkgs('master', add_pkgs)
+ return add_infos,delete_infos
+
+ def _ensure_delete_infos(self, del_old_msg, del_new_msg):
+ '''
+ check new version delete pkgs
+ '''
+ del_new_pkg = {}
+ del_old_pkg = {}
+ ensure_delete_pkg = {}
+ for branch,del_new_msgs in del_new_msg.items():
+ del_change_pkgs = []
+ del_new_pkg[branch] = [new['name'] for new in del_new_msgs]
+ del_old_pkg[branch] = [old['name'] for old in del_old_msg[branch]]
+ delete_pkgs = list(set(del_new_pkg[branch]).difference(set(del_old_pkg[branch])))
+ if delete_pkgs:
+ for del_new in del_new_msgs:
+ if del_new['name'] in delete_pkgs:
+ del_change_pkgs.append(del_new)
+ if branch == 'delete':
+ ensure_delete_pkg['master'] = del_change_pkgs
+ else:
+ ensure_delete_pkg[branch] = del_change_pkgs
+ for branch,branch_del_pkgs in ensure_delete_pkg.items():
+ if branch_del_pkgs:
+ log.info("branch:{},delete pkgs:{}".format(branch,branch_del_pkgs))
+ return ensure_delete_pkg
+
+
+ def sync_yaml_meta(self):
+ change = self._get_change_file()
+ change_file, master_change_file, new_version_change_file = self._parse_commit_file(change)
+ master_change_yaml_msg,del_master_change_yaml_msg = self._get_new_version_yaml_msg(master_change_file, self.release_management_path)
+ new_version_change_msg,del_new_version_change_msg = self._get_new_version_yaml_msg(new_version_change_file, self.release_management_path, vtype='newversion')
+ self._rollback_get_msg(self.release_management_path)
+ old_master_yaml_msg,del_old_master_yaml_msg = self._get_new_version_yaml_msg(master_change_file, self.release_management_path)
+ old_new_version_msg,del_old_new_version_msg = self._get_new_version_yaml_msg(new_version_change_file, self.release_management_path, vtype='newversion')
+ clone_flag, current_release_path = self.clone_repo('release-management')
+ release_delete_changes = []
+ if master_change_file:
+ log.info(master_change_file)
+ add_infos, move_infos= self._get_move_and_add(old_master_yaml_msg, master_change_yaml_msg)
+ master_yaml_packages = self._ensure_delete_infos(del_old_master_yaml_msg, del_master_change_yaml_msg)
+ if master_yaml_packages:
+ branch_packages = self.find_pkg_in_yaml(current_release_path, master_yaml_packages)
+ release_delete_changes.append(branch_packages)
+ if new_version_change_file:
+ log.info(new_version_change_file)
+ change_infos = self._check_rpms_complete_and_repeat(old_new_version_msg, new_version_change_msg)
+ parse_change_pkgs = self._parse_change_infos(change_infos)
+ release_yaml_packages = self._ensure_delete_infos(del_old_new_version_msg, del_new_version_change_msg)
+ if release_yaml_packages:
+ branch_packages = self.find_pkg_in_yaml(current_release_path, release_yaml_packages)
+ release_delete_changes.append(branch_packages)
+ pull_result = self._do_git_pull(current_release_path)
self._del_pckg_from_yaml(release_delete_changes)
- self._write_release_yaml(pull_result)
- ret = self._push_code(self.obs_meta_path)
- self._push_code(self.release_management_path)
- return ret
+ self._write_release_yaml(pull_result, current_release_path)
+ self._push_code(current_release_path)
if __name__ == "__main__":
--
Gitee